Support for removing constraints?

745 views
Skip to first unread message

Malcolm Cleaton

unread,
Jul 1, 2014, 5:04:18 AM7/1/14
to juli...@googlegroups.com
Hello julia-opt!

I'm using JuMP with Gurobi to solve large numbers of similar feasibility problems.

With other languages, I've been able to build up my large problem, solve it, remove just a couple of constraints, add a couple of new ones, and solve again.

With JuMP, it seems like removing constraints isn't supported, which causes a lot of inefficiency in this case.

So:
- Have I missed a way I can do this efficiently with JuMP?
- If not, is this a feature request which might go anywhere? Unfortunately I don't have the knowledge to add this support myself yet.

Thanks,
Malcolm.



Joey Huchette

unread,
Jul 1, 2014, 11:17:50 AM7/1/14
to juli...@googlegroups.com
Hi Malcolm,
Thanks for using JuMP! Currently we do not have support for removing constraints from a model stored in memory, at least in part because support for this functionality is not uniform across solvers. There is support for adding new constraints to a model built in memory (do @addConstraint as usual and it should Just Work), so if that is not working as expected, please open an issue.

Although removing constraints is not supported at the JuMP level, it is still possible to access solver level functionality exposed through the particular solvers C API. However, it doesn't look like the appropriate function for Gurobi (GRBdelconstrs) is currently wrapped. This is a pretty straightforward addition, though; we can add it in the next day or two. Note that working on a lower level like this will mess with the indexing of constraints in the JuMP model: JuMP only has knowledge of constraints it adds, so anything indexed by constraints (e.g. dual values) may be incorrect.

-Joey

Joey Huchette

unread,
Jul 1, 2014, 11:45:14 AM7/1/14
to juli...@googlegroups.com
Just added it; you can pull the changes by doing Pkg.update("Gurobi"). To use it, you can do something like

using Gurobi,MathProgBase,JuMP
m=Model(solver=GurobiSolver())
...
Gurobi.del_constrs!(MathProgBase.getrawsolver(getInternalModel(m)), [1,3])
Gurobi.update_model!(MathProgBase.getrawsolver(getInternalModel(m)))

Where [1,3] is the (one-indexed) set if rows you want to delete from your model. To verify you get what you expect, you can always do MathProgBase.getconstrmatrix(getInternalModel(m)) and inspect the results. Same disclaimers about messing with JuMPs constraint indexing apply. I didn't do extensive testing, so let me know if it doesn't work as expected. 

-Joey

Miles Lubin

unread,
Jul 1, 2014, 11:54:48 AM7/1/14
to Joey Huchette, julia-opt
On the JuMP side of things, I don't think it would be too disruptive to make it easy to disable/enable constraints at a high level, so we'll definitely consider supporting it in a future version. If you're looking for a idiomatic way to do this currently, one approach is to wrap your model generation inside a function whose parameters decide which constraints to add, e.g.:

function generate_model(whichconstraints)
    ...
    if i in whichconstraints
        @addConstraint(...)
    end
end

I'm not convinced that using Gurobi's low-level constraint deletion methods would be much faster than just generating a new model from scratch each time, though I'm happy to be proven wrong.


--
You received this message because you are subscribed to the Google Groups "julia-opt" group.
To unsubscribe from this group and stop receiving emails from it, send an email to julia-opt+...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Iain Dunning

unread,
Jul 1, 2014, 12:00:17 PM7/1/14
to Miles Lubin, Joey Huchette, julia-opt
As one final point to consider, if you have some constraints you want to remove but want to benefit from warm starting, you might be able to change the RHS of the constraint so its no longer active, e.g. 

x + y <= 5
change it to
x + y <= 50000

and its effectively gone.

Malcolm Cleaton

unread,
Jul 2, 2014, 5:20:00 AM7/2/14
to juli...@googlegroups.com
Thanks! It works very nicely.

My program's total runtime is around 10% less, which I'm pretty pleased with, given that this also includes all the time spent actually solving these things and everything else I'm doing. I should also be able to do better; I'm often removing and re-adding the same constraints at the moment, due to some code it's only just become worthwhile to improve.

I did discover one wrinkle. If I add new variables to a model after removing constraints, it ends up in one of those scary states where I don't get any errors, I just get the wrong answers. Like the man in the joke (Doctor, it hurts when I do this), it's simple enough to simply not do that, but it's a little bit scary to sometimes get the wrong answers and not know quite why.

Thanks,
Malcolm.

Malcolm Cleaton

unread,
Jul 2, 2014, 6:48:35 AM7/2/14
to juli...@googlegroups.com
Even better. I've fixed my code, and now the complete run is over twice as fast as before on my test data set. I suspect it will also scale out better too.

Thanks very much for the very quick response, it's really helped me out.

Thanks,
Malcolm.
Reply all
Reply to author
Forward
0 new messages