-
-
Notifications
You must be signed in to change notification settings - Fork 401
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
Ease the computation of IIS? #1035
Comments
I would think of an IIS as a mapping from variables and constraint references to true/false indicating if they participate in the IIS or not. I would be willing to consider making this mapping easier to access through JuMP/MPB. Pretty printing and constructing submodels is a level of complexity that I would prefer not to be responsible for maintaining and could be included in a separate model diagnostics package. |
For the record this is a duplicate of #235. |
In what form would you return this mapping? I can think of several ways:
What elements should be considered when making a choice here? Does one affect more performance than the other (is this kind of question relevant for IISes, which are not really used that often)? A bit of loud thinking about the implementation.
For MathProgBase, I would need define a few functions: one to start the computation of the IIS, one to get the UP/LB/IISness of a variable, IISness of a constraint (following the conventions of MathProgBase, which seem to be having functions that work on one item at a time for
(I prefer to discuss this kind of details now before having to rewrite thing… Well, functions names are easy to change, but not really the overall architecture.) About the "enhanced" functionalities, would it be possible to create a package such as JuMPExtensions with this kind of code? (Plus things like sensitivity analysis, as CPLEX does https://www.ibm.com/support/knowledgecenter/SSSA5P_12.7.0/ilog.odms.cplex.help/CPLEX/GettingStarted/topics/tutorials/InteractiveOptimizer/sensitivityAnalysis.html, possibly.) |
I think we should focus with the MathProgBase interface portion first. I don't see a compelling reason to query only part of an IIS (correct me if wrong), so I think having only a single function that computes an IIS for a model would be appropriate. It could be called E.g. Does this sound reasonable? |
That indeed sounds reasonable. The only problem I have with the interface is when this Another problem I have is with the name of the function, as it seems to imply that the results can be obtained quickly (like all existing |
I think it's alright to tailor the interface to LP in this case. We can also go with |
Gurobi's IIS also includes SOS and quadratic constraints. |
Hence, what would be the best? Returning a structure that may be extended in the future (or even a dictionary, indexed by the type of things in the IIS: variable bounds, linear/quadratic constraint, etc.; but that seems horrible to me)? That structure would already be concrete within MPB. |
A concrete type seems reasonable to me, e.g., type IISInfo
varlb::Vector{Bool}
varub::Vector{Bool}
linconstr::Vector{Bool}
quadconstr::Vector{Bool}
sosconstr::Vector{Bool}
end (don't take the names seriously, it's just a sketch) |
I agree that the vector of Booleans fits probably much better the level of abstraction of MPB; then, for JuMP, maybe both the vector of Booleans and the vector of indices make sense (they are just a (I'm just not getting your point with attributes in MPB, but that's most likely due to my lack of acquaintance with that code.) OK, so I'm planning to have drafts of this (first MPB, then solvers, then JuMP) on GitHub rather soonish so we may speak about actual code. (I think I should be targetting Julia 0.6 for this? That would just mean |
We haven't dropped support for 0.5 at this point, so we would not be able to merge a PR that requires 0.6. |
OK, no problem, I'll keep that in mind (but I've completely skipped version 0.5, migrating directly from 0.4 to 0.6). |
FWIW I expect we'll end up dropping 0.5 sooner rather than later. |
@dourouc05, following some very recent discussions, we're about to propose some very big changes to MathProgBase, so you may want to put your implementation on pause. More will come next week. |
OK, no problem! (And I also see that I can use Julia 0.6 more freely!) |
I guess I should wait for the branch https://github.com/JuliaOpt/MathProgBase.jl/tree/break_everything to be merged before considering working on this? |
Yep, that branch and corresponding updates to JuMP will make exposing the IIS much more straightforward (as a variable/constraint attribute). |
OK, thank you! Do you have an ETA for this? |
Mid-July |
Interested in the discussion. I am using the following code for MILPs with Gurobi. I don't remeber who posted it, but it has been useful so far. Maybe it can be generalized. function getIIS(m::JuMP.Model)
grb_model = m.internalModel.inner
num_constrs = Gurobi.num_constrs(grb_model)
Gurobi.computeIIS(grb_model)
iis_constrs = Gurobi.get_intattrarray(grb_model, "IISConstr", 1, num_constrs)
m.linconstr[find(iis_constrs)]
end |
Actually, the goal is to generalise such code! |
We now have a good solution for this issue with MOI, so let's actually put the pieces together so that we can consider the issue resolved. Gurobi needs to define an MOI attribute for IIS, and we need to make sure that it gets passed cleanly through JuMP. |
To be sure of the steps to follow, here is what I understand now (I followed MOI's development, but only at a very high level), with the idea of a function that indicates, for each constraint, if it participates in the IIS:
@mlubin : any thoughts? |
@mlubin up? |
The first step is probably to implement in in Gurobi.jl. Just an attribute in Gurobi.jl instead of MOI so you can go model = JuMP.Model(with_optimizer(Gurobi.Optimizer))
@variable(model, x >= 1)
@constraint(model, c, 2x <= 0)
optimize!(model)
iis = MOI.get(model, Gurobi.IIS())
# typeof(iis) ??? Once we play around with Gurobi's IIS and sort out the API etc. We could add it to MOI. |
Thanks @odow for your answer! (I may go first with CPLEX, as I don't have a Gurobi license on this computer, though, but I guess that's OK.) |
No problem, except I have no Gurobi license on any computer I have access to right now. However, I may have access to an Xpress license at work, and it seems to have the feature (https://www.fico.com/fico-xpress-optimization/docs/latest/evalguide2/dhtml/eg2sec4_sec_eg2ssec42.html). |
Process repeated for Xpress! |
And also for Gurobi! (Once the first one is done, it's becoming easier, it seems!) |
PRs are now merged for both CPLEX and Gurobi (Xpress still waiting). What would be the next step? Moving the new attributes to MOI? |
Yes, please write up a short proposal for the new attributes in the form of MOI issue. I'd be interested in the lessons learned from the implementations for Gurobi, CPLEX, and Xpress.
Is this question resolved? Thanks for your work on this! |
This is kind of solved: either the IIS solver is done and the question makes no sense (everything is proved to be part of the IIS or not), or it is not and no distinction is made between things that are proved and those that have not been excluded yet. From a user perspective, I think this is OK, albeit it might be nice to have a specific way to query the exact status (but the attribute would then be a union of types: either a boolean or a missing value -- the latter indicating that the constraint has not been proved to be part of the IIS, which is closest to the meaning of jump-dev/CPLEX.jl#233 (comment) There is still a question that was only partially decided: what about forcing the user to call jump-dev/CPLEX.jl#233 (comment) About the current limitations, there are mostly solver-specific things:
For the non-solver-specific things (currently, all three implementation work for MILP models), requiring no change in MOI:
|
How do I correctly apply model = Model(with_optimizer(Gurobi.Optimizer))
@variable(model, x >= 0)
@variable(model, y >= 0)
@constraint(model, con1, x + y <= 3)
@constraint(model, con2, x + y >= 5)
@objective(model, Min, x)
optimize!(model)
grb_model = model.moi_backend.optimizer.model
computeIIS(grb_model.inner)
MOI.get(grb_model, Gurobi.ConstraintConflictStatus(), con2.index) (also see my post regarding this in the Julia board) |
MOI.get(model, Gurobi.ConstraintConflictStatus(), con2) |
I'm surprised that |
I got my minimal example working like this now: Gurobi.compute_conflict(model.moi_backend.optimizer.model)
MOI.get(model.moi_backend, Gurobi.ConstraintConflictStatus(), con1.index) |
What's the error for |
It works as well. I came up with the posted code, because your suggestion didn't work for me first, but I couldn't reproduce that error. |
Follow-up on the topic. As the required bits have been accepted into MOI age should make it in release 0.9.14, I updated the support for the solvers: I guess the next and final step would be to add something in JuMP to retrieve the IIS, I was thinking of a way to copy only the parts of the model that are in the IIS. |
Now that everything needed is merged in MOI and that the PR for two solvers seem to have reached an acceptable state, I guess the time is right to discuss about what we could need in JuMP. A simple thing would be to provide a function in JuMP to call Then, the next thing is probably to allow copying only the relevant parts of the conflict into a new model. It would almost be a clone of I had a new look at other optimisation packages, but they don't seem to offer an interface for conflicts (Pyomo, GAMS, AIMMS, AMPL): for some solvers, it looks like you have access to the underlying functionality, but without any kind of unification. While it's a very good point for selling JuMP once it's done, there are not many sources for inspiration… Do you have any other ideas, or comments about these ideas? |
What's the workflow for people using the IIS? I haven't really used it, so I don't have a strong opinion on what to do. I imagine people would need to write out the IIS to an LP file for inspection, so having a way to If there is no generic interface in other modeling packages, it might be a good idea to post on Discourse and say "Have you used the IIS feature of a solver? What is your workflow?/How would you design the IIS interface for JuMP?" |
Whenever I needed that functionality, that was exactly my workflow. It worked okayish, but I couldn't find any better way to do it… Here is the discussion: https://discourse.julialang.org/t/have-you-used-the-iis-conflict-refiner-feature-of-a-solver-how-would-you-like-to-access-it-from-jump/41862. On the side, I'll also work on a |
I've been digging in What do you think of this? Or do you have other/better ideas? |
I've just thought of another solution: add (more) parameters to |
@odow @mlubin @joehuchette do you have opinions on how to implement this? As there has been no answer on Discourse, I guess that no other functionality is really required… |
Let's go ahead with this as a first step, it will be a big improvement over not having any JuMP-level API for IIS. As you observed, creating a sub-model with only the constraints that participate in the IIS is a bit complex, and it's not obvious what users want. |
#2300 addresses the bulk of this issue, so I'm going to close this. New issues may be opened to discuss improvements to the IIS API. A big thanks to @dourouc05 for seeing this through over three years! |
I was waiting for MOI 0.9.15 to be tagged (for jump-dev/MathOptInterface.jl#1135), so that JuMP's interface is on the same level as Gurobi's API, for instance, but that's the last step I see for this :)! |
Many solvers present an option to compute an IIS in case of infeasibility (Gurobi, CPLEX, BARON at least, probably others that I don't know of). However, accessing this functionality from JuMP is a bit of a mess (like the example
iis.jl
).I think such functionality should be directly available from JuMP (when the underlying solver supports it), with a function like
computeIIS
, but I have seen no previous work in this direction. It could have two kinds of outputs:Which solution would be preferable? I think that the second is more general (you could get the first one by just printing the resulting model), although I am not sure having the whole model is really useful for the user (except probably that it would be consistent).
Of course, I propose myself as a potential implementer of the needed changes (in JuMP, MathProgBase, and a few solvers).
The text was updated successfully, but these errors were encountered: