CPX_CALLBACKCONTEXT_BRANCHING

Generic callback at branching

#define CPX_CALLBACKCONTEXT_BRANCHING 0x0080

Description

CPLEX invokes the generic callback in this context when it is done processing a node and has to decide how to branch. This gives the user the possibility either to specify a custom branching decision, or to let CPLEX branch according to the selected branching strategy.

You can use the constant CPX_CALLBACKCONTEXT_BRANCHING in two different ways:
  • As a value passed into the generic callback function to specify in which context the generic callback is invoked.
  • As a bit-wise OR with the where argument of the routine CPXXcallbacksetfunc and CPXcallbacksetfunc to specify in which situations CPLEX should invoke the generic callback.

User branching decisions are always specified in terms of the original model and possibly have to be crushed to the presolved model. (This crushing happens internally in CPLEX.) To guarantee that user branching decisions can be crushed, certain types of nonlinear presolve reductions have to be disabled. Consequently, CPLEX automatically disables those nonlinear presolve reductions if the user asks for the callback to be invoked in this context.

CPLEX invokes the callback in this context before deciding how to branch. To specify a custom branching decision the user can create one or two children nodes with CPXXcallbackmakebranch and CPXcallbackmakebranch. Alternatively, the user can simply instruct CPLEX to prune the current node with CPXXcallbackprunenode and CPXcallbackprunenode. If the routine CPXXcallbackprunenode and CPXcallbackprunenode is invoked, any child node created with CPXXcallbackmakebranch and CPXcallbackmakebranch in the same invocation of the callback is disregarded. If the routines CPXXcallbackprunenode and CPXcallbackprunenode and CPXXcallbackmakebranch and CPXcallbackmakebranch are not invoked (i.e., if the user does not specify any branching), then CPLEX will branch according to the selected branching strategy.

The solution of the continuous relaxation of the current tree node can be queried with CPXXcallbackgetrelaxationpoint and CPXcallbackgetrelaxationpoint. However, when the callback is invoked in this context, the continuous relaxation of the node may not be solved to optimality for various reasons (for example an iteration limit, an infeasible status, etc.). In order to deal with this situation, the routine CPXXcallbackgetrelaxationstatus and CPXcallbackgetrelaxationstatus allows to query the solution status of the node relaxation, and can be used to force solving the current node relaxation in case the optimal solution is not available. The user should call CPXXcallbackgetrelaxationstatus and CPXcallbackgetrelaxationstatus before querying the actual solution with CPXXcallbackgetrelaxationpoint and CPXcallbackgetrelaxationpoint.

Important: All information queried from a callback in this context is local to the thread.
A typical flow of control within this context looks like this (error checking omitted):

int callback(CPXCALLBACKCONTEXTptr context, CPXLONG contextid, void *cbhandle) {
   if ( contextid == CPX_CALLBACKCONTEXT_BRANCHING ) {
      /* Check the status of the continuous relaxation. */
      int statind;
      CPXXcallbackgetrelaxationstatus(context, &statind, 0);
      if ( statind == CPX_STAT_OPTIMAL        ||
           statind == CPX_STAT_OPTIMAL_INFEAS   ) {
         /* Continuous relaxation is solved to optimality. Get the current
          * x-vector and the objective value and create custom branches.
          */
         double *x = ...;
         double obj;
         CPXXcallbackgetrelaxationpoint(context, x, 0, nvars - 1, &obj);
         if ( ... ) {
            /* We decided to cut off the current node. */
            CPXXcallbackrelaxationprunenode(context);
         }
         else {
            /* We want to branch. */
            CPXCNT child1, child2;
            CPXXcallbackmakebranch(context, ..., obj, &child1);
            CPXXcallbackmakebranch(context, ..., obj, &child2);
         }
      }
      else {
         /* The continuous relaxation was not solved to optimality.
          * There may be a problem and some special handling may be required.
          */
         ...
      }
   }
}
      

Incompatibility with Benders algorithm

This context is incompatible with Benders algorithm.

See also