Cutting plane algorithm performance varies with Gurobi and CPLEX


I’ve implemented a cutting plane algorithm (using lazy callback mechanism) to robustify the solution obtained from the deterministic MIP akin to the work “Reformulation versus cutting-planes for robust optimization”. What I observed here was that CPLEX quite often returned a solution with a bad optimality gap while Gurobi couldn’t find even a feasible solution for the same problem. The only change that I perform to the code is that I replace the name of the solver from CPLEX to Gurobi. Apart from that, the logic remains untouched. Could you please throw some pointers regarding this issue?


Callbacks are tied in very deeply to how a MIP solver works, and they’re just not the same across solvers. (This took some experience to discover.) In JuMP 0.19 we will no longer be providing solver-independent callbacks for this reason; they create a false expectation that you can abstract away the solver when you implement the callbacks. The replacement will be solver-specific callbacks that expose the same interface as the low-level API.

Adding cuts to a MILP prior to the solving
JuMP solver callback arguments
Callback information about parent in B&B tree
Cut generation not working lazy constraints - lagrangian relaxation

In addition, there is a lot performance variability in MIP solving, even before you add callbacks.
That’s also why there is no clear winner in MIP benchmarks.


I understand the variability issues. But why kill the whole thing all together?. I really love that it is so simple to implement a callback in JuMP 0.18. By moving to lower level things will only become more complicated. Would it be too much to keep the callback interface?.


Solver-independent callbacks can still be implemented by an extension of JuMP. I think the point is to not offer them officially because the actual behavior is not really solver-independent.


Would it be possible to add solver-dependent callbacks in JuMP 0.18? An example would be very helpful.


I’m guessing you would just use the direct solver code, not the MathProgBase wrapper.
I have not done that before, but I would start looking here: