예제 #1
0
int setCplexParam(IloCplex& cplex, IloEnv& env, int time_limit){
  //Set cplex parameter
  cplex.setParam(IloCplex::TiLim, time_limit);
  cplex.setParam(IloCplex::Threads, 2);
  cplex.setOut(env.getNullStream());
  cplex.setParam(IloCplex::PreLinear, 0);

  return 0;
}
예제 #2
0
// This routine set up the IloCplex algorithm to solve the worker LP, and
// creates the worker LP (i.e., the dual of flow constraints and
// capacity constraints of the flow MILP)
//
// Modeling variables:
// forall k in V0, i in V:
//    u(k,i) = dual variable associated with flow constraint (k,i)
//
// forall k in V0, forall (i,j) in A:
//    v(k,i,j) = dual variable associated with capacity constraint (k,i,j)
//
// Objective:
// minimize sum(k in V0) sum((i,j) in A) x(i,j) * v(k,i,j)
//          - sum(k in V0) u(k,0) + sum(k in V0) u(k,k)
//
// Constraints:
// forall k in V0, forall (i,j) in A: u(k,i) - u(k,j) <= v(k,i,j)
//
// Nonnegativity on variables v(k,i,j)
// forall k in V0, forall (i,j) in A: v(k,i,j) >= 0
//
void
createWorkerLP(IloCplex cplex, IloNumVarArray v, IloNumVarArray u, 
               IloObjective obj, IloInt numNodes)
{

   IloInt i, j, k;
   IloEnv env = cplex.getEnv();
   IloModel mod(env, "atsp_worker"); 

   // Set up IloCplex algorithm to solve the worker LP

   cplex.extract(mod);
   cplex.setOut(env.getNullStream());
      
   // Turn off the presolve reductions and set the CPLEX optimizer
   // to solve the worker LP with primal simplex method.

   cplex.setParam(IloCplex::Reduce, 0);
   cplex.setParam(IloCplex::RootAlg, IloCplex::Primal); 
   
   // Create variables v(k,i,j) forall k in V0, (i,j) in A
   // For simplicity, also dummy variables v(k,i,i) are created.
   // Those variables are fixed to 0 and do not partecipate to 
   // the constraints.

   IloInt numArcs  = numNodes * numNodes;
   IloInt vNumVars = (numNodes-1) * numArcs;
   IloNumVarArray vTemp(env, vNumVars, 0, IloInfinity);
   for (k = 1; k < numNodes; ++k) {
      for (i = 0; i < numNodes; ++i) {
         vTemp[(k-1)*numArcs + i *numNodes + i].setBounds(0, 0);
      }
   }
   v.clear();
   v.add(vTemp);
   vTemp.end();
   mod.add(v);

   // Set names for variables v(k,i,j) 

   for (k = 1; k < numNodes; ++k) {
      for(i = 0; i < numNodes; ++i) {
         for(j = 0; j < numNodes; ++j) {
            char varName[100];
            sprintf(varName, "v.%d.%d.%d", (int) k, (int) i, (int) j); 
            v[(k-1)*numArcs + i*numNodes + j].setName(varName);
         }
      }
   }
   
   // Associate indices to variables v(k,i,j)

   IloIntArray vIndex(env, vNumVars);
   for (j = 0; j < vNumVars; ++j)
   {
      vIndex[j] = j;
      v[j].setObject(&vIndex[j]);
   }

   // Create variables u(k,i) forall k in V0, i in V

   IloInt uNumVars = (numNodes-1) * numNodes;
   IloNumVarArray uTemp(env, uNumVars, -IloInfinity, IloInfinity);
   u.clear();
   u.add(uTemp);
   uTemp.end();
   mod.add(u);

   // Set names for variables u(k,i) 

   for (k = 1; k < numNodes; ++k) {
      for(i = 0; i < numNodes; ++i) {
         char varName[100];
         sprintf(varName, "u.%d.%d", (int) k, (int) i); 
         u[(k-1)*numNodes + i].setName(varName);
      }
   }

   // Associate indices to variables u(k,i)

   IloIntArray uIndex(env, uNumVars);
   for (j = 0; j < uNumVars; ++j)
   {
      uIndex[j] = vNumVars + j;
      u[j].setObject(&uIndex[j]);
   }

   // Initial objective function is empty

   obj.setSense(IloObjective::Minimize);
   mod.add(obj);

   // Add constraints:
   // forall k in V0, forall (i,j) in A: u(k,i) - u(k,j) <= v(k,i,j)

   for (k = 1; k < numNodes; ++k) {
      for(i = 0; i < numNodes; ++i) {
         for(j = 0; j < numNodes; ++j) {
            if ( i != j ) {
               IloExpr expr(env);
               expr -= v[(k-1)*numArcs + i*(numNodes) + j];
               expr += u[(k-1)*numNodes + i];
               expr -= u[(k-1)*numNodes + j];
               mod.add(expr <= 0);
               expr.end();
            }
         }
      }
   }

}// END createWorkerLP
예제 #3
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;
      }
   }