How to enable linear relaxation outputs

Viewed 86

I have a rather complex MILP, but the main problem is the number of continuous variables, not the number of binaries. I just "hard-coded" the linear relaxation to understand its output, and it takes approx. 10-15 minutes to solve (which is not extremely surprising). If I run the MILP with outputs, I don't see anything happening for the first 10 minutes, because it takes those 10 minutes to construct a first integer-feasible solution. So it would help to be able to enable the same outputs I am seeing when solving the linear relaxation "manually" (so something like Iteration: 1 Dual objective = 52322816.412592) within the B&B output.

Is this possible? I googled at bit, but I only found solutions for steering the solution algorithm, or for deriving linear relaxations using callbacks, while I am interested in a "simple" output of the intermediate steps.

2 Answers

It sounds like you are asking for extra detailed logging during the linear relaxation part of the solve during the B&B. Have a look at the CPLEX parameter settings like IloCplex.Param.MIP.Display (try setting this to 5) and also IloCplex.Param.Simplex.Display (try setting to 1 or 2).

within java you could rely on IloConversion objects that will allow you to locally change the type of one or more variables.

See the sample AdMIPex6.java

/* --------------------------------------------------------------------------
 * File: AdMIPex6.java
 * Version 20.1.0  
 * --------------------------------------------------------------------------
 * Licensed Materials - Property of IBM
 * 5725-A06 5725-A29 5724-Y48 5724-Y49 5724-Y54 5724-Y55 5655-Y21
 * Copyright IBM Corporation 2001, 2021. All Rights Reserved.
 *
 * US Government Users Restricted Rights - Use, duplication or
 * disclosure restricted by GSA ADP Schedule Contract with
 * IBM Corp.
 * --------------------------------------------------------------------------
 *
 * AdMIPex6.java -- Solving a model by passing in a solution for the root node
 *                  and using that in a solve callback
 *
 * To run this example, command line arguments are required:
 *     java AdMIPex6  filename
 * where 
 *     filename  Name of the file, with .mps, .lp, or .sav
 *               extension, and a possible additional .gz 
 *               extension.
 * Example:
 *     java AdMIPex6  mexample.mps.gz
 */

import ilog.concert.*;
import ilog.cplex.*;


public class AdMIPex6 {
   static class Solve extends IloCplex.SolveCallback {
      boolean     _done = false;
      IloNumVar[] _vars;
      double[]    _x;
      Solve(IloNumVar[] vars, double[] x) { _vars = vars; _x = x; }
    
      public void main() throws IloException {
         if ( !_done ) {
            setStart(_x, _vars, null, null);
            _done = true;
         }
      }
   }

   public static void main(String[] args) {
      try (IloCplex cplex = new IloCplex()) {
         cplex.importModel(args[0]);
         IloLPMatrix lp = (IloLPMatrix)cplex.LPMatrixIterator().next();
       
         IloConversion relax = cplex.conversion(lp.getNumVars(),
                                                IloNumVarType.Float);
         cplex.add(relax);

         cplex.solve();
         System.out.println("Relaxed solution status = " + cplex.getStatus());
         System.out.println("Relaxed solution value  = " + cplex.getObjValue());

         double[] vals = cplex.getValues(lp.getNumVars());
         cplex.use(new Solve(lp.getNumVars(), vals));

         cplex.delete(relax);

         cplex.setParam(IloCplex.Param.MIP.Strategy.Search,
                        IloCplex.MIPSearch.Traditional);
         if ( cplex.solve() ) {
            System.out.println("Solution status = " + cplex.getStatus());
            System.out.println("Solution value  = " + cplex.getObjValue());
         }
      }
      catch (IloException e) {
         System.err.println("Concert exception caught: " + e);
      }
   }
}

if you use OPL then you could have a look at Relax integrity constraints and dual value

int nbKids=300;
float costBus40=500;
float costBus30=400;
 
dvar int+ nbBus40;
dvar int+ nbBus30;
 
minimize
 costBus40*nbBus40  +nbBus30*costBus30;
 
subject to
{
 ctKids:40*nbBus40+nbBus30*30>=nbKids;
}
main {
  var status = 0;
  thisOplModel.generate();
  if (cplex.solve()) {
    writeln("Integer Model");   
    writeln("OBJECTIVE: ",cplex.getObjValue());   
    
  }
  // relax integrity constraint
  thisOplModel.convertAllIntVars();
 
  if (cplex.solve()) {
    writeln("Relaxed Model");   
    writeln("OBJECTIVE: ",cplex.getObjValue());  
    
    writeln("dual of the kids constraint = ",thisOplModel.ctKids.dual);
  }
   
 
}
Related