Skip to main content
FRAMES NO FRAMES

Callbacks in Concert Technology
PREVIOUS NEXT

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:

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:

  1. Determine which kind of callback you want to write, and choose the appropriate class for it. The class hierarchy in Tree may give you some ideas here.
  2. Derive your own subclass, MyCallbackI, say, from the appropriate predefined callback class.
  3. In your subclass of the callback class, use the protected API defined in the base class to implement the 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.)
  4. In your subclass, implement the method duplicateCallback.
  5. Write a function myCallback, say, that creates an instance of your implementation class in the Concert Technology environment and returns it as an IloCplex::Callback handle.
  6. Create an instance of your callback class and pass it to the member function 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();
     }
  }
PREVIOUS NEXT