Dear All,
I am trying to implement the fix-and-dive heuristic for the traveling salesman problem in JuMP
with Gurobi
based on the Python+Gurobi
code available here: https://github.com/Gurobi/pres-mipheur/blob/master/mipheurs.md#callback-for-fix-and-dive-heuristic. This heuristic works as follows: when a fractional solution contains some variables at 1, we fix those and solve the smaller submodel, whose solution is then submitted as a heuristic solution. For convenience, I am recording the Python+Gurobi
code below:
# Callback for fix-and-dive heuristic
# -------------------------------------------
def fixcb(subcb=None):
def inner(model, where):
if where == GRB.Callback.MIPNODE:
if model.cbGet(GRB.Callback.MIPNODE_STATUS) == GRB.OPTIMAL:
# Try solving the fixed submodel
fixed = model._fixed
# Relaxed values near 1.0 get the lower bound set to 1.0
for k,v in model.cbGetNodeRel(model._vars).items():
fixed._vars[k].LB = math.floor(v+0.01)
# Set a cutoff for the fixed model, based on the current best solution
if model.cbGet(GRB.Callback.MIPNODE_SOLCNT) > 0:
fixed.Params.Cutoff = model.cbGet(GRB.Callback.MIPNODE_OBJBST)
fixed.optimize(tspcb(subcb)) # call subproblem callback
if fixed.status == GRB.OPTIMAL:
fixedvals = fixed.getAttr('x', fixed._vars)
model.cbSetSolution(model._vars, fixedvals)
return inner
# Create the fixed model
# ------------------------------
def tspmipwithfixed(n, dist):
m = tspmip(n, dist) # main model
m._fixed = tspmip(n, dist) # fixed model
m._fixed.Params.OutputFlag = 0
m._fixed._parent = m
return m
The code requires to look at the existing fractional solution via cbGetNodeRel
, and I am not sure how to do that in the Gurobi specific callback in https://github.com/jump-dev/Gurobi.jl#callbacks. I will appreciate any tips/suggestion how to do the same thing via Gurobi
specific callback or solver independent callback in Julia.