问题描述
我想以有效的方式保存我完成的 lp 优化的所有变量和双变量。我当前的解决方案有效,但既不优雅也不适合具有许多变量和约束的大型优化程序,因为我定义并推送!每个单独的变量分别放入 DataFrame 中。有没有办法使用 all_variables() 和 all_constraints() 来迭代变量?在迭代时,我想将结果推送到 DataFrame 中,并将变量索引名称作为列,并将 DataFrame 保存在 Dict() 中。 一个概念的例子是变量:
Result_vars = Dict()
for vari in all_variables(Model)
Resul_vars["vari"] = DataFrame(data=[indexval(vari),value(vari)],columns=[index(vari),"Value"])
end
JuMP 和 DataFrame 中声明变量的外观示例:
@variable(Model,p[t=s_time,n=s_n,m=s_m],lower_bound=0,base_name="Expected production")
而 Result_vars[p] 应大致如下:
t,n,m,Value
1,1,50
2,60
3,145
解决方法
大概,你可以这样做:
x = all_variables(model)
DataFrame(
name = variable_name.(x),Value = value.(x),)
如果你想要一些更复杂的结构,你需要编写自定义代码。
T,N,M,primal_solution = [],[],[]
for t in s_time,n in s_n,m in s_m
push!(T,t)
push!(N,n)
push!(M,m)
push!(primal_solution,value(p[t,n,m]))
end
DataFrame(t = T,n = N,m = M,Value = primal_solution)
请参阅此处了解限制条件:https://jump.dev/JuMP.jl/stable/constraints/#Accessing-constraints-from-a-model-1。你想要这样的东西:
for (F,S) in list_of_constraint_types(model)
for con in all_constraints(model,F,S)
@show dual(con)
end
end
,
感谢 Oscar,我构建了一个有助于自动提取结果的解决方案。
解决方案是围绕在变量定义中使用 base_name
的命名约定构建的。可以将变量定义复制粘贴到 base_name
后跟 :
。例如:
@variable(Model,p[t=s_time,n=s_n,m=s_m],lower_bound=0,base_name="p[t=s_time,m=s_m]:")
命名约定和语法可以更改,注释可以例如添加,或者不能定义 base_name
。以下函数将 base_name
划分为变量名、集合(如果需要)和索引:
function var_info(vars::VariableRef)
split_conv = [":","]","[",","]
x_str = name(vars)
if occursin(":",x_str)
x_str = replace(x_str," " => "") #Deletes all spaces
x_name,x_index = split(x_str,split_conv[1]) #splits raw variable name+ sets and index
x_name = replace(x_name,split_conv[2] => "")
x_name,s_set = split(x_name,split_conv[3])#splits raw variable name and sets
x_set = split(s_set,split_conv[4])
x_index = replace(x_index,split_conv[2] => "")
x_index = replace(x_index,split_conv[3] => "")
x_index = split(x_index,split_conv[4])
return (x_name,x_set,x_index)
else
println("Var base_name not properly defined. Special Syntax required in form var[s=set]: ")
end
end
接下来的函数为原始解决方案(“值”)创建列和索引值以及列。
function create_columns(x)
col_ind=[String(var_info(x)[2][col]) for col in 1:size(var_info(x)[2])[1]]
cols = append!(["Value"],col_ind)
return cols
end
function create_index(x)
col_ind=[String(var_info(x)[3][ind]) for ind in 1:size(var_info(x)[3])[1]]
index = append!([string(value(x))],col_ind)
return index
end
function create_sol_matrix(varss,model)
nested_sol_array=[create_index(xx) for xx in all_variables(model) if varss[1]==var_info(xx)[1]]
sol_array=hcat(nested_sol_array...)
return sol_array
end
最后,最后一个函数创建了 Dict,它以前面提到的样式保存 DataFrames 中变量的所有结果:
function create_var_dict(model)
Variable_dict=Dict(vars[1]
=>DataFrame(Dict(vars[2][1][cols]
=>create_sol_matrix(vars,model)[cols,:] for cols in 1:size(vars[2][1])[1]))
for vars in unique([[String(var_info(x)[1]),[create_columns(x)]] for x in all_variables(model)]))
return Variable_dict
end
将这些函数添加到您的脚本中后,您可以通过调用 create_var_dict()
来简单地检索优化后变量的所有解:
var_dict = create_var_dict(model)
请注意:它们是嵌套函数。当您更改命名约定时,您可能还必须更新其他函数。如果您添加更多评论,则必须避免使用 [
、]
和 ,
。
这个解决方案显然远非最佳。我相信回归到 MOI 可能会有更有效的解决方案。