Originally posted by: JorisK
Given an IloCplex MIP model, I'm trying to solve the LP relaxation. One could set the nodeLim=0, but that is not exactly the same as solving the LP relaxation because:
-
with nodeLim=0, cplex still creates cuts and applies heuristics at the root
-
dual values and reduced costs can only be queried if the problem is an actual LP, not a MIP
So in order to solve the pure LP relaxation, all variables must be of the type ILOFLOAT. One easy way to fix this is to iterate over all integer variables in the model and to apply an IloConversion to those variable. This works if you store a reference to each integer variable. Interestingly, the following does not work:
public static void solveLP(IloCplex cplex) throws IloException {
//Convert all integer variables into continuous variables
List<IloConversion> conversions=new LinkedList<>();
for(Iterator it = cplex.iterator(); it.hasNext(); ){
Object o=it.next();
if(o instanceof IloIntVar){
IloIntVar var=(IloIntVar) o;
IloConversion conv=cplex.conversion(var, IloNumVarType.Float);
conversions.add(conv);
cplex.add(conv);
}
}
//Do something with the model, e.g. solve
cplex.solve();
//Restore original model
for(IloConversion conv : conversions)
cplex.remove(conv);
}
public static IloCplex buildModel() throws IloException {
IloCplex cplex = new IloCplex();
IloNumVar[] vars = new IloNumVar[3];
vars[0] = cplex.intVar(-3, 5, "x");
vars[1] = cplex.intVar(0, 10, "y");
vars[2] = cplex.intVar(-5, 5, "z");
cplex.addMaximize(
cplex.scalProd(new double[]{1., 2., 3.}, vars),"Obj"
);
cplex.addLe(cplex.sum(vars), 5., "Con1");
cplex.addLe(cplex.scalProd(new double[]{0., 1., 2.}, vars),3., "Con2");
cplex.addEq(vars[0], vars[2], "Con3");
return cplex;
}
public static void main(String[] args) throws IloException {
IloCplex model=buildModel();
solveLP(model);
}
The reason this doesn't work is that the iterator in solveLP does not return any of the variables in the model! I could fix this by manually adding all variables to the model, i.e. by explicitly adding the line `cplex.add(vars)` at the end of buildModel. This is quite weird though, since the variables are already part of the model (they are in the constraints).
Is there a cleaner way of fixing this, i.e. how can I iterate over all variables in my model? I could use the rangeIterator and iterate over all constraints and then iterate over all variables in each constraint, but that's even worse since many variables appear in multiple constraints.
Edit: Paul has a blogpost about obtaining a set of variables from the cplex model: https://orinanobworld.blogspot.com/2011/12/extracting-variables-in-cplex.html However, this still seems rather cumbersome to simply compute a pure LP solution.
#CPLEXOptimizers#DecisionOptimization