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; }
bool MIQPSolver::createModel() { try { model.add(IloMaximize(environment, g - h - p + s)); model.add(constraints); cplex = IloCplex(model); } catch (...) { return false; } return true; }
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 ); } }
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; }
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 ); } }
/** 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())); }
/** 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()); }
/** 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; } }