在dataframe中保存JuMP优化结果的紧凑方式



我想以一种有效的方式保存我完成的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,1,50
2,1,1,60 
3,1,1,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,n=s_n,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

下面的函数为原始解("Value")创建列和索引值加上列。

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。

最新更新