Written by: Paul Rubin
Primary Source: Or in an OB World, 5/29/2019
A question elsewhere on the blog reminded me that some users of the CPLEX programming APIs are not conscious of a “technicality” that, when violated, might cause CPLEX to crash (or at least throw an exception).
The bottom line can be stated easily enough: modifying a CPLEX model while solving it is a Bozo no-no. In the Java API, that means making a change to instance of
IloCplex while that instance is solving. In the C++ API, where the model (
IloModel) and solver (
IloCplex) are separate, I suspect it means making a change to either on … but I’m not sure.
But wait, you say, callbacks do just that! No, not exactly. Callbacks add constraints (either user cuts or lazy constraints) to cut pools maintained by the solver, but they are not added to the model itself. Callbacks have their own add-whatever methods, for this specific purpose. Let’s say that (in Java) I declare
IloCplex cplex = new IloCplex();
and then build a model, attach a callback or two and call
cplex.solve(). While the solver is working, I can add user cuts or lazy constraints using the
IloCplex.LazyConstraintCallback.add() methods (or their local alternatives). What I cannot do, even in a callback, is use
cplex.add() to add a user cut or lazy constraint (or anything else). If I do, kaboom!
What if, during a solve, I discover some new constraints that I would like to add to the model? One option is to abort the solver, add them, and start over. Another is to store them in program memory, wait for the solver to terminate (optimal solution, time limit, whatever), and then add them to the model. I just cannot add them while the solver is running (unless I want to crash the program).
Note that, while one model is solving, I am free to modify some other model that is not solving. For instance, suppose I decompose a problem into a master problem and several subproblems (one per time period, say). Assuming that subproblems are solved sequentially, not in parallel, if I stumble on a constraint relevant to subproblem #2 while I am solving subproblem #1, I am free to add it to subproblem #2 … just not (yet) to subproblem #1.