Callbacks

COPT provides the Callbacks utility, which supports users to obtain intermediate information (such as the current best bound, the current optimal objective value, etc.) during the MIP solving process; or control the solving process: such as modifying the model (such as adding lazy constraints, adding cutting planes), terminating the solving procress and so on. The problem types supporting the use of Callbacks are MILP, MISOCP, MIQ(C)P.

The content of this chapter is organized as follows:

Obtain the intermediate information of the MIP

The intermediate information that can be obtained during the MIP solving process depends on the Callback Context. The supported Contexts are as follows:

  • CBCONTEXT_MIPSOL: Invokes the callback when a new MIP candidate solution is found.

  • CBCONTEXT_MIPRELAX : Invokes the callback when a new LP-relaxation solution is found.

  • CBCONTEXT_MIPNODE: Invokes the callback when a MIP node is processed and LP-relaxation has been solved.

Regarding the Callback information supported by COPT, please refer to the Callback related information section for details.

The corresponding relationships are listed in the following table:

Context

Callback Information

CBCONTEXT_MIPSOL

MipCandObj, MipCandidate

CBCONTEXT_MIPRELAX

RelaxSolution, RelaxSolObj

CBCONTEXT_MIPNODE

NodeStatus, RelaxSolution, RelaxSolObj, MipCandObj, MipCandidate

BestObj, BestBnd, HasIncumbent, Incumbent can be obtained at any context (that is, both CBCONTEXT_MIPNODE, CBCONTEXT_MIPSOL and CBCONTEXT_MIPRELAX ).

Notes

  1. If HasIncumbent == False, then Incumbent cannot be obtained.

  2. For Incumbent , LP-relaxation Solution , Incumbent, these three items are obtained through different methods in different interfaces:

    • C language: through the function COPT_GetCallbackInfo, the name of the intermediate information to be obtained is provided as a parameter of the function;

    • In object-oriented programming languages (C++/C#/Java/Python), the CallbackBase class provides specialized functions to obtain corresponding intermediate information.

  3. In object-oriented programming languages (C++/C#/Java/Python), CallbackBase.getInfo(infoname) function, only supports obtaining information constants of scalar type, namely: NodeStatus, MipCandObj, RelaxSolObj, BestObj, BestBnd, HasIncumbent. As for other non-scalar information, they provide specialized function access.

    Taking the Python interface as an example, the corresponding function names are listed below. Other programming language interfaces are similar, you can refer to the CallbackBase class of each API.

    • Get the current feasible solution: CallbackBase.getSolution()

    • Get the current LP relaxation solution: CallbackBase.getRelaxSol()

    • Get the current optimal feasible solution: CallbackBase.getIncumbent()

Controlling the MIP solving process

COPT provides functions to allow users to interactively add lazy constraints or cutting planes during the solving process of the MIP branch-and-cut to control the MIP solving process. There are three main types of operations:

  1. Add lazy constraints

  2. Add cutting planes

  3. Set up feasible solutions

Add lazy constraints

COPT supports users to add lazy constraints in two ways, one is to add directly to the model, and the other is to add in specified context during the solving process through Callback. In the C API, it is distinguished according to whether the function name contains "Callback"; In the object-oriented API, the functions corresponding to Model class and CallbackBase respectively:

  1. Before solving, user can directly add to the model, and COPT supports adding unilateral and bilateral lazy constraints. Take Python as an example:

  • Add a single lazy contraint: Model.addLazyConstr()

  • Add a set of lazy contraints: Model.addLazyConstrs()

  1. During the solving process, user can dynamically add according to the specified context through callback, and COPT only supports the addition of single-sided lazy constraints. Take Python as an example:

  • Add a single lazy contraint: CallbackBase.addLazyConstr()

  • Add a set of lazy contraints: CallbackBase.addLazyConstrs()

Add cutting planes

Similarly, for cutting planes, COPT also supports the above two adding methods.

  1. Before solving, user can directly add to the model, and COPT supports adding unilateral and bilateral cutting-planes. Take Python as an example:

  • Add a single cutting-plane: Model.addUserCut()

  • Add a set of cutting-planes: Model.addUserCuts()

  1. During the solving process, user can dynamically add according to the specified context through callback, and COPT only supports the addition of single-sided cutting-planes. Take Python as an example:

  • Add a single cutting-plane: CallbackBase.addUserCut()

  • Add a set of cutting-planes: CallbackBase.addUserCuts()

Notes

  • It is invalid to call the functions of Model class to add lazy constraints or user cutting-planes in Callback.

Set feasible solutions

COPT supports adding feasible solutions (the user can provide any feasible solution they found in the meantime, e.g. in some self-implemented heuristic.) during the MIP solving process.

  • Set the feasible solution: CallbackBase.setSolution(vars, val)

  • Load a custom solution into the model: CallbackBase.loadSolution()

Notes

Currently supports setting complete feasible solutions.

Similarly, certain callback functions that operate on models can only be called at specified context.

Taking python as an example, the functions in CallbackBase class and the corresponding callback context are listed as follows:

Context

Function

CBCONTEXT_MIPSOL

CallbackBase.addLazyConstr CallbackBase.addLazyConstrs CallbackBase.getSolution CallbackBase.setSolution CallbackBase.getIncumbent CallbackBase.getInfo

CBCONTEXT_MIPRELAX

CallbackBase.addUserCut CallbackBase.addUserCuts CallbackBase.getRelaxSol CallbackBase.getIncumbent CallbackBase.setSolution CallbackBase.getInfo

CBCONTEXT_MIPNODE

CallbackBase.getRelaxSol CallbackBase.getIncumbent CallbackBase.setSolution CallbackBase.getInfo

Notes

The function forms may slightly look different in different APIs, but the corresponding relationship is the same. For the C language chapter, please refer to C API: callback function for details.

Using the callback utilities in different APIs

Take the object-oriented programming interface as an example to show the basic steps of calling the Callback function in different APIs:

  1. Build a custom Callback class and inherit the CallbackBase class;

  2. Implement the CallbackBase.callback() function, in which you can customize the operations you need to perform (such as obtaining intermediate information or adding lazy constraints/cutting-planes);

  3. Create a new custom Callback instance and pass in the arguments required;

  4. Add a Callback instance through Model.setCallback() of the Model class, and input the Callback Context as a parameter.

In the subsequent solving process, in the specified Callback Context, the user-defined callback function in the Callback instance will be called.

The specific implementation in each programming language API is also similar, you can refer to the sample code.Taking Python as an example, "cb_ex1.py" is in the examples directory in the installation package.

The calling method and function name of the callback function in different programming interfaces are slightly different, but the supported functions and function meanings are the same. Please refer to the corresponding chapters of different programming interface API reference manuals for specific introductions: