h1. Default CPLEX

Callbacks allow user written code to be run at select points to monitor or influence the behavior of the CPLEX solver.  Before modifying the behavior of the solver, lets understand exactly how the solver works.  Below is a somewhat simplified picture of the algorithm CPLEX is using to solve an integer program.

{gliffy:name=defaultCplex|align=left|size=L|version=3}

The algorithm terminates when the node stack is empty, and the best incumbent found is the new solution.  The first node pushed on, the LP relaxation of the original problem is often called the _root node_.


h1. Lazy Constraints in CPLEX

Lazy constraints, at a high level, are constraints that are only checked when a candidate for an integer solution has been identified.  They can be added to the model at the start though the {{IloCplex}} method {{addLazyConstraint(IloRange range)}}, or they can be added on the fly with a {{LazyConstraintCallback}} (documentation [here|http://pic.dhe.ibm.com/infocenter/cosinfoc/v12r5/index.jsp?topic=%2Filog.odms.cplex.help%2Frefjavacplex%2Fhtml%2Filog%2Fcplex%2FIloCplex.LazyConstraintCallback.html]).  The {{LazyConstraintCallback}} provides a user implemented routine to take a new potential incumbent solution, determine any of the lazy constraints were violated, and if so, to add at least one of them to the model.  Typically, you would want to use lazy constraints when you have a large number of constraints and you expect that few will be violated, as they allow you to have smaller LPs to solve when processing each node.  In the case of the {{LazyConstraintCallback}}, you gain an additional advantage in that you do not need to explicitly store all of the lazy constraints in memory, which is critical for problems like TSP that have an exponential number of constraints.  The downside is that you can waste a lot of time in branch and bound trying to generate integer solutions, only to find that they are actually infeasible.  Regardless of whether {{addLazyConstraint(IloRange range))}} or a {{LazyConstraintCallback}} was used, the model becomes

{gliffy:name=lazyCplex|align=left|size=L|version=1}

h1. Using LazyConstraintCallback

Qualitatively, the idea of the class {{LazyConstraintCallback}} is that you pass CPLEX the function meeting the following specification:
* *Input:* an integral solution to your IP that is guaranteed to satisfy all constraints except the Lazy Constraints not yet added
* *Output:* a (potentially empty) list of violated constraints that is guaranteed to be nonempty if at least one constraint was violated

However, in Java, we do not pass functions (methods), we pass objects satisfying some interface specifying methods.  This means we must create an object of type {{LazyConstraintCallback}}.  The class is {{abstract}}, (see [Java introduction|Do you know Java]), so we must extend the class and fill in the abstract methods, where we will specify how to check for violated constraints.  Since LazyConstraintCallback is an abstract class, it comes with some methods already implemented:

||Method Name||Return Type||Arguments||Description||
|getValue|double|IloNumVar var|Returns the solution value of var at the current node.|
|getValues|double[]|IloNumVar[] vars|Returns the solution values for vars at the current node.|
|add|IloRange|IloRange cut|Adds the constraint cut to the model.  Assumes cut is linear.|

To generate the constraints we will add, we use the same {{IloCplex}} instance that is solving the IP.  Notice that {{IloCplex}} has all of these methods for getting variable values and adding constraints to the model.  However, using these methods in the middle of a callback will cause an error.  E.g., to make a {mathinline} \ge {mathinline} constraint, be sure to call {{cplex.ge()}}, not {{cplex.addGe()}}, as discussed [here|Java and CPLEX#The Java Interface to CPLEX].

{warning:title=Warning}
The method {{getValue(IloNumVar v)}} is significantly slower than {{getValues(IloNumVar[] vars)}}, as [previously discussed for IloCplex|Java and Cplex#Performance Issues Reading Variable Values from CPLEX].
{warning}

It is convenient to make the new class an [inner class|http://docs.oracle.com/javase/tutorial/java/javaOO/nested.html] of the class where you are formulating your optimization problem, as then all of the fields which hold your problem data will be accessible.  In particular, you will need access to the {{IloCplex}} instance as well as whatever data structure you have storing you {{IloIntVar}} instances.

h1. Implementing LazyConstraintCallback for the Cutset constraints