Dear community,
as the title suggests, I want to obtain the root relaxation of a branch & cut algorithm. More precisely, if the relaxation is fractional I like to add violated cuts and resolve as long as no violated cuts can be found.
I tried it with an adapted version of the example provided in the JuMP documentation documentation, with both CPLEX and Gurobi (see the code example below).
According to the Gurobi documentation parameters PreCrush
and CutPasses
should do the trick, since user cuts are not added in the root node by default. However, in the example below the callback is not even called, if node_limit=0
.
If CPLEX is used, the callback is called but it has no impact, i.e., the problem is not resolved. I pointed that in this thread of last week, and it seemed that this is an issue of the CPLEX.jl. However, as this example shows the problem could be somewhere else.
So the questions are:
Is this an issue of JuMP, or of CPLEX.jl and Gurobi.jl?
How can I overcome this issue to obtain the root relaxation ?
Thank you in advance, mike
Here is the example code:
## ROOT RELAXATION TEST
#########################
using JuMP
using Gurobi
using CPLEX
#BUILD MODEL
function build_model( solver_type::Int, node_limit::Int )
if( solver_type == 1 ) #GUROBI
m = Model(solver=GurobiSolver(PreCrush=1,
CutPasses=1000,
NodeLimit=node_limit,
Cuts=0,
Presolve=0,
Threads=1,
Heuristics=0.0))
elseif( solver_type == 2 ) #CPLEX
m = Model( solver=CplexSolver(CPXPARAM_MIP_Limits_Nodes = node_limit,
CPXPARAM_Threads = 1,
CPXPARAM_MIP_Display = 2,
#deactivate general purpose cuts
CPXPARAM_MIP_Limits_EachCutLimit = 0,
CPXPARAM_MIP_Cuts_Gomory = -1,
CPXPARAM_MIP_Cuts_LiftProj = -1,
CPXPARAM_MIP_Strategy_CallbackReducedLP = 0,
#deactivate preprocessing
CPXPARAM_Preprocessing_Presolve = 0,
CPXPARAM_Preprocessing_Relax = 0,
CPXPARAM_Preprocessing_RepeatPresolve = 0,
CPXPARAM_MIP_Strategy_PresolveNode = -1,
CPXPARAM_MIP_Strategy_Probe = -1,
#deactivate heuristics
CPXPARAM_MIP_Strategy_HeuristicFreq = -1,
CPXPARAM_MIP_Strategy_RINSHeur = -1,
CPXPARAM_MIP_Strategy_FPHeur = -1,
CPXPARAM_MIP_Strategy_LBHeur = 0))
end
return m
end
#CALLBACK
function mycutgenerator(cb)
x_val = getvalue(x)
y_val = getvalue(y)
println("In callback function, x=$x_val, y=$y_val")
# Allow for some impreciseness in the solution
TOL = 1e-6
# Check top right
if y_val + x_val > 3 + TOL
# Cut off this solution
println("Fractional solution was in top right, cut it off")
# Use the original variables
@usercut(cb, y + x <= 3)
end
end # End of callback function
#MAIN
#parameters
solver_type = 1
node_limit = 0
#build model
m = build_model( solver_type, node_limit )
@variable(m, 0 <= x <= 2, Int)
@variable(m, 0 <= y <= 2, Int)
@objective(m, Max, x + 2y)
@constraint(m, y + x <= 3.5)
addcutcallback(m, mycutgenerator)
# solve problem
solve(m)
# print solution
println("Final solution: [ $(getvalue(x)), $(getvalue(y)) ]")
println("nBB nodes: ", getnodecount(m))