plasmo-dev / Plasmo.jl

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

Quadratic objectives with variables on separate nodes is not supported #84

Open dlcole3 opened 1 year ago

dlcole3 commented 1 year ago

Plasmo seems to only support quadratic objectives when the two terms of the quadratic objectives are on the same node. If a quadratic term is added to the objective function which has variables on separate nodes, the line here returns an error. The example below returns the error:

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^2)
end

optimize!(graph)

obj_func = objective_function(graph)

new_term = UnorderedPair(nodes[1][:x], nodes[2][:x])
obj_func.terms[new_term] = 3.0

optimize!(graph)

On the modeling side, this can be avoided by placing dummy variables on each node and then adding a linking constraint between the dummy variable and the variable it represents, but it could be nice to someday support quadratic objectives on different nodes.

dlcole3 commented 1 year ago

I am not sure if this is sufficient (or robust), but I currently avoid this error by changing these lines into the following code:

for (i, terms) in enumerate(quad_terms(obj))
    term1 = terms[2]
    term2 = terms[3]
    node1 = optinode(term1)
    node2 = optinode(term2)
    #@assert optinode(term1) == optinode(term2)
    moi_term1 = index(term1)
    moi_term2 = index(term2)
    node_idx_map1 = backend(node1).optimizers[graph.id].node_to_optimizer_map
    node_idx_map2 = backend(node2).optimizers[graph.id].node_to_optimizer_map
    new_moi_idx_1 = node_idx_map1[moi_term1]
    new_moi_idx_2 = node_idx_map2[moi_term2]
    moi_obj = _swap_quad_term!(moi_obj, i, new_moi_idx_1, new_moi_idx_2)
end

When I make this change, I no longer get an error. I have quadratic terms with variables from separate nodes, and the OptiGraph solves without issue.