-
Notifications
You must be signed in to change notification settings - Fork 87
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
Add Lazy/Heuristic MIP callbacks #782
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So it seems like each callback has three attributes
- an attribute to set the callback function
- an attribute to pass the submittable
- an attribute to query the solution
Should we standardize naming on
[NewCallback]Callback
, e.g.,LazyConstraintCallback
[NewCallback]
, e.g.,LazyConstraint
[NewCallback]VariablePrimal
, e.g.,LazyConstraintVariablePrimal
Codecov Report
@@ Coverage Diff @@
## master #782 +/- ##
==========================================
- Coverage 95.1% 95.09% -0.02%
==========================================
Files 80 80
Lines 8518 8519 +1
==========================================
Hits 8101 8101
- Misses 417 418 +1
Continue to review full report at Codecov.
|
In terms of interface, Gurobi and CPLEX are good examples that we can follow. Gurobi has a generic CPLEX follows the same idea (query what from where in the optimization), but has specific functions for querying/posting information from/to the solver. Only a generic callback function is registered. Pointers to the docs:
|
One approach would be to have only one callback A second approach would be to have The third approach is having So to summarize in a table:
|
IMO,
FYI, here is a table of what MIP solvers currently support.
With respect to
This distinction is the same as, say querying the solution value after calling Back to One question I don't have an answer to is: what about solvers that don't do generic callbacks (e.g. XPress)? How do you break a generic callback into usercut callback / heuristic callback, etc? |
Not sure to follow. Solvers can already define new callbacks by defining new attributes, this PR will not change the situation in that respect.
Thanks a lot !
The case 1. is already covered by
I agree, this could be included in
You could put in the |
To implement an informational callback, just define a
Wouldn't this be duplicating code? Solvers already perform this check, and raise an error if needed. |
Suppose you have some algo to generate a heuristic solution but it takes some time. With |
The problematic part is more about registering the callback in the first place. One possibility (but quite cumbersome) would be to have Xpress.jl register a callback function for every possible specific callback in Xpress, each of them calling |
To correct something I said in earlier posts: In fact, we don't need Thinking more about it, I prefer solution 2 of #782 (comment). That is, similarly to
This type of fallbacks kind of defines what the user can if MOI.supports(optimizer, MOI.UserCut(callback_data))
func, set = # Long computation
MOI.submit(optimizer, MOI.UserCut(callback_data), (func, set))
end @mtanneau You suggest using rather solution 3. So a single callback and you have a way to query why it was called (or from where it was called but it seems kind of the same), let's say by
However, there are several reasons for which IMO solution 2 is more appropriate for solver independent callbacks in MOI:
I am not saying that solution 3 was a bad design decision for Gurobi. The argument above only apply for solver-independent callbacks for MOI. Not for solver-dependent ones in C.
Yes, that would be the way if we go for solution 3. |
It's not clear to me what you mean by "generic callback" (but it might be covered by SCIP's event handlers). Other than that, I'm confident that SCIP provides functionality that is equivalent (and goes beyond) what other solvers offer in terms of callbacks. However, the plugin system in SCIP typically requires that the user implement multiple callback methods and only imperfect mappings are possible (as we did with the MPB-wrapper of SCIP). |
I still want to believe in generic callbacks, but... I don't see any of it being practical (nor consensual) anytime soon. So @blegat I'm overturning my previous comments, and I support having a small set of specific callbacks that expose a limited set of functionalities. That should be enough to satisfy most users and hopefully be merged soon.
@rschwarz same terminology as CPLEX' generic callback. |
PR updated based on the discussion above as well as discussion with @ccoffrin, @harshangrjn and @kaarthiksundar. |
Continuing the discussion (@blegat this is mostly aligned with what you're proposing). I would suggest to go with the following minimal set of functionalities which should be supported by most (if not all) MIP solvers:
To motivate this, here's a compilation of what (some) MIP solvers supports in terms of callback functionality.
For instance: Gurobi allows to submit heuristic solutions, user cuts and lazy constraints after solving a node relaxation, and only lazy constraints when an incumbent is found. Notes & caveats.
|
A question for understanding: Is the idea that the user can only add a single callback function for each type (lazy constraint, heuristic) via the new attribute? So, if I have a model where I want to use represent two separate constraints via lazy constraints, I would have to create a wrapper callback that checks violation and adds cuts for either of them? |
Yes, in the current design there is only one callback. If you set another callback it overwrites the previous one. The wrapper approach would be a solution. |
8c58675
to
6b06224
Compare
6b06224
to
30c16b9
Compare
@mtanneau I agree with your latest comment, let's define I have updated the PR, last call for objections. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Couple of comments dealing with callback-wise conventions.
This PR defines the necessary attributes and submittables for lazy and heuristic callbacks.
The docstrings are based on #670.
Closes #670
cc @mtanneau