Exemplo n.º 1
0
void CplexTSPSolver::initial()
{
    // zu kleine Systeme (bspw. N=0) bringen den solver zum Absturz
    if(N <= 3)
    {
        printf(ERROR "%d cities do not make sense! aborting...\n", N);
        return;
        //~ return -3;
    }

    // create the CPLEX objects
    model = IloModel(env);
    cplex = IloCplex(model);

    // how verbose are we?
    if(v<4)
        cplex.setOut(env.getNullStream());
    if(v==0)
        cplex.setWarning(env.getNullStream());

    x = init_symmetric_var(model);
    add_symmetric_inout_constraints(model, x);

    cplex.setParam(IloCplex::HeurFreq, -1);

    //~ cplex.setParam(IloCplex::RootAlg, IloCplex::Barrier);
    cplex.setParam(IloCplex::Threads, 1);
    cplex.setParam(IloCplex::NodeFileInd, 3);
    // maximal 900MB Tree Size
    cplex.setParam(IloCplex::TreLim, 900);

    cplex.solve();

}
CPLEX_LP_MSTSolverIF::CPLEX_LP_MSTSolverIF(GraphIF * graph,
		IloNumVar::Type edgeVariablesType) :
		MSTSolverIF(graph), numberOfVertices { graph->getNumberOfVertices(
				Visibility::VISIBLE) }, numberOfEdges { graph->getNumberOfEdges(
				Visibility::VISIBLE) } {

	model = IloModel(env);
	cplex = IloCplex(model);

	TRACE(logger, LogBundleKey::CPLPMSTIF_INIT,
			LogStringUtils::graphDescription(graph, "\t").c_str());

	solution = nullptr;
}
Exemplo n.º 3
0
bool MIQPSolver::createModel()
{
	try
	{
		model.add(IloMaximize(environment, g - h - p + s));
		model.add(constraints);
		cplex = IloCplex(model);
	}
	catch (...)
	{
		return false;
	}
	return true;
}
Exemplo n.º 4
0
void kMST_ILP::solve()
{
	try {
		// initialize CPLEX
		env = IloEnv();
		model = IloModel( env );

		Variables *vars;

		// add model-specific constraints
		if( model_type == "scf" ) vars = modelSCF();
		else if( model_type == "mcf" ) vars = modelMCF();
		else if( model_type == "mtz" ) vars = modelMTZ();
		else {
			cerr << "No existing model chosen\n";
			exit( -1 );
		}

		// build model
		cplex = IloCplex( model );
		// export model to a text file
		//cplex.exportModel( "model.lp" );
		// set parameters
		setCPLEXParameters();

		// solve model
		cout << "Calling CPLEX solve ...\n";
		cplex.solve();
		cout << "CPLEX finished.\n\n";
		cout << "CPLEX status: " << cplex.getStatus() << "\n";
		cout << "Branch-and-Bound nodes: " << cplex.getNnodes() << "\n";
		cout << "Objective value: " << cplex.getObjValue() << "\n";
		cout << "CPU time: " << Tools::CPUtime() << "\n\n";

		// vars->print(cplex);

		delete vars;
	}
	catch( IloException& e ) {
		cerr << "kMST_ILP: exception " << e << "\n";
		exit( -1 );
	}
	catch( ... ) {
		cerr << "kMST_ILP: unknown exception.\n";
		exit( -1 );
	}
}
Exemplo n.º 5
0
bool cplex_solver::solve(int timeout)
{
	std::cout << "Solving with CPLEX" << std::endl;
	try {

		cplex=IloCplex(model);

		int ret= cplex.solve();
		if(!ret) {
			std::cerr << "error unkown, return code:  "<< ret << std::endl;
			std::cerr.flush();
			return false;
		}
	} catch (IloException& ex) {
		std::cerr << "Error: " << ex << std::endl;
		std::cerr.flush();
		return false;
	} catch (...) {
		std::cerr << "error unkown" << std::endl;
		std::cerr.flush();
		return false;
	}
	return true;
}
Exemplo n.º 6
0
void kMST_ILP::solve()
{
	try {
		// initialize CPLEX
		env = IloEnv();
		model = IloModel( env );

		addTreeConstraints(); // call first, initialises edges

		// add model-specific constraints
		if( model_type == "scf" ) modelSCF();
		else if( model_type == "mcf" ) modelMCF();
		else if( model_type == "mtz" ) modelMTZ();
		else {
			cerr << "No existing model chosen\n";
			exit( -1 );
		}

		addObjectiveFunction();

		// build model
		cplex = IloCplex( model );
		// export model to a text file
		//cplex.exportModel( "model.lp" );
		// set parameters
		setCPLEXParameters();

		// solve model
		cout << "Calling CPLEX solve ...\n";
		cplex.solve();
		cout << "CPLEX finished.\n\n";
		cout << "CPLEX status: " << cplex.getStatus() << "\n";
		cout << "Branch-and-Bound nodes: " << cplex.getNnodes() << "\n";
		cout << "Objective value: " << cplex.getObjValue() << "\n";
		cout << "CPU time: " << Tools::CPUtime() << "\n\n";

		// show result
		IloNumArray edgesSelected(env, edges.getSize()), flowRes(env, edges.getSize()), uRes(env, instance.n_nodes);
		cplex.getValues(edgesSelected, edges);

		if (model_type == "scf") {
			cplex.getValues(flowRes, flow_scf);
		} else if (model_type == "mtz") {
			try {
				cplex.getValues(uRes, u);
			} catch ( IloException& e ) {
				cerr << "Exception while extracting u: " << e << endl;
				uRes = IloNumArray(env, 0);
			}
		}
		cout << "Edges:\n";

		for (unsigned int i=0; i<edges.getSize(); i++) {

			// skip unused ones
			if (((int)edgesSelected[i])  == 0 ) {
				continue;
			}

			if (i == instance.n_edges) {
				cout << endl;
			}
			bool direction = ( i >= instance.n_edges);
			cout << "  " << setw(4) <<  i << ": " << ((int)edgesSelected[i]) << " ";

			// flow
			if (model_type == "scf") {
				cout << "f: " << setw(2) << (flowRes[i]);
			} else if (model_type == "mtz") {
				if (uRes.getSize() != 0) {
					cout << "u: " ;
					if (i < instance.n_edges) {
						//cout << setw(2) << instance.edges[i % instance.n_edges].v1 << ": ";
						cout << setw(2) <<((int)uRes[ instance.edges[i % instance.n_edges].v1]) << " ";
						//cout << setw(2) << instance.edges[i % instance.n_edges].v2 << ": ";
						cout << setw(2) << ((int)uRes[ instance.edges[i % instance.n_edges].v2]) ;
					}  else {
						//cout << setw(2) << instance.edges[i % instance.n_edges].v2 << ": ";
						cout << setw(2) <<((int)uRes[ instance.edges[i % instance.n_edges].v2]) << " ";
						//cout << setw(2) << instance.edges[i % instance.n_edges].v1 << ": ";
						cout << setw(2) <<((int)uRes[ instance.edges[i % instance.n_edges].v1]) ;
					}
				}

			}

			cout << " " << Tools::edgeToString(instance.edges[i % instance.n_edges], direction) ;

			cout << endl;
		}

	} catch (IloAlgorithm::CannotExtractException& e) {
		cerr << "CannotExtractException: " << e << endl ;
		IloExtractableArray failed = e.getExtractables();
		for (IloInt i = 0; i < failed.getSize(); ++i) {
			cerr << "\t" << failed[i] << std::endl;
		}
	} catch( IloException& e ) {
		cerr << "kMST_ILP: exception " << e << "\n";
		exit( -1 );
	}
	catch( ... ) {
		cerr << "kMST_ILP: unknown exception.\n";
		exit( -1 );
	}
}
Exemplo n.º 7
0
/** Extract the master block from <code>problem</code>.
 * The constructor also sets up the solver for the newly created master
 * block. The master block can only be extracted if all sub-blocks have
 * already been extracted.
 * @param problem The problem from which to extract the master.
 * @param blocks  The sub blocks that have already been extracted.
 */
BendersOpt::Block::Block(Problem const *problem, BlockVector const &blocks)
   : env(), number(-1), vars(0), rows(0), cplex(0), cb(0)
{
   IloNumVarArray problemVars = problem->getVariables();
   IloRangeArray problemRanges = problem->getRows();

   IloExpr masterObj(env);
   IloNumVarArray masterVars(env);
   IloRangeArray masterRows(env);

   // Find columns that do not intersect block variables and
   // copy them to the master block.
   IdxMap idxMap;
   RowSet rowSet;
   for (IloInt j = 0; j < problemVars.getSize(); ++j) {
      IloNumVar x = problemVars[j];
      if ( problem->getBlock(x) < 0 ) {
         // Column is not in a block. Copy it to the master.
         IloNumVar v(env, x.getLB(), x.getUB(), x.getType(), x.getName());
         varMap.insert(VarMap::value_type(v, x));
         masterObj += problem->getObjCoef(x) * v;

         idxMap[x] = masterVars.getSize();
         masterVars.add(v);
      }
      else {
         // Column is in a block. Collect all rows that intersect
         // this column.
         RowSet const &intersected = problem->getIntersectedRows(x);
         for (RowSet::const_iterator it = intersected.begin();
              it != intersected.end(); ++it)
            rowSet.insert(*it);
         idxMap[x] = -1;
      }
   }

   // Pick up the rows that we need to copy.
   // These are the rows that are only intersected by master variables,
   // that is, the rows that are not in any block's rowset.
   for (IloInt i = 0; i < problemRanges.getSize(); ++i) {
      IloRange r = problemRanges[i];
      if ( rowSet.find(r) == rowSet.end() ) {
         IloRange masterRow(env, r.getLB(), r.getUB(), r.getName());
         IloExpr lhs(env);
         for (IloExpr::LinearIterator it = r.getLinearIterator(); it.ok(); ++it)
         {
            lhs += it.getCoef() * masterVars[idxMap[it.getVar()]];
         }
         masterRow.setExpr(lhs);
         masterRows.add(masterRow);
      }
   }

   // Adjust variable indices in blocks so that reference to variables
   // in the original problem become references to variables in the master.
   for (BlockVector::const_iterator b = blocks.begin(); b != blocks.end(); ++b) {
      for (std::vector<FixData>::iterator it = (*b)->fixed.begin(); it != (*b)->fixed.end(); ++it)
         it->col = idxMap[problemVars[it->col]];
   }

   // Create the eta variables, one for each block.
   // See the comments at the top of this file for details about the
   // eta variables.
   IloInt const firsteta = masterVars.getSize();
   for (BlockVector::size_type i = 0; i < blocks.size(); ++i) {
      std::stringstream s;
      s << "_eta" << i;
      IloNumVar eta(env, 0.0, IloInfinity, s.str().c_str());
      masterObj += eta;
      masterVars.add(eta);
   }

   // Create model and solver instance
   vars = masterVars;
   rows = masterRows;
   IloModel model(env);
   model.add(obj = IloObjective(env, masterObj, problem->getObjSense()));
   model.add(vars);
   model.add(rows);
   cplex = IloCplex(model);

   cplex.use(cb = new (env) LazyConstraintCallback(env, this, blocks,
                                              firsteta));

   for (IloExpr::LinearIterator it = obj.getLinearIterator(); it.ok(); ++it)
      objMap.insert(ObjMap::value_type(it.getVar(), it.getCoef()));
}
Exemplo n.º 8
0
/** Extract sub block number <code>n</code> from <code>problem</code>.
 * The constructor creates a representation of block number <code>n</code>
 * as described in <code>problem</code>.
 * The constructor will also connect the newly created block to a remote
 * object solver instance.
 * @param problem  The problem from which the block is to be extracted.
 * @param n        Index of the block to be extracted.
 * @param argc     Argument for IloCplex constructor.
 * @param argv     Argument for IloCplex constructor.
 * @param machines List of machines to which to connect. If the code is
 *                 compiled for the TCP/IP transport then the block will
 *                 be connected to <code>machines[n]</code>.
 */
BendersOpt::Block::Block(Problem const *problem, IloInt n, int argc, char const *const *argv,
                         std::vector<char const *> const &machines)
   : env(), number(n), vars(0), rows(0), cplex(0), cb(0)
{
   IloNumVarArray problemVars = problem->getVariables();
   IloRangeArray problemRanges = problem->getRows();

   // Create a map that maps variables in the original model to their
   // respective index in problemVars.
   std::map<IloNumVar,IloInt,ExtractableLess<IloNumVar> > origIdxMap;
   for (IloInt j = 0; j < problemVars.getSize(); ++j)
      origIdxMap.insert(std::map<IloNumVar,IloInt,ExtractableLess<IloNumVar> >::value_type(problemVars[j], j));

   // Copy non-fixed variables from original problem into primal problem.
   IloExpr primalObj(env);
   IloNumVarArray primalVars(env);
   IloRangeArray primalRows(env);
   IdxMap idxMap; // Index of original variable in block's primal model
   RowSet rowSet;
   for (IloInt j = 0; j < problemVars.getSize(); ++j) {
      IloNumVar x = problemVars[j];
      if ( problem->getBlock(x) == number ) {
         // Create column in block LP with exactly the same data.
         if ( x.getType() != IloNumVar::Float ) {
            std::stringstream s;
            s << "Cannot create non-continuous block variable " << x;
            std::cerr << s.str() << std::endl;
            throw s.str();
         }
         IloNumVar v(env, x.getLB(), x.getUB(), x.getType(), x.getName());
         // Normalize objective function to 'minimize'
         double coef = problem->getObjCoef(x);
         if ( problem->getObjSense() != IloObjective::Minimize )
            coef *= -1.0;
         primalObj += coef * v;
            
         // Record the index that the copied variable has in the
         // block model.
         idxMap.insert(IdxMap::value_type(x, primalVars.getSize()));
         primalVars.add(v);
            
         // Mark the rows that are intersected by this column
         // so that we can collect them later.
         RowSet const &intersected = problem->getIntersectedRows(x);
         for (RowSet::const_iterator it = intersected.begin();
              it != intersected.end(); ++it)
            rowSet.insert(*it);
      }
      else
         idxMap.insert(IdxMap::value_type(x, -1));
   }

   // Now copy all rows that intersect block variables.
   for (IloInt i = 0; i < problemRanges.getSize(); ++i) {
      IloRange r = problemRanges[i];
      if ( rowSet.find(r) == rowSet.end() )
         continue;

      // Create a copy of the row, normalizing it to '<='
      double factor = 1.0;
      if ( r.getLB() > -IloInfinity )
         factor = -1.0;
      IloRange primalR(env,
                       factor < 0 ? -r.getUB() : r.getLB(),
                       factor < 0 ? -r.getLB() : r.getUB(), r.getName());
      IloExpr lhs(env);
      for (IloExpr::LinearIterator it = r.getLinearIterator(); it.ok(); ++it)
      {
         IloNumVar v = it.getVar();
         double const val = factor * it.getCoef();
         if ( problem->getBlock(v) != number ) {
            // This column is not explicitly in this block. This means
            // that it is a column that will be fixed by the master.
            // We collect all such columns so that we can adjust the
            // dual objective function according to concrete fixings.
            // Store information about variables in this block that
            // will be fixed by master solves.
            fixed.push_back(FixData(primalRows.getSize(), origIdxMap[v], -val));
         }
         else {
            // The column is an ordinary in this block. Just copy it.
            lhs += primalVars[idxMap[v]] * val;
         }
      }
      primalR.setExpr(lhs);
      primalRows.add(primalR);
      lhs.end();
   }

   // Create the dual of the primal model we just created.
   // Note that makeDual _always_ returns a 'maximize' objective.
   IloObjective objective(env, primalObj, IloObjective::Minimize);
      
   makeDual(objective, primalVars, primalRows,
            &obj, &vars, &rows);
   objective.end();
   primalRows.endElements();
   primalRows.end();
   primalVars.endElements();
   primalVars.end();
   primalObj.end();
   // Create a model.
   IloModel model(env);
   model.add(obj);
   model.add(vars);
   model.add(rows);
   for (IloExpr::LinearIterator it = obj.getLinearIterator(); it.ok(); ++it)
      objMap.insert(ObjMap::value_type(it.getVar(), it.getCoef()));

   // Finally create the IloCplex instance that will solve
   // the problems associated with this block.
   char const **transargv = new char const *[argc + 3];
   for (int i = 0; i < argc; ++i)
      transargv[i] = argv[i];
#if defined(USE_MPI)
   char extra[128];
   sprintf (extra, "-remoterank=%d", static_cast<int>(number + 1));
   transargv[argc++] = extra;
   (void)machines;
#elif defined(USE_PROCESS)
   char extra[128];
   sprintf (extra, "-logfile=block%04d.log", static_cast<int>(number));
   transargv[argc++] = extra;
   (void)machines;
#elif defined(USE_TCPIP)
   transargv[argc++] = machines[number];
#endif
   cplex = IloCplex(model, TRANSPORT, argc, transargv);
   delete[] transargv;

   // Suppress output from this block's solver.
   cplex.setOut(env.getNullStream());
   cplex.setWarning(env.getNullStream());
}
Exemplo n.º 9
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;
      }
   }