示例#1
0
int
main (int argc, char **argv)
{
   char const *vmconfig = NULL;

   // Check command line length (exactly two arguments are required).
   if ( argc != 3 ) {
      usage (argv[0]);
      return -1;
   }

   // Pick up VMC from command line.
   vmconfig = argv[1];

   // Solve the model.
   int exitcode = 0;
   IloEnv env;
   try {
      // Create and read the model.
      IloModel model(env);
      IloCplex cplex(model);

      IloObjective   obj;
      IloNumVarArray var(env);
      IloRangeArray  rng(env);
      IloSOS1Array   sos1(env);
      IloSOS2Array   sos2(env);
      IloRangeArray  lazy(env);
      IloRangeArray  cuts(env);

      cplex.importModel(model, argv[2], obj, var, rng, sos1, sos2,
                        lazy, cuts);

      cplex.extract(model);

      if ( lazy.getSize() > 0 )  cplex.addLazyConstraints (lazy);
      if ( cuts.getSize() > 0 )  cplex.addUserCuts (cuts);

      // Load the virtual machine configuration.
      // This will force solve() to use parallel distributed MIP.
      cplex.readVMConfig(vmconfig);

      // Install logging info callback.
      IloNum lastObjVal = (obj.getSense() == IloObjective::Minimize ) ?
         IloInfinity : -IloInfinity;
      cplex.use(loggingCallback(env, var, -100000, lastObjVal,
                                cplex.getCplexTime(), cplex.getDetTime()));
      // Turn off CPLEX logging
      cplex.setParam(IloCplex::Param::MIP::Display, 0);


      // Solve the problem and display some results.
      if ( cplex.solve() )
         env.out() << "Solution value  = " << cplex.getObjValue() << endl;
      else
         env.out() << "No solution" << endl;
      env.out() << "Solution status = " << cplex.getStatus() << endl;

      // Cleanup.
      cplex.end();
      model.end();
   }
   catch (IloException& e) {
      cerr << "Concert exception caught: " << e << endl;
      exitcode = -1;
   }
   catch (...) {
      cerr << "Unknown exception caught" << endl;
      exitcode = -1;
   }

   env.end();

   return exitcode;

}  // END main
示例#2
0
/** Create the dual of a linear program.
 * The function can only dualize programs of the form
 * <code>Ax <= b, x >= 0</code>. The data in <code>primalVars</code> and
 * <code>dualRows</code> as well as in <code>primalRows</code> and
 * <code>dualVars</code> is in 1-to-1-correspondence.
 * @param primalObj  Objective function of primal problem.
 * @param primalVars Variables in primal problem.
 * @param primalRows Rows in primal problem.
 * @param dualObj    Objective function of dual will be stored here.
 * @param dualVars   All dual variables will be stored here.
 * @param dualRows   All dual rows will be stored here.
 */
void BendersOpt::makeDual(IloObjective const &primalObj,
                          IloNumVarArray const &primalVars,
                          IloRangeArray const &primalRows,
                          IloObjective *dualObj,
                          IloNumVarArray *dualVars,
                          IloRangeArray *dualRows)
{
   // To keep the code simple we only support problems
   // of the form Ax <= b, b >= 0 here. We leave it as a reader's
   // exercise to extend the function to something that can handle
   // any kind of linear model.
   for (IloInt j = 0; j < primalVars.getSize(); ++j)
      if ( primalVars[j].getLB() != 0 ||
           primalVars[j].getUB() < IloInfinity )
      {
         std::stringstream s;
         s << "Cannot dualize variable " << primalVars[j];
         throw s.str();
      }
   for (IloInt i = 0; i < primalRows.getSize(); ++i)
      if ( primalRows[i].getLB() > -IloInfinity ||
           primalRows[i].getUB() >= IloInfinity )
      {
         std::stringstream s;
         s << "Cannot dualize constraint " << primalRows[i];
         std::cerr << s.str() << std::endl;
         throw s.str();
      }

   // The dual of
   //   min/max c^T x
   //       Ax <= b
   //        x >= 0
   // is
   //   max/min y^T b
   //       y^T A <= c
   //           y <= 0
   // We scale y by -1 to get >= 0

   IloEnv env = primalVars.getEnv();
   IloObjective obj(env, 0.0,
                    primalObj.getSense() == IloObjective::Minimize ?
                    IloObjective::Maximize : IloObjective::Minimize);
   IloRangeArray rows(env);
   IloNumVarArray y(env);
   std::map<IloNumVar,IloInt,ExtractableLess<IloNumVar> > v2i;
   for (IloInt j = 0; j < primalVars.getSize(); ++j) {
      IloNumVar x = primalVars[j];
      v2i.insert(std::map<IloNumVar,IloInt,ExtractableLess<IloNumVar> >::value_type(x, j));
      rows.add(IloRange(env, -IloInfinity, 0, x.getName()));
   }
   for (IloExpr::LinearIterator it = primalObj.getLinearIterator(); it.ok(); ++it)
      rows[v2i[it.getVar()]].setUB(it.getCoef());

   for (IloInt i = 0; i < primalRows.getSize(); ++i) {
      IloRange r = primalRows[i];
      IloNumColumn col(env);
      col += obj(-r.getUB());
      for (IloExpr::LinearIterator it = r.getLinearIterator(); it.ok(); ++it)
         col += rows[v2i[it.getVar()]](-it.getCoef());
      y.add(IloNumVar(col, 0, IloInfinity, IloNumVar::Float, r.getName()));
   }

   *dualObj = obj;
   *dualVars = y;
   *dualRows = rows;
}
示例#3
0
 /** Get the objective sense for this worker's objective. */
 IloObjective::Sense getObjectiveSense() const { return obj.getSense(); }
示例#4
0
int
main (int argc, char **argv)
{
   IloEnv env;
   try {
      IloModel model(env);
      IloCplex cplex(env);

      IloBool useLoggingCallback = IloFalse;
      IloBool useTimeLimitCallback = IloFalse;
      IloBool useAborter = IloFalse;


      if (( argc != 3 )                              ||
          ( strchr ("lat", argv[2][0]) == NULL )  ) {
         usage (argv[0]);
         throw(-1);
      }

      switch (argv[2][0]) {
         case 'l':
            useLoggingCallback = IloTrue;
            break;
         case 't':
            useTimeLimitCallback = IloTrue;
            break;
         case 'a':
            useAborter = IloTrue;
            break;
         default:
            break;
      }

      IloObjective   obj;
      IloNumVarArray var(env);
      IloRangeArray  rng(env);
      IloSOS1Array   sos1(env);
      IloSOS2Array   sos2(env);
      IloRangeArray  lazy(env);
      IloRangeArray  cuts(env);

      IloCplex::Aborter myAborter;

      cplex.importModel(model, argv[1], obj, var, rng, sos1, sos2,
                        lazy, cuts);

      cplex.extract(model);

      if ( lazy.getSize() > 0 )  cplex.addLazyConstraints (lazy);
      if ( cuts.getSize() > 0 )  cplex.addUserCuts (cuts);

      if ( useLoggingCallback ) {
         // Set an overall node limit in case callback conditions
         // are not met.
         cplex.setParam(IloCplex::Param::MIP::Limits::Nodes, 5000);

         IloNum lastObjVal = (obj.getSense() == IloObjective::Minimize ) ?
                                 IloInfinity : -IloInfinity;
         cplex.use(loggingCallback(env, var, -100000, lastObjVal,
                                   cplex.getCplexTime(), cplex.getDetTime()));
         // Turn off CPLEX logging
         cplex.setParam(IloCplex::Param::MIP::Display, 0);
      }
      else if ( useTimeLimitCallback ) {
         cplex.use(timeLimitCallback(env, cplex, IloFalse, cplex.getCplexTime(),
                                     1.0, 10.0));
      }
      else if ( useAborter ) {
         myAborter = IloCplex::Aborter(env); 
         cplex.use(myAborter);
         // Typically, you would pass the Aborter object to
         // another thread or pass it to an interrupt handler,
         // and  monitor for some event to occur.  When it does,
         // call the Aborter's abort method.
         //
         // To illustrate its use without creating a thread or
         // an interrupt handler, abort immediately by calling
         // abort before the solve.
         //  
         myAborter.abort();
      }


      cplex.solve();

      env.out() << endl;
      env.out() << "Solution status = " << cplex.getStatus() << endl;
      env.out() << "CPLEX status =    " << cplex.getCplexStatus() << endl;

   }
   catch (IloException& e) {
      cerr << "Concert exception caught: " << e << endl;
   }
   catch (...) {
      cerr << "Unknown exception caught" << endl;
   }

   env.end();
   return 0;
}  // END main
示例#5
0
   /** Create a new worker.
    * The constructor mainly does the following:
    * - create an IloCplex instance that refers to a remote worker,
    * - load the model in <code>modelfile</code>,
    * - setup parameters depending on this worker's index,
    * - start an asynchronous solve.
    * If anything fails then an exception will be thrown.
    * @param env The environment used for instantiating Ilo* objects.
    * @param i The index of the worker to be created. This also
    *          determines the parameter settings to use in this worker.
    * @param s  A pointer to the global solve state.
    * @param transport  The transport name for the IloCplex constructor.
    * @param argc       The argument count for the IloCplex constructor.
    * @param argv       The array of transport arguments for the IloCplex
    *                   constructor.
    * @param modelfile  Name of the model to be loaded into the worker.
    * @param output     The output mode.
    * @param objdiff    The minimal difference between so that two
    *                   consecutive objective function values are considered
    *                   different.
    */
   Worker(IloEnv env, int i, SolveState *s, char const *transport,
          int argc, char const **argv, char const *modelfile,
          OUTPUT output, double objdiff)
      : idx(i), state(s), model(env), cplex(0), handle(0),
        primal(IloInfinity), dual(-IloInfinity),
        obj(env), x(env), rng(env), infoHandler(this), outb(idx), outs(&outb)
   {
      try {
         // Create remote object, setup output and load the model.
         cplex = IloCplex(model, transport, argc, argv);
         switch (output) {
         case OUTPUT_SILENT:
            // Disable output on the output and warning stream.
            cplex.setOut(env.getNullStream());
            cplex.setWarning(env.getNullStream());
            break;
         case OUTPUT_PREFIXED:
            // Redirect output to our custom stream.
            cplex.setOut(outs);
            cplex.setWarning(outs);
            break;
         case OUTPUT_LOG:
            // Nothing to do here. By default output is enabled.
            break;
         }
         cplex.importModel(model, modelfile, obj, x, rng);
         if ( obj.getSense() == IloObjective::Minimize ) {
            primal = -IloInfinity;
            dual = IloInfinity;
         }

         // We set the thread count for each solver to 1 so that we do not
         // run into problems if multiple solves are performed on the same
         // machine.
         cplex.setParam(IloCplex::Param::Threads, 1);
         // Each worker runs with a different random seed. This way we
         // get different paths through the tree even if the other
         // parameter settings are the same.
         cplex.setParam(IloCplex::Param::RandomSeed, idx);
         // Apply parameter settings.
         for (class ParamValue const *vals = settings[idx % NUMSETTINGS].values;
              vals->isValid(); ++vals)
            vals->apply(cplex);

         // Install callback and set objective change.
         int status = cplex.userfunction (USERACTION_ADDCALLBACK,
                                          0, NULL, 0, 0, NULL);
         if ( status )
            throw status;
         IloCplex::Serializer s;
         s.add(objdiff);
         status = cplex.userfunction (USERACTION_CHANGEOBJDIFF,
                                      s.getRawLength(), s.getRawData(),
                                      0, 0, NULL);
         if ( status )
            throw status;

         // Register the handler that will process info messages sent
         // from the worker.
         cplex.setRemoteInfoHandler(&infoHandler);

         // Everything is setup. Launch the asynchronous solve.
         handle = cplex.solve(true);
      } catch (...) {
         // In case of an exception we need to take some special
         // cleanup actions. Note that if we get here then the
         // solve cannot have been started and we don't need to
         // kill or join the asynchronous solve.
         if ( cplex.getImpl() )
            cplex.end();
         rng.end();
         x.end();
         obj.end();
         model.end();
         throw;
      }
   }