| Overview | Group | Tree | Graph | Deprecated | Index | Concepts |
A callback is an object
with a main method implemented by a user.
This user-written main method is called by the
IloCplex algorithm at specific points during
optimization.
Callbacks may be called repeatedly at various points during optimization;
for each place a callback is called, CPLEX provides a separate callback
class (derived from the class IloCplex::CallbackI).
Such a callback class provides the specific API as a protected method
to use for the particular implementation.
There are two varieties of callbacks:
IloCplex.
The information available depends on the algorithm
(primal simplex, dual simplex, barrier, mixed integer, or network)
that you are using. For example, a query callback can return the
current objective value, the number of simplex iterations that have
been completed, and other details. Query callbacks can also be called
from presolve, probing, fractional cuts, and disjunctive cuts.
IloCplex. For example,
control callbacks enable you to select the next node to process
or to control the creation of subnodes (among other possibilities).
Control callbacks are an advanced feature of CPLEX, and as such,
they require a greater degree of familiarity with CPLEX algorithms.
You do not create instances of the class IloCplex::CallbackI;
rather, you use one of its child classes to implement your own callback.
In order to implement your user-written callbacks with an instance of
IloCplex, you should follow these steps:
MyCallbackI, say,
from the appropriate predefined callback class.
main
routine of your user-written callback. (All constructors of
predefined callback classes are protected; they can be called
only from user-written derived subclasses.)
duplicateCallback.
myCallback, say,
that creates an instance of your implementation class in the
Concert Technology environment and returns it as an
IloCplex::Callback handle.
IloCplex::use.
There are macros of the form ILOXXXCALLBACKn (for n from 0 to 7)
available to facilitate steps 2 through 5, where XXX
stands for the particular callback under construction and n stands for
the number of arguments that the function written in step 5 is to receive
in addition to the environment argument.
You can use one instance of a callback with only one instance of
IloCplex. When you use a callback with a second
instance of IloCplex, a copy will be automatically
created using the method duplicateCallback,
and that copy will be used instead.
Also, an instance of IloCplex takes account of
only one instance of a particular callback at any given time.
That is, if you call IloCplex::use more than once
with the same class of callback, the last call overrides any previous one.
For example, you can use only one primal simplex callback at a
time, or you can use only one network callback at a time; and so forth.
Existing extractables should never be modified within a callback. Temporary extractables, such as arrays, expressions, and range constraints, can be created and modified. Temporary extractables are often useful, for example, for computing cuts.
Compound Termination Criteria in Callbacks
Here is an example showing you how to terminate optimization after a given period of time if the solution is good enough. It uses one of the predefined macros to facilitate writing a control callback with a timer, a time limit, and a way to recognize a good enough solution.
ILOMIPCALLBACK3(MyCallback, IloTimer, myTimer,
IloNum, timeLimit,
IloNum, acceptableGap) {
if ( hasIncumbent() ) {
IloNum objval = getIncumbentObjValue();
IloNum bound = getBestObjValue();
IloNum gap = fabs(objval - bound) / (1.0 + fabs(bound));
if ( myTimer.getTime() > timeLimit &&
gap < acceptableGap ) {
cout << "Good enough solution at = "
<< myTimer.getTime() << " sec., gap = "
<< gap * 100.00 << ", quitting" << endl;
abort();
}
}