plasmo-dev / Plasmo.jl

A Platform for Scalable Modeling and Optimization
Other
143 stars 20 forks source link

`dual(subgraph, link_ref)` does not work like `value(subgraph, var_ref)` #86

Closed dlcole3 closed 10 months ago

dlcole3 commented 1 year ago

When using expanded subgraphs with the same variables defined on multiple subgraphs, the value of the variables in the different subgraphs after optimization can be queried by calling value(subgraph, var_ref). However, the same is not true for the dual function when the same linking constraints are defined on different subgraphs.

The code below replicates this issue. In the last print statement, I would expect that calling dual(expanded_subgraphs[1], middle_link) would return the value of dual1, but it returns dual2.

using Plasmo, JuMP, Ipopt

graph = OptiGraph()
set_optimizer(graph, Ipopt.Optimizer)

@optinode(graph, nodes[1:4])
for (i, node) in enumerate(nodes)
    @variable(node, x >= i)
    @objective(node, Min, 2 * x)
end
for i in 1:3
    @linkconstraint(graph, nodes[i + 1][:x] + nodes[i][:x] >= i * 4)
end

node_membership = [1, 1, 2, 2]
hypergraph, hyper_map = gethypergraph(graph)
partition = Partition(hypergraph, node_membership, hyper_map)
apply_partition!(graph, partition)
subgraphs = getsubgraphs(graph)
expanded_subgraphs = Plasmo.expand.(graph, subgraphs, 1)
set_optimizer(expanded_subgraphs[1], Ipopt.Optimizer)
set_optimizer(expanded_subgraphs[2], Ipopt.Optimizer)

middle_link = graph.optiedges[1].linkrefs[1]

optimize!(expanded_subgraphs[1])
dual1 = dual(middle_link)

optimize!(expanded_subgraphs[2])
dual2 = dual(middle_link)

println(dual(expanded_subgraphs[1], middle_link) == dual1) # this line is false

I believe this is because the code here depends on the last_solution_id attribute of the optiedge, which links to the solution from expanded_subgraphs[2]. For now, I am able to get around this by writing a wrapper to set the last_solution_id of the optiedge to point to expanded_subgraphs[1] as in the code below.

graph.optiedges[1].backend.last_solution_id = expanded_subgraphs[1].id
jalving commented 10 months ago

This should now be fixed in main