I have a MIP in which I am able to generate cuts at intermediate relaxation solutions using the context class. These cuts are derived from a separation problem. However, after adding them, the code runs very slowly since the separation problem takes some time to solve.
I tried adding cuts sparingly based on the iteration number or the node number, but this did little to improve the LP relaxation solutions.
Does anyone have advice on how best to schedule the calls to the separator to improve the LP bounds? Additionally, I am unsure about what CPLEX does when I ask it to apply the cuts every (say) 2000 iterations. Does it call the separation problem for all nodes left or just a single node?
I am using the following code before I call the solve function.
connectivity_cb = SeparationProblem(arguments...)
contextmask = 0
contextmask |= cplex.callbacks.Context.id.relaxation
contextmask |= cplex.callbacks.Context.id.candidate
if contextmask:
problem.set_callback(connectivity_cb, contextmask)
The SeparationProblem has an invoke function like the CPLEX examples.
def should_add_user_cuts(self, context):
iteration_count = context.get_int_info(context.info.iteration_count)
return (iteration_count % 20) == 0
def invoke(self, context):
try:
if context.in_candidate():
self.add_type1_cut(context)
elif context.in_relaxation() and self.should_add_user_cuts(context):
self.add_type2_cut(context)
except:
info = sys.exc_info()
print('#### Exception in callback: ', info[0])
print('#### ', info[1])
print('#### ', info[2])
traceback.print_tb(info[2], file=sys.stdout)
raise
```