Question & Answer
Question
How do I invoke the conflict refiner or call feasopt using the Java API and concert technology?
Cause
The CPLEX documentation includes an example to call feasopt using the C++ API in Concert under the "User's Manual > ILOG CPLEX User's Manual > Infeasibility and unboundedness > Repairing infeasibilities with FeasOpt > Example: FeasOpt in Concert Technology" section.
The documentation also illustrates a C++ sample to call the conflict refiner in the "User's Manual > ILOG CPLEX User's Manual > Infeasibility and unboundedness > Diagnosing infeasibility by refining conflicts > Using the conflict refiner in an application > Example: modifying ilomipex2.cpp" section.
Given the differences between the C++ and the Java API, the methods used for the invocation of the conflict refiner and feasopt are different. This sample is essentially an equivalent sample using the Java API.
Answer
<infeasAnalysis.java>
import java.util.*;
import ilog.concert.*;
import ilog.cplex.*;
public class infeasAnalysis {
public static void main(String[] args) {
try {
if (args.length != 1)
{
System.out.println("Usage: infeasAnalysis <model_file_name>");
return;
}
IloCplex cplex = new IloCplex();
cplex.importModel(args[0]);
Iterator matrixEnum = cplex.LPMatrixIterator();
IloLPMatrix lp = (IloLPMatrix)matrixEnum.next();
//Disable CPLEX logs
cplex.setOut(null);
if (cplex.solve())
{
System.out.println("Model Feasible");
System.out.println("Solution status = " + cplex.getStatus());
System.out.println("Solution value = " + cplex.getObjValue());
double[] x = cplex.getValues(lp);
for (int j = 0; j < x.length; ++j)
System.out.println("Variable Name:"+lp.getNumVar(j).getName()+"; Value = " + x[j]);
}
else
{
System.out.println("Solution status = " + cplex.getStatus());
System.out.println("Model Infeasible, Calling CONFLICT REFINER");
IloRange[] rng = lp.getRanges();
int numVars = 0;
//calculate the number of non-boolean variables
for (int c1 = 0; c1 < lp.getNumVars().length; c1++)
if (lp.getNumVar(c1).getType() != IloNumVarType.Bool)
numVars++;
//find the number of SOSs in the model
int numSOS = cplex.getNSOSs();
System.out.println("Number of SOSs=" + numSOS);
int numConstraints = rng.length+2*numVars+numSOS;
IloConstraint[] constraints = new IloConstraint[numConstraints];
for (int c1 = 0; c1 < rng.length; c1++)
{
constraints[c1] = rng[c1];
}
int numVarCounter = 0;
//add variable bounds to the constraints array
for(int c1=0;c1<lp.getNumVars().length;c1++)
{
if (lp.getNumVar(c1).getType() != IloNumVarType.Bool)
{
constraints[rng.length + 2*numVarCounter] = cplex.addLe(lp.getNumVar(c1).getLB(), lp.getNumVar(c1));
constraints[rng.length + 2 * numVarCounter].setName(lp.getNumVar(c1).toString() + "_LB");
constraints[rng.length + 2*numVarCounter + 1] = cplex.addGe(lp.getNumVar(c1).getUB(), lp.getNumVar(c1));
constraints[rng.length + 2 * numVarCounter + 1].setName(lp.getNumVar(c1).toString() + "_UB");
numVarCounter++;
}
}
//add SOSs to the constraints array
if (numSOS > 0)
{
int s1Counter = 0;
Iterator s1 = cplex.SOS1iterator();
while (s1.hasNext())
{
IloSOS1 cur = (IloSOS1)s1.next();
System.out.println(cur);
constraints[rng.length + numVars * 2 + s1Counter] = (IloConstraint)cur;
s1Counter++;
}
int s2Counter = 0;
Iterator s2 = cplex.SOS2iterator();
while (s2.hasNext())
{
IloSOS2 cur = (IloSOS2)s2.next();
System.out.println(cur);
constraints[rng.length + numVars * 2 + s1Counter + s2Counter] = (IloConstraint)cur;
s2Counter++;
}
}
double[] prefs = new double[constraints.length];
for (int c1 = 0; c1 < constraints.length; c1++)
{
//System.out.println(constraints[c1]);
prefs[c1] = 1.0;//change it per your requirements
}
if (cplex.refineConflict(constraints, prefs))
{
System.out.println("Conflict Refinement process finished: Printing Conflicts");
IloCplex.ConflictStatus[] conflict = cplex.getConflict(constraints);
int numConConflicts = 0;
int numBoundConflicts = 0;
int numSOSConflicts = 0;
for (int c2 = 0; c2 < constraints.length; c2++)
{
if (conflict[c2] == IloCplex.ConflictStatus.Member)
{
System.out.println(" Proved : " + constraints[c2]);
if (c2 < rng.length)
numConConflicts++;
else if (c2 < rng.length + 2*numVars)
numBoundConflicts++;
else
numSOSConflicts++;
}
else if (conflict[c2] == IloCplex.ConflictStatus.PossibleMember)
{
System.out.println(" Possible : " + constraints[c2]);
if (c2 < rng.length)
numConConflicts++;
else if (c2 < rng.length + 2*numVars)
numBoundConflicts++;
else
numSOSConflicts++;
}
}
System.out.println("Conflict Summary:");
System.out.println(" Constraint conflicts = " + numConConflicts);
System.out.println(" Variable Bound conflicts = " + numBoundConflicts);
System.out.println(" SOS conflicts = " + numSOSConflicts);
}
else
{
System.out.println("Conflict could not be refined");
}
System.out.println("Calling FEASOPT");
// cplex.SetParam(Cplex.IntParam.FeasOptMode, 0);//change per feasopt requirements
// Relax contraints only, modify if variable bound relaxation is required
double[] lb_pref = new double[rng.length];
double[] ub_pref = new double[rng.length];
for (int c1 = 0; c1 < rng.length; c1++)
{
lb_pref[c1] = 1.0;//change it per your requirements
ub_pref[c1] = 1.0;//change it per your requirements
}
if (cplex.feasOpt(rng, lb_pref, ub_pref))
{
System.out.println("Finished Feasopt");
double[] infeas = cplex.getInfeasibilities(rng);
//Print bound changes
System.out.println("Suggested Bound changes:");
for (int c3 = 0; c3 < infeas.length; c3++)
if(infeas[c3]!=0)
System.out.println(" "+rng[c3] + " : Change=" + infeas[c3]);
System.out.println("Relaxed Model's obj value=" + cplex.getObjValue());
System.out.println("Relaxed Model's solution status:" + cplex.getCplexStatus());
double[] x = cplex.getValues(lp);
for (int j = 0; j < x.length; ++j)
System.out.println("Relaxed Model's Variable Name:"+lp.getNumVar(j).getName()+"; Value = " + x[j]);
}
else
{
System.out.println("FeasOpt failed- Could not repair infeasibilities");
}
}
cplex.end();
}
catch (ilog.concert.IloException e) {
System.out.println("Concert exception caught: " + e);
}
}
}
<test_infeas.lp>
Maximize
obj: x1 + 2 x2 + 3 x3
Subject To
c1: x2 + x3 <= 20
c2: x1 - 3 x2 + x3 <= 30
c3: x1<= 20
c4: x1>=40
Bounds
0 <= x1 <= 40
Generals
x1 x2 x3
End
The program imports a model (passed as a command line argument) and then sets an equal preference (weight) of 1.0 to every constraint in the model- users may change this per their requirements. It first calls the conflict refiner and prints out the 'proven' and 'possible' constraints causing the infeasibility. It then calls feasopt and prints the suggested bound changes for the appropriate constraints.
Was this topic helpful?
Document Information
Modified date:
16 June 2018
UID
swg21437987