Hi Paul,
thanks for your feedback.
I was also somewhat surprised to see branch callbacks being called before heuristic callbacks. My experiment was the following:
- I added both callbacks.
- Whenever a callback is called reads, prints and modifies the node data leaving a message.
By doing that, the branch callback at a given node_id always finds empty node data, while the heuristic callback always finds the message left by the branch callback. To me, this is enough evidence to conclude that branch callbacks are called before. Nevertheless, this is not too problematic, I can still achieve what I want, regardless of the order.
I do not expect lazy constraints callbacks to be called at integer nodes only when their value is better than the incumbent. They should be called at all integer feasible solutions. Quoting the documentation "This callback will be used when CPLEX finds a new integer feasible solution ... ".
In any case, now I am able to branch at an integer node, to replace the current integer feasible solution with a different integer feasible solution (or better said, I leave the value of the integer variables unchanged, and replace only the solution of the remaining nonnegative variables, thus the solution remains integer and feasible). Nevertheless, lazy constraints are not called.
But I will definitely look up newer versions. I am currently using 20.1.
------------------------------
Giovanni Pantuso
------------------------------
Original Message:
Sent: Wed October 26, 2022 05:30 PM
From: Paul Rubin
Subject: Understanding the interplay between callbacks
I believe you are incorrect about branch callbacks being called before heuristic callbacks. My understanding is as follows.
- When CPLEX visits a node and solves the node LP, it calls the heuristic callback (if present) after solving the node LP (including any adding of cuts).
- After that, if the node yields an integer feasible solution (the node LP solution is integer, node heuristics find an integer solution, or added cuts get the LP to cough up an integer solution), and if the integer feasible solution looks like a candidate to be the new incumbent (better objective value than the current incumbent), the lazy constraint callback (if present) is called.
- Finally, assuming the node is not pruned for being infeasible or suboptimal, the branch callback (if present) is called.
Any combination of the three callbacks can be used. In recent versions of CPLEX, you can also use a generic callback. Each of those situations now becomes a "context" (passed to the generic callback when it is called). The generic callback checks to see which context it is in and runs the corresponding code.
------------------------------
Paul Rubin
Professor Emeritus
Michigan State University
------------------------------