Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

unset_binary function does not work after optimize! is called #87

Closed
dlcole3 opened this issue Aug 10, 2023 · 2 comments
Closed

unset_binary function does not work after optimize! is called #87

dlcole3 opened this issue Aug 10, 2023 · 2 comments
Labels

Comments

@dlcole3
Copy link
Collaborator

dlcole3 commented Aug 10, 2023

I found that calling unset_binary does not work after optimize! is called when using Juniper as the solver. Below is a MWE that returns the same error.

using Ipopt, Juniper, Plasmo

graph = OptiGraph()

@optinode(graph, nodes[1:2])
@variable(nodes[1], x, Bin)
@variable(nodes[1], 1 <= y)
@variable(nodes[2], 1 <= y)
@linkconstraint(graph, nodes[1][:y] + nodes[2][:y] >= 3)
@constraint(nodes[1], nodes[1][:x] + nodes[1][:y] == 1.5)
@objective(graph, Min, nodes[1][:y] + nodes[2][:y] - nodes[1][:x])

ipopt = optimizer_with_attributes(Ipopt.Optimizer, "print_level"=>0)
optimizer = optimizer_with_attributes(Juniper.Optimizer, "nl_solver"=>ipopt)

set_optimizer(graph, optimizer)
optimize!(graph)
unset_binary(graph[:nodes][1][:x])

I initially thought it might be a problem on Juniper's side, but I can run the same problem in JuMP using Juniper and it does not return an error (see below).

using JuMP
m = Model()

@variable(m, x, Bin)
@variable(m, y1 >= 1)
@variable(m, y2 >= 1)
@constraint(m, y1 + y2 >= 3)
@constraint(m, y1 + x == 1.5)
@objective(m, Min, y1 + y2 - x)

set_optimizer(m, optimizer)

optimize!(m)
unset_binary(m[:x])

I followed the stacktrace, and it seems like it might be because this line calls delete on a MOI.Bridges.LazyBridgeOptimizer object. In contrast, this line works, but it is calling delete on a MOI.Utilities.CachingOptimizer object. It looks like the JuMP version also only calls delete on the CachingOptimizer object.

@jalving
Copy link
Member

jalving commented Oct 10, 2023

With v0.5.4, you can use a work-around with reset_optimizer like following:

using Ipopt, Juniper, Plasmo

graph = OptiGraph()

@optinode(graph, nodes[1:2])
@variable(nodes[1], x, Bin)
@variable(nodes[1], 1 <= y)
@variable(nodes[2], 1 <= y)
@linkconstraint(graph, nodes[1][:y] + nodes[2][:y] >= 3)
@constraint(nodes[1], nodes[1][:x] + nodes[1][:y] == 1.5)
@objective(graph, Min, nodes[1][:y] + nodes[2][:y] - nodes[1][:x])

ipopt = optimizer_with_attributes(Ipopt.Optimizer, "print_level"=>0)
optimizer = optimizer_with_attributes(Juniper.Optimizer, "nl_solver"=>ipopt)

set_optimizer(graph, optimizer)
optimize!(graph)
reset_optimizer(graph)
unset_binary(graph[:nodes][1][:x])

Juniper does not seem to support deleting constraints, so it falls back to the caching optimizer. We will need to change how we manage optimizers to fix this correctly. Mainly, we should call reset_optimizer when we detect unsupported changes.

Your first snippet does work with HiGHS which supports deleting constraints.

@jalving
Copy link
Member

jalving commented Sep 1, 2024

This seems to be fixed in v0.6 @dlcole3. Please re-open if you run into this issue again.

@jalving jalving closed this as completed Sep 1, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants