Originally posted by: SystemAdmin
Hi to all,
I am currently solving a problem using a branch-and-price scheme. Since CPLEX does not support B&P over column generation formulations (i.e., does not let you include additional variables while branching), I decided to branch over the original variables of an aggregated formulation that I have. The idea is, as in many branch and price schemes, to stop CPLEX before solving the problem at each node, then, use the information of the node to solve a reformulation of the problem via column generation (which produces a better bound), and finally, reconstruct the solution found in terms of the variables of the aggregated formulation, pass it to CPLEX, and ask it to use it instead of using the solution that would be produced if the aggregated formulation is solved. To do that, I know from the
AdMIPex6
example that you can use a
SolveCallback
.
Basically, if I understand it correctly, in the
SolveCallback
what you do is set the values of the variables using
setVectors
. You do not even need to set all the variables, just some of them; CPLEX would find the values of the other variables (if a valid feasible solution exists with the given values). Now, if you just use
setVectors
, CPLEX will use the solution as an initial value, but it will try to continue solving the node. To stop CPLEX you have to include
useSolution()
and CPLEX will use the given solution. Am I correct?
I try to use that but I was getting the following exception:
Concert Error: ilog.cplex.CpxException: CPLEX Error 3019: Failure to solve MIP subproblem.
I try several things to ensure that the solution that I was passing was feasible and correct, but all the effort was in vain, I was still getting the same exception. Then, I decided to use the same approach in a simpler problem (as a prove of concept) just to see if I was able to do it correctly. I came up with the following example:
max x+y
s.t.
2x+2y<=3
-x+y<=2
x,y in {0,1}
The optimal solution is x=1, y=0, but the relaxation is x=0.5,y=1.
Using the
SolveCallback
I try to pass optimal solution but I still get the same problem (Concert exception caught: ilog.cplex.CpxException: CPLEX Error 3019: Failure to solve MIP subproblem.)
The code I used follows (I use Java). I apologize for this code. I know that the way I formulated is probably the ugliest way for doing it, but I was not paying too much attention to the details, I just wanted to do it fast.
Do you have any ideas or suggestions?
Thanks a lot in advance.
-Jose
import ilog.concert.*;
import ilog.cplex.*;
public
class TestOfAdMIPex6
{
static
class Solve
extends IloCplex.SolveCallback
{
boolean _done =
false; IloNumVar[] x; IloNumVar[] y; Solve(IloNumVar[] x, IloNumVar[] y)
{ this.y = y; this.x = x;
}
public
void main()
throws IloException
{
double num[]=
new
double[1]; num[0]=1; setVectors(num, x, null,
null); num[0]=0; setVectors(num, y, null,
null); useSolution();
}
}
public
static
void main(String[] args)
{
try
{ IloCplex cplex =
new IloCplex(); IloNumVar[] x=
new IloNumVar[1]; IloNumVar[] y=
new IloNumVar[1]; x[0]=cplex.numVar(0.0, 1.0, IloNumVarType.Bool,
"x"); y[0]=cplex.numVar(0.0, 1.0, IloNumVarType.Bool,
"y"); IloLinearNumExpr lin=cplex.linearNumExpr();
//Constraint 1 lin.addTerm(2, x[0]); lin.addTerm(2, y[0]); cplex.addLe(lin, 3); lin.clear();
//Constraint 2 lin.addTerm(-1, x[0]); lin.addTerm(1, y[0]); cplex.addLe(lin, 2); lin.clear();
//OF lin.addTerm(1, x[0]); lin.addTerm(1, y[0]); cplex.addMaximize(lin); cplex.use(
new Solve(x,y)); cplex.setParam(IloCplex.BooleanParam.PreInd,
false); cplex.setParam(IloCplex.IntParam.Threads, 1); cplex.setParam(IloCplex.IntParam.MIPSearch, IloCplex.MIPSearch.Traditional); cplex.setParam(IloCplex.IntParam.HeurFreq, -1);
//turn off heuristic cplex.setParam(IloCplex.DoubleParam.CutsFactor , 1.0);
//add no cuts cplex.setParam(IloCplex.IntParam.Reduce, 0); cplex.solve(); System.out.println(
"Relaxed solution status = " + cplex.getStatus()); System.out.println(
"Relaxed solution value = " + cplex.getObjValue()); System.out.println(
"x = " + cplex.getValue(x[0])); System.out.println(
"y = " + cplex.getValue(y[0])); cplex.setParam(IloCplex.IntParam.MIPSearch, IloCplex.MIPSearch.Traditional);
if ( cplex.solve() )
{ System.out.println(
"Solution status = " + cplex.getStatus()); System.out.println(
"Solution value = " + cplex.getObjValue());
} cplex.end();
}
catch (IloException e)
{ System.err.println(
"Concert exception caught: " + e);
}
}
}
#CPLEXOptimizers#DecisionOptimization