Hello,
I have a couple of questions regarding Branch and Cut in Python using Gurobi as a solver.
In a maximisation problem, at each node, I would like to add cuts (obtained from a separation problem) to cut off fractional solutions. I have done this using callback functions.
if where == GRB.callback.MIPNODE:
nodecnt = int(model.cbGet(GRB.callback.MIPNODE_NODCNT))
status = model.cbGet(GRB.Callback.MIPNODE_STATUS)
print '*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*'
print "Node count: %s" %nodecnt
print "Objective bound: %s" %mipnodeobjbnd
print '*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*'
if status==GRB.OPTIMAL:
CurrentBestObjBound=model.cbGet(GRB.callback.MIPNODE_OBJBND)
CurrentBestObj=model.cbGet(GRB.callback.MIPNODE_OBJBST)
if CurrentBestObjBound-CurrentBestObj>0.001:
I generate and optimize my Separation Problem.
I get one of two types of cuts (feasibility or optimality)
If cut is violated:
model.cbCut( bla bla)
print "OPTIMALITY CUT ADDED" (or feasibility cut added)
From what I see from the output it would appear that several cuts are added at the root node but then from then on, no more than one cut is added at subsequent nodes.
Changed value of parameter Presolve to 0
Prev: -1 Min: -1 Max: 2 Default: -1
Changed value of parameter Heuristics to 0.0
Prev: 0.05 Min: 0.0 Max: 1.0 Default: 0.05
Changed value of parameter Cuts to 0
Prev: -1 Min: -1 Max: 3 Default: -1
Changed value of parameter PreCrush to 1
Prev: 0 Min: 0 Max: 1 Default: 0
Changed value of parameter TimeLimit to 1800.0
Prev: 1e+100 Min: 0.0 Max: 1e+100 Default: 1e+100
Changed value of parameter Threads to 1
Prev: 0 Min: 0 Max: 1024 Default: 0
*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*
Node count: 0.0
Objective bound: 21.9468085106
*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*
OPTIMALITY CUT ADDED
*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*
Node count: 0.0
Objective bound: 6.26442665386
*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*
OPTIMALITY CUT ADDED
*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*
Node count: 0.0
Objective bound: 6.26442665386
*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*
OPTIMALITY CUT ADDED
*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*
Node count: 1.0
Objective bound: 6.25559677952
*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*
OPTIMALITY CUT ADDED
*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*
Node count: 2.0
Objective bound: 6.25141656732
*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*
OPTIMALITY CUT ADDED
*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*
Node count: 3.0
Objective bound: 6.24290495181
*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*
OPTIMALITY CUT ADDED
*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*
Node count: 4.0
Objective bound: 6.23847511683
*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*
OPTIMALITY CUT ADDED
*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*
Node count: 5.0
Objective bound: 6.22881353932
*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*
OPTIMALITY CUT ADDED
*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*
Node count: 6.0
*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*
Cutting planes:
User: 8
Explored 7 nodes (51 simplex iterations) in 0.27 seconds
Thread count was 1 (of 4 available processors)
Optimal solution found (tolerance 1.00e-04)
Best objective 6.182651391162e+00, best bound 6.182651391162e+00, gap 0.0%
So it seems that I am adding cuts at the root node and then at some point, the algorithm decides to branch and move on to the next node. Is there no way I can control how many cuts I can add at a node before branching? Also, I get the impression that once the cut is added at a node other than the root node, that node is not then resolved before moving on the next one. Is this the case? Again, how can I ensure staying at the node to apply successive rounds of cuts before moving on?
I guess that I would be able to do what I want if the callback were called when a new fractional solution is found and not when a new node is visited. I would then have some parameter to force the algorithm to branch after a certain condition is met (number of cuts added at the node, or time spent at the node). Is this possible?
Any help will be appreciated :) Thank you!
Carlos.