Originally posted by: AlbertoSantini
Since you want to add cuts to integer incumbents, you should use a lazy constraint callback because the user cut callback is not called when an integer incumbent is found.
You are right. Unfortunately lazy constraints are not really suitable for my purpose. The manual says that:
Lazy constraints are constraints that the user knows are unlikely to be violated, and in consequence, the user wants them applied lazily, that is, only as necessary or not before needed.
Which is not true in my case, as the cuts are subtour elimination cuts for a Travelling Salesman Problem. The way I thought to solve this issue is by checking that the integer solution is valid in 2 places:
1) in the cuts callback (in case the integer solution is found as the solution of the relaxation of the problem);
2) in an incumbent callback, by calling the reject() method of IloCplex::IncumbentCallbackI in case the solution is not feasible.
Right now I'm trying to do just this, but I'm wondering if my approach would also require me to instruct CPLEX on how to branch after an incumbent has been refused.
In short, having such a huge number of potential cuts makes the approach of adding all of them as lazy constraints infeasible, in my opinion. Again, I'm open to suggestions on how to implement this.
Going back to the solution you kindly proposed, I came up with somehting similar too, but it has the disadvantage that it relies on a global variable counting the current node number. I would like to avoid using such an approach, as global variables tend to lead to unpredicatable errors, as their value can be set anywhere in the programme. I thought it was impossible that the node number is not available to IloCplex::UserCutCallbackI but maybe I should review my expectation?
Thanks,
AS
#CPLEXOptimizers#DecisionOptimization