Reading a Problem from a File: Example ilolpex2.cpp

This example shows how to read an optimization problem from a file, and solve it with a specified optimizer option. It prints solution information, including a Simplex basis, if available. Finally it prints the maximum infeasibility of any variable of the solution.

The file to read and the optimizer choice are passed to the program via command line parameters. For example, this command:

  ilolpex2 example.mps d

reads the file example.mps and solves the problem with the dual simplex optimizer.

Example ilolpex2 demonstrates:

The general structure of this example is the same as for example ilolpex1.cpp. It starts by creating the environment and terminates with destroying it by calling the end() method. The code in between is enclosed in try/catch statements for error handling.

Reading the Model from a File

The model is created by reading it from the file specified as the first command line argument argv[1]. This is done using the method importModel() of an IloCplex object. Here the IloCplex object is used as a model reader rather than an optimizer. Calling importModel() does not extract the model to the invoking cplex object. This must be done later by calling cplex.extract(model). We pass objects obj, var, and rng to importModel() to be able to access the variables later on when querying results.

Selecting the Optimizer

The selection of the optimizer option is done in the switch statement controlled by the second command line parameter. A call to setParam(IloCplex::RootAlg, alg) selects the desired IloCplex::Algorithm option.

Accessing Basis Information

After solving the model by calling method solve(), the results are accessed in the same way as in ilolpex1.cpp, with the exception of basis information for the variables. It is important to understand that not all optimizer options compute basis information, and thus it cannot be queried in all cases. In particular, basis information is not available when the model is solved using the barrier optimizer (IloCplex::Barrier) without crossover (parameter IloCplex::BarCrossAlg set to IloCplex::NoAlg).

Querying Quality Measures

Finally, the program prints the maximum primal infeasibility or bound violation of the solution. To cope with the finite precision of the numerical computations done on the computer, IloCplex allows some tolerances by which (for instance) optimality conditions may be violated. A long list of other quality measures is available.

Complete Program

The complete program follows. You can also view it online in the file ilolpex2.cpp.

  // -------------------------------------------------------------- -*- C++ -*-
  // File: examples/src/ilolpex2.cpp
  // Version 8.1
  // --------------------------------------------------------------------------
  //  Copyright (C) 1999-2002 by ILOG.
  //  All Rights Reserved.
  //  Permission is expressly granted to use this example in the
  //  course of developing applications that use ILOG products.
  // --------------------------------------------------------------------------
  //
  // ilolpex2.cpp - Reading in and optimizing a problem
  //
  // To run this example, command line arguments are required.
  // i.e.,   ilolpex2   filename   method
  // where
  //     filename is the name of the file, with .mps, .lp, or .sav extension
  //     method   is the optimization method
  //                 o          default
  //                 p          primal simplex
  //                 d          dual   simplex
  //                 h          barrier with crossover
  //                 b          barrier without crossover
  //                 n          network with dual simplex cleanup
  //                 s          sifting
  //                 c          concurrent
  // Example:
  //     ilolpex2  example.mps  o
  //
  
  #include <ilcplex/ilocplex.h>
  ILOSTLBEGIN
  
  static void usage (const char *progname);
  
  int
  main (int argc, char **argv)
  {
     IloEnv env;
     try {
        IloModel model(env);
        IloCplex cplex(env);
  
        if (( argc != 3 )                              ||
            ( strchr ("podhbnsc", argv[2][0]) == NULL )  ) {
           usage (argv[0]);
           throw(-1);
        }
  
        switch (argv[2][0]) {
           case 'o':
              cplex.setParam(IloCplex::RootAlg, IloCplex::AutoAlg);
              break;
           case 'p':
              cplex.setParam(IloCplex::RootAlg, IloCplex::Primal);
              break;
           case 'd':
              cplex.setParam(IloCplex::RootAlg, IloCplex::Dual);
              break;
           case 'b':
              cplex.setParam(IloCplex::RootAlg, IloCplex::Barrier);
              cplex.setParam(IloCplex::BarCrossAlg, IloCplex::NoAlg);
              break;
           case 'h':
              cplex.setParam(IloCplex::RootAlg, IloCplex::Barrier);
              break;
           case 'n':
              cplex.setParam(IloCplex::RootAlg, IloCplex::Network);
              break;
           case 's':
              cplex.setParam(IloCplex::RootAlg, IloCplex::Sifting);
              break;
           case 'c':
              cplex.setParam(IloCplex::RootAlg, IloCplex::Concurrent);
              break;
           default:
              break;
        }
  
        IloObjective   obj;
        IloNumVarArray var(env);
        IloRangeArray  rng(env);
        cplex.importModel(model, argv[1], obj, var, rng);
  
        cplex.extract(model);
        if ( !cplex.solve() ) {
           env.error() << "Failed to optimize LP" << endl;
           throw(-1);
        }
  
        IloNumArray vals(env);
        cplex.getValues(vals, var);
        env.out() << "Solution status = " << cplex.getStatus() << endl;
        env.out() << "Solution value  = " << cplex.getObjValue() << endl;
        env.out() << "Solution vector = " << vals << endl;
  
        try {     // basis may not exist
           IloCplex::BasisStatusArray cstat(env);
           cplex.getBasisStatuses(cstat, var);
           env.out() << "Basis statuses  = " << cstat << endl;
        } catch (...) {
        }
  
        env.out() << "Maximum bound violation = "
                  << cplex.getQuality(IloCplex::MaxPrimalInfeas) << endl;
     }
     catch (IloException& e) {
        cerr << "Concert exception caught: " << e << endl;
     }
     catch (...) {
        cerr << "Unknown exception caught" << endl;
     }
  
     env.end();
     return 0;
  }  // END main
  
  
  static void usage (const char *progname)
  {
     cerr << "Usage: " << progname << " filename algorithm" << endl;
     cerr << "   where filename is a file with extension " << endl;
     cerr << "      MPS, SAV, or LP (lower case is allowed)" << endl;
     cerr << "   and algorithm is one of the letters" << endl;
     cerr << "      o          default" << endl;
     cerr << "      p          primal simplex" << endl;
     cerr << "      d          dual simplex  " << endl;
     cerr << "      b          barrier       " << endl;
     cerr << "      h          barrier with crossover" << endl;
     cerr << "      n          network simplex" << endl;
     cerr << "      s          sifting" << endl;
     cerr << "      c          concurrent" << endl;
     cerr << " Exiting..." << endl;
  } // END usage
  
  


Previous Page: Selecting an Optimizer  Return to Top Next Page: Modifying and Reoptimizing