IBM Support

Calling the Conflict Refiner and Feasopt using the Java API

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.

[{"Product":{"code":"SSSA5P","label":"IBM ILOG CPLEX Optimization Studio"},"Business Unit":{"code":"BU059","label":"IBM Software w\/o TPS"},"Component":"Samples from Model Building in Mathematical Programming","Platform":[{"code":"PF002","label":"AIX"},{"code":"PF010","label":"HP-UX"},{"code":"PF016","label":"Linux"},{"code":"PF022","label":"OS X"},{"code":"PF027","label":"Solaris"},{"code":"PF033","label":"Windows"}],"Version":"11.0;11.0.1;11.1;11.1.1;11.2;11.2.1;12.0;12.1;12.2","Edition":"Standard","Line of Business":{"code":"LOB10","label":"Data and AI"}},{"Product":{"code":"SSSA5P","label":"IBM ILOG CPLEX Optimization Studio"},"Business Unit":{"code":"BU059","label":"IBM Software w\/o TPS"},"Component":"General","Platform":[{"code":"PF002","label":"AIX"},{"code":"PF010","label":"HP-UX"},{"code":"PF016","label":"Linux"},{"code":"PF027","label":"Solaris"},{"code":"PF033","label":"Windows"},{"code":"PF017","label":"Mac OS"}],"Version":"12.2","Edition":"All Editions","Line of Business":{"code":"LOB10","label":"Data and AI"}}]

Document Information

Modified date:
16 June 2018

UID

swg21437987