00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #include "BonSubMipSolver.hpp"
00013 #include "BonminConfig.h"
00014 #include "CbcModel.hpp"
00015 #include "CbcStrategy.hpp"
00016 #include "OsiAuxInfo.hpp"
00017 #include "OsiClpSolverInterface.hpp"
00018
00019 #include <climits>
00020 #ifdef COIN_HAS_CPX
00021 #include "OsiCpxSolverInterface.hpp"
00022 #include "cplex.h"
00023 void throw_error(const std::string &s, const std::string &f, const std::string &func){
00024 throw CoinError(s,f,func);
00025 }
00026 #define CHECK_CPX_STAT(a,b) if(b) throw_error("Error in CPLEX call",__FILE__,a);
00027
00028 #endif
00029
00030 #include "BonRegisteredOptions.hpp"
00031 #include "BonBabSetupBase.hpp"
00032 #include "BonCbcLpStrategy.hpp"
00033
00034
00035 namespace Bonmin {
00037 SubMipSolver::SubMipSolver(BabSetupBase &b, const std::string &prefix):
00038 clp_(NULL),
00039 cpx_(NULL),
00040 lowBound_(-DBL_MAX),
00041 optimal_(false),
00042 integerSolution_(NULL),
00043 strategy_(NULL),
00044 ownClp_(false)
00045 {
00046
00047 int logLevel;
00048 b.options()->GetIntegerValue("milp_log_level", logLevel, prefix);
00049
00050 int ivalue;
00051 b.options()->GetEnumValue("milp_solver",ivalue,prefix);
00052 if (ivalue <= 0) {
00053 strategy_ = new CbcStrategyDefault;
00054 clp_ = new OsiClpSolverInterface;
00055 ownClp_ = true;
00056 clp_->messageHandler()->setLogLevel(logLevel);
00057 }
00058 else if (ivalue == 1) {
00059 CbcStrategyChooseCuts strategy(b, prefix);
00060 strategy_ = new CbcStrategyChooseCuts(b, prefix);
00061 clp_ = new OsiClpSolverInterface;
00062 ownClp_ = true;
00063 clp_->messageHandler()->setLogLevel(logLevel);
00064 }
00065 else if (ivalue == 2) {
00066 #ifdef COIN_HAS_CPX
00067 OsiCpxSolverInterface * cpxSolver = new OsiCpxSolverInterface;
00068 #if 1
00069
00070 b.options()->GetIntegerValue("number_cpx_threads",ivalue,prefix);
00071 CPXsetintparam(cpxSolver->getEnvironmentPtr(), CPX_PARAM_THREADS, ivalue);
00072 b.options()->GetIntegerValue("cpx_parallel_strategy",ivalue,prefix);
00073 CPXsetintparam(cpxSolver->getEnvironmentPtr(), CPX_PARAM_PARALLELMODE, ivalue);
00074 #endif
00075 cpx_ = cpxSolver;
00076 cpx_->messageHandler()->setLogLevel(logLevel);
00077 #else
00078 std::cerr << "You have set an option to use CPLEX as the milp\n"
00079 << "subsolver in oa decomposition. However, apparently\n"
00080 << "CPLEX is not configured to be used in bonmin.\n"
00081 << "See the manual for configuring CPLEX\n";
00082 throw -1;
00083 #endif
00084 }
00085
00086 b.options()->GetEnumValue("milp_strategy",ivalue,prefix);
00087 if(ivalue == 0){
00088 milp_strat_ = FindGoodSolution;
00089 }
00090 else {
00091 milp_strat_ = GetOptimum;
00092 }
00093
00094 b.options()->GetNumericValue("allowable_fraction_gap", gap_tol_, prefix);
00095
00096
00097 }
00098 SubMipSolver::SubMipSolver(const SubMipSolver ©):
00099 clp_(NULL),
00100 cpx_(NULL),
00101 lowBound_(-DBL_MAX),
00102 optimal_(false),
00103 integerSolution_(NULL),
00104 strategy_(NULL),
00105 milp_strat_(copy.milp_strat_),
00106 gap_tol_(copy.gap_tol_),
00107 ownClp_(copy.ownClp_)
00108 {
00109 #ifdef COIN_HAS_CPX
00110 if(copy.cpx_ != NULL){
00111 cpx_ = new OsiCpxSolverInterface(*copy.cpx_);
00112 int ival;
00113 CPXgetintparam(copy.cpx_->getEnvironmentPtr(), CPX_PARAM_THREADS, &ival);
00114 CPXsetintparam(cpx_->getEnvironmentPtr(), CPX_PARAM_THREADS, ival);
00115 CPXgetintparam(copy.cpx_->getEnvironmentPtr(), CPX_PARAM_PARALLELMODE, &ival);
00116 CPXsetintparam(cpx_->getEnvironmentPtr(), CPX_PARAM_PARALLELMODE, ival);
00117 }
00118 #endif
00119 if(copy.clp_ != NULL){
00120 if(ownClp_) clp_ = new OsiClpSolverInterface(*copy.clp_);
00121 else clp_ = copy.clp_;
00122 }
00123 if(copy.strategy_){
00124 strategy_ = dynamic_cast<CbcStrategyDefault *>(copy.strategy_->clone());
00125 assert(strategy_);
00126 }
00127 }
00128 SubMipSolver::~SubMipSolver()
00129 {
00130 if (strategy_) delete strategy_;
00131 if (integerSolution_) delete [] integerSolution_;
00132 #ifdef COIN_HAS_CPX
00133 if(cpx_) delete cpx_;
00134 #endif
00135 if(ownClp_) delete clp_;
00136 }
00137
00139 void
00140 SubMipSolver::setLpSolver(OsiSolverInterface * lp)
00141 {
00142 #ifdef COIN_HAS_CPX
00143 if(cpx_){
00144 clp_ = NULL;
00145 cpx_->loadProblem(*lp->getMatrixByCol(), lp->getColLower(), lp->getColUpper(), lp->getObjCoefficients(), lp->getRowLower(), lp->getRowUpper());
00146 int ncols = lp->getNumCols();
00147 for(int i = 0 ; i < ncols ; i++){
00148 if(lp->isInteger(i) || lp->isBinary(i))
00149 cpx_->setInteger(i);
00150 else
00151 cpx_->setContinuous(i);
00152 }
00153 }
00154 else {
00155 #endif
00156 if(ownClp_) delete clp_;
00157 ownClp_ = false;
00158 clp_ = (lp == NULL) ? NULL :
00159 dynamic_cast<OsiClpSolverInterface *>(lp);
00160 assert(clp_);
00161 #ifdef COIN_HAS_CPX
00162 }
00163 #endif
00164 lowBound_ = -COIN_DBL_MAX;
00165 optimal_ = false;
00166 if (integerSolution_) {
00167 delete [] integerSolution_;
00168 integerSolution_ = NULL;
00169 }
00170 }
00171
00172 OsiSolverInterface *
00173 SubMipSolver::solver(){
00174 if(clp_ != NULL)
00175 return clp_;
00176 else
00177 #ifdef COIN_HAS_CPX
00178 return cpx_;
00179 #else
00180 return NULL;
00181 #endif
00182 }
00183
00184 void
00185 SubMipSolver::find_good_sol(double cutoff, int loglevel, double max_time){
00186
00187 if(clp_){
00188 CbcStrategyDefault * strat_default = NULL;
00189 if (!strategy_){
00190 strat_default = new CbcStrategyDefault(1,5,5, loglevel);
00191 strat_default->setupPreProcessing();
00192 strategy_ = strat_default;
00193 }
00194 OsiBabSolver empty;
00195 CbcModel cbc(*clp_);
00196 cbc.solver()->setAuxiliaryInfo(&empty);
00197
00198
00199 strcpy(cbc.messagesPointer()->source_,"OCbc");
00200
00201 cbc.setLogLevel(loglevel);
00202 cbc.solver()->messageHandler()->setLogLevel(0);
00203 clp_->resolve();
00204 cbc.setStrategy(*strategy_);
00205 cbc.setLogLevel(loglevel);
00206 cbc.solver()->messageHandler()->setLogLevel(0);
00207 cbc.setMaximumSeconds(max_time);
00208 cbc.setMaximumSolutions(1);
00209 cbc.setCutoff(cutoff);
00210
00211
00212 cbc.branchAndBound();
00213 lowBound_ = cbc.getBestPossibleObjValue();
00214
00215 if (cbc.isProvenOptimal() || cbc.isProvenInfeasible())
00216 optimal_ = true;
00217 else optimal_ = false;
00218
00219 if (cbc.getSolutionCount()) {
00220 if (!integerSolution_)
00221 integerSolution_ = new double[clp_->getNumCols()];
00222 CoinCopyN(cbc.bestSolution(), clp_->getNumCols(), integerSolution_);
00223 }
00224 else if (integerSolution_) {
00225 delete [] integerSolution_;
00226 integerSolution_ = NULL;
00227 }
00228 nodeCount_ = cbc.getNodeCount();
00229 iterationCount_ = cbc.getIterationCount();
00230
00231 if(strat_default != NULL){
00232 delete strat_default;
00233 strategy_ = NULL;
00234 }
00235 }
00236 else if (cpx_){
00237 #ifndef COIN_HAS_CPX
00238 throw CoinError("Unsuported solver, for local searches you should use clp or cplex",
00239 "performLocalSearch",
00240 "OaDecompositionBase::SubMipSolver");
00241 #else
00242 cpx_->messageHandler()->setLogLevel(loglevel);
00243 cpx_->switchToMIP();
00244 CPXENVptr env = cpx_->getEnvironmentPtr();
00245 CPXLPptr cpxlp = cpx_->getLpPtr(OsiCpxSolverInterface::KEEPCACHED_ALL);
00246 CPXsetdblparam(env, CPX_PARAM_TILIM, max_time);
00247 CPXsetintparam(env, CPX_PARAM_CLOCKTYPE, 1);
00248 CPXsetdblparam(env, CPX_PARAM_EPINT, 1e-08);
00249 CPXsetdblparam(env, CPX_PARAM_CUTUP, cutoff);
00250 CPXsetdblparam(env, CPX_PARAM_EPGAP, gap_tol_);
00251
00252 double start_time = CoinCpuTime();
00253
00254 CPXsetintparam(env,CPX_PARAM_INTSOLLIM, 10);
00255 CPXsetintparam(env,CPX_PARAM_NODELIM, 1000);
00256
00257 nodeCount_ = 0;
00258 iterationCount_ = 0;
00259 int status = CPXmipopt(env,cpxlp);
00260 CHECK_CPX_STAT("mipopt",status)
00261
00262
00263 status = CPXgetbestobjval(env, cpxlp, &lowBound_);
00264 CHECK_CPX_STAT("bestobjvalue",status)
00265
00266 int stat = CPXgetstat( env, cpxlp);
00267 optimal_ = (stat == CPXMIP_INFEASIBLE) || (stat == CPXMIP_OPTIMAL) || (stat == CPXMIP_OPTIMAL_TOL) || (stat == CPXMIP_INForUNBD) ;
00268 nodeCount_ = CPXgetnodecnt(env , cpxlp);
00269 iterationCount_ = CPXgetmipitcnt(env , cpxlp);
00270
00271 int type;
00272 status = CPXsolninfo(env, cpxlp, NULL, &type, NULL, NULL);
00273 CHECK_CPX_STAT("solninfo", status);
00274 while(!optimal_ && type == CPX_NO_SOLN && stat != CPXMIP_SOL_LIM && stat != CPXMIP_TIME_LIM_INFEAS
00275 && stat != CPXMIP_TIME_LIM_FEAS && (CoinCpuTime() - start_time) <= max_time){
00276 CPXsetintparam(env, CPX_PARAM_INTSOLLIM, 1);
00277 CPXsetdblparam(env, CPX_PARAM_TILIM, max_time - CoinCpuTime() + start_time);
00278 CPXsetintparam(env,CPX_PARAM_NODELIM, 2100000000);
00279 status = CPXmipopt(env,cpxlp);
00280 CHECK_CPX_STAT("mipopt",status)
00281
00282 stat = CPXgetstat( env, cpxlp);
00283 optimal_ = (stat == CPXMIP_INFEASIBLE) || (stat == CPXMIP_OPTIMAL) || (stat == CPXMIP_OPTIMAL_TOL) || (stat == CPXMIP_INForUNBD) ;
00284 nodeCount_ = CPXgetnodecnt(env , cpxlp);
00285 iterationCount_ = CPXgetmipitcnt(env , cpxlp);
00286 }
00287 bool infeasible = (stat == CPXMIP_INFEASIBLE) || (stat == CPXMIP_ABORT_INFEAS) || (stat == CPXMIP_TIME_LIM_INFEAS)
00288 || (stat == CPXMIP_NODE_LIM_INFEAS) || (stat == CPXMIP_FAIL_INFEAS)
00289 || (stat == CPXMIP_MEM_LIM_INFEAS) || (stat == CPXMIP_INForUNBD);
00290
00291
00292 status = CPXgetbestobjval(env, cpxlp, &lowBound_);
00293 CHECK_CPX_STAT("getbestobjval",status)
00294 if(!infeasible){
00295 nodeCount_ += CPXgetnodecnt(env, cpxlp);
00296
00297 if(!integerSolution_){
00298 integerSolution_ = new double[cpx_->getNumCols()];
00299 }
00300 CPXgetmipx(env, cpxlp, integerSolution_, 0, cpx_->getNumCols() -1);
00301 CHECK_CPX_STAT("getmipx",status)
00302 }
00303 else {
00304 if (integerSolution_) {
00305 delete [] integerSolution_;
00306 integerSolution_ = NULL;
00307 }
00308 }
00309 cpx_->switchToLP();
00310 #endif
00311 }
00312 else {
00313 throw CoinError("Unsuported solver, for local searches you should use clp or cplex",
00314 "performLocalSearch",
00315 "OaDecompositionBase::SubMipSolver");
00316 }
00317 }
00318
00319 void
00320 SubMipSolver::optimize(double cutoff, int loglevel, double maxTime)
00321 {
00322 if (clp_) {
00323 assert(strategy_);
00324 CbcStrategyDefault * strat_default = dynamic_cast<CbcStrategyDefault *>(strategy_->clone());
00325 assert(strat_default);
00326 strat_default->setupPreProcessing();
00327
00328 OsiBabSolver empty;
00329 CbcModel cbc(*clp_);
00330 cbc.solver()->setAuxiliaryInfo(&empty);
00331
00332
00333 strcpy(cbc.messagesPointer()->source_,"OCbc");
00334
00335 cbc.setLogLevel(loglevel);
00336 cbc.solver()->messageHandler()->setLogLevel(0);
00337 clp_->resolve();
00338 cbc.setStrategy(*strategy_);
00339 cbc.setLogLevel(loglevel);
00340 cbc.solver()->messageHandler()->setLogLevel(0);
00341 cbc.setMaximumSeconds(maxTime);
00342 cbc.setCutoff(cutoff);
00343 cbc.setDblParam( CbcModel::CbcAllowableFractionGap, gap_tol_);
00344
00345
00346 cbc.branchAndBound();
00347 lowBound_ = cbc.getBestPossibleObjValue();
00348
00349 if (cbc.isProvenOptimal() || cbc.isProvenInfeasible())
00350 optimal_ = true;
00351 else optimal_ = false;
00352
00353 if (cbc.getSolutionCount()) {
00354 if (!integerSolution_)
00355 integerSolution_ = new double[clp_->getNumCols()];
00356 CoinCopyN(cbc.bestSolution(), clp_->getNumCols(), integerSolution_);
00357 }
00358 else if (integerSolution_) {
00359 delete [] integerSolution_;
00360 integerSolution_ = NULL;
00361 }
00362 nodeCount_ = cbc.getNodeCount();
00363 iterationCount_ = cbc.getIterationCount();
00364 delete strat_default;
00365 }
00366 else
00367 #ifdef COIN_HAS_CPX
00368 if (cpx_) {
00369 cpx_->switchToMIP();
00370 CPXENVptr env = cpx_->getEnvironmentPtr();
00371 CPXLPptr orig_lp = cpx_->getLpPtr(OsiCpxSolverInterface::KEEPCACHED_ALL);
00372
00373 int s;
00374 CPXLPptr cpxlp = CPXcloneprob(env, orig_lp, &s);
00375 double gap_tol = std::max(0.,gap_tol_- gap_tol_*(1e-01));
00376
00377 #ifdef SHIFT_CUTOFF
00378 if(cutoff < 1e20){
00379 cutoff = cutoff-fabs(cutoff)*gap_tol_*0.2;
00380 gap_tol = gap_tol_*0.8;
00381 }
00382 #endif
00383
00384 CPXsetdblparam(env, CPX_PARAM_TILIM, maxTime);
00385 CPXsetintparam(env, CPX_PARAM_CLOCKTYPE, 1);
00386 CPXsetdblparam(env, CPX_PARAM_CUTUP, cutoff);
00387 CPXsetdblparam(env, CPX_PARAM_EPGAP, gap_tol);
00388 CPXsetintparam( env, CPX_PARAM_PREIND, CPX_ON );
00389
00390
00391
00392
00393
00394 cpx_->messageHandler()->setLogLevel(loglevel);
00395
00396 int status = CPXmipopt(env,cpxlp);
00397 CHECK_CPX_STAT("mipopt",status)
00398
00399 int stat = CPXgetstat( env, cpxlp);
00400 bool infeasible = (stat == CPXMIP_INFEASIBLE) || (stat == CPXMIP_ABORT_INFEAS) || (stat == CPXMIP_TIME_LIM_INFEAS) || (stat == CPXMIP_NODE_LIM_INFEAS) || (stat == CPXMIP_FAIL_INFEAS)
00401 || (stat == CPXMIP_MEM_LIM_INFEAS) || (stat == CPXMIP_INForUNBD);
00402 optimal_ = (stat == CPXMIP_INFEASIBLE) || (stat == CPXMIP_OPTIMAL) || (stat == CPXMIP_OPTIMAL_TOL) || (stat == CPXMIP_INForUNBD);
00403 nodeCount_ = CPXgetnodecnt(env , cpxlp);
00404 iterationCount_ = CPXgetmipitcnt(env , cpxlp);
00405 status = CPXgetbestobjval(env, cpxlp, &lowBound_);
00406 CHECK_CPX_STAT("getbestobjval",status)
00407
00408 if(!infeasible){
00409 if(!integerSolution_){
00410 integerSolution_ = new double[cpx_->getNumCols()];
00411 }
00412 CPXgetmipx(env, cpxlp, integerSolution_, 0, cpx_->getNumCols() -1);
00413 CHECK_CPX_STAT("getmipx",status)
00414 }
00415 else {
00416 if (integerSolution_) {
00417 delete [] integerSolution_;
00418 integerSolution_ = NULL;
00419 }
00420 }
00421 CPXfreeprob(env, &cpxlp);
00422 cpx_->switchToLP();
00423 }
00424 else {
00425 #else
00426 {
00427 #endif
00428 throw CoinError("Unsuported solver, for local searches you should use clp or cplex",
00429 "performLocalSearch",
00430 "OaDecompositionBase::SubMipSolver");
00431 }
00432 }
00433
00434 void
00435 SubMipSolver::optimize_with_lazy_constraints(double cutoff, int loglevel, double maxTime, const OsiCuts &cs)
00436 {
00437 if (clp_) {
00438 fprintf(stderr, "Function optimize_with_lazy_constraints can only be used with CPLEX\n");
00439 optimize(cutoff,loglevel, maxTime);
00440 }
00441 else
00442 #ifdef COIN_HAS_CPX
00443 if (cpx_) {
00444 cpx_->switchToMIP();
00445 CPXENVptr env = cpx_->getEnvironmentPtr();
00446 CPXLPptr cpxlp = cpx_->getLpPtr(OsiCpxSolverInterface::KEEPCACHED_ALL);
00447
00448
00449
00450 int orig_nrows = CPXgetnumrows(env, cpxlp) - cs.sizeRowCuts();
00451
00452 CPXdelrows(env, cpxlp, orig_nrows, CPXgetnumrows(env, cpxlp) - 1);
00453
00454 int rcnt = cs.sizeRowCuts(), nzcnt = 0;
00455 vector<double> rhs(rcnt);
00456 vector<char> sense(rcnt);
00457 vector<int> beg(rcnt);
00458 vector<int> ind;
00459 vector<double> val;
00460 double infty = cpx_->getInfinity();
00461
00462 for(int i =0 ; i < rcnt ; i++){
00463 const OsiRowCut &r = cs.rowCut(i);
00464 const double lb = r.lb(), ub=r.ub();
00465 if(ub >= infty) {
00466 sense[i] = 'G';
00467 rhs[i] = lb;
00468 }
00469 else if (lb <= infty) {
00470 sense[i] = 'L';
00471 rhs[i] = ub;
00472 }
00473 else {
00474 assert(lb == ub);
00475 sense[i] = 'E';
00476 rhs[i] = ub;
00477 }
00478 beg[i] = nzcnt;
00479 nzcnt += r.row().getNumElements();
00480 }
00481
00482 ind.resize(nzcnt);
00483 val.resize(nzcnt);
00484 for(int i =0 ; i < rcnt ; i++){
00485 const OsiRowCut &r = cs.rowCut(i);
00486 const double * el = r.row().getElements();
00487 const int * id = r.row().getIndices();
00488 int nz = r.row().getNumElements();
00489 std::copy(el, el + nz, val() + beg[i]);
00490 std::copy(id, id + nz, ind() + beg[i]);
00491 }
00492
00493 CPXaddlazyconstraints(env, cpxlp, rcnt, nzcnt, rhs(), sense(), beg(), ind(), val(), NULL);
00494 CPXsetintparam(env, CPX_PARAM_REDUCE, CPX_PREREDUCE_PRIMALONLY);
00495
00496 CPXsetdblparam(env, CPX_PARAM_TILIM, maxTime);
00497 CPXsetintparam(env, CPX_PARAM_CLOCKTYPE, 1);
00498 CPXsetdblparam(env, CPX_PARAM_CUTUP, cutoff);
00499 CPXsetdblparam(env, CPX_PARAM_EPGAP, gap_tol_);
00500 cpx_->messageHandler()->setLogLevel(loglevel);
00501 int status = CPXmipopt(env,cpxlp);
00502 CHECK_CPX_STAT("mipopt",status)
00503
00504 int stat = CPXgetstat( env, cpxlp);
00505 bool infeasible = (stat == CPXMIP_INFEASIBLE) || (stat == CPXMIP_ABORT_INFEAS) || (stat == CPXMIP_TIME_LIM_INFEAS) || (stat == CPXMIP_NODE_LIM_INFEAS) || (stat == CPXMIP_FAIL_INFEAS)
00506 || (stat == CPXMIP_MEM_LIM_INFEAS) || (stat == CPXMIP_INForUNBD);
00507 optimal_ = (stat == CPXMIP_INFEASIBLE) || (stat == CPXMIP_OPTIMAL) || (stat == CPXMIP_OPTIMAL_TOL) || (stat == CPXMIP_INForUNBD);
00508 nodeCount_ = CPXgetnodecnt(env , cpxlp);
00509 iterationCount_ = CPXgetmipitcnt(env , cpxlp);
00510 status = CPXgetbestobjval(env, cpxlp, &lowBound_);
00511 CHECK_CPX_STAT("getbestobjval",status)
00512
00513 if(!infeasible){
00514 if(!integerSolution_){
00515 integerSolution_ = new double[cpx_->getNumCols()];
00516 }
00517 CPXgetmipx(env, cpxlp, integerSolution_, 0, cpx_->getNumCols() -1);
00518 CHECK_CPX_STAT("getmipx",status)
00519 }
00520 else {
00521 if (integerSolution_) {
00522 delete [] integerSolution_;
00523 integerSolution_ = NULL;
00524 }
00525 }
00526 cpx_->switchToLP();
00527 CPXfreelazyconstraints(env, cpxlp);
00528 CPXaddrows(env, cpxlp, 0, rcnt, nzcnt, rhs(), sense(), beg(), ind(), val(), NULL, NULL);
00529 }
00530 else {
00531 #else
00532 {
00533 #endif
00534 throw CoinError("Unsuported solver, for local searches you should use clp or cplex",
00535 "performLocalSearch",
00536 "OaDecompositionBase::SubMipSolver");
00537 }
00538 }
00539
00541 void
00542 SubMipSolver::setStrategy(CbcStrategyDefault * strategy)
00543 {
00544 if (strategy_) delete strategy_;
00545 strategy_ = dynamic_cast<CbcStrategyDefault *>(strategy->clone());
00546 assert(strategy_);
00547 }
00548
00550 void
00551 SubMipSolver::registerOptions(Ipopt::SmartPtr<Bonmin::RegisteredOptions> roptions)
00552 {
00553 roptions->SetRegisteringCategory("MILP Solver", RegisteredOptions::BonminCategory);
00554 roptions->AddStringOption3("milp_solver",
00555 "Choose the subsolver to solve MILP sub-problems in OA decompositions.",
00556 "Cbc_D",
00557 "Cbc_D","Coin Branch and Cut with its default",
00558 "Cbc_Par", "Coin Branch and Cut with passed parameters",
00559 "Cplex","IBM Cplex",
00560 " To use Cplex, a valid license is required and you should have compiled OsiCpx in COIN-OR (see Osi documentation).");
00561 roptions->setOptionExtraInfo("milp_solver",64);
00562
00563 roptions->AddBoundedIntegerOption("cpx_parallel_strategy",
00564 "Strategy of parallel search mode in CPLEX.",
00565 -1, 1, 0,
00566 "-1 = opportunistic, 0 = automatic, 1 = deterministic (refer to CPLEX documentation)"
00567 );
00568 roptions->setOptionExtraInfo("cpx_parallel_strategy",64);
00569
00570 roptions->AddLowerBoundedIntegerOption("number_cpx_threads",
00571 "Set number of threads to use with cplex.",
00572 0, 0,
00573 "(refer to CPLEX documentation)"
00574 );
00575 roptions->setOptionExtraInfo("number_cpx_threads",64);
00576
00577
00578 roptions->AddStringOption2("milp_strategy",
00579 "Choose a strategy for MILPs.",
00580 "solve_to_optimality",
00581 "find_good_sol","Stop sub milps when a solution improving the incumbent is found",
00582 "solve_to_optimality", "Solve MILPs to optimality",
00583 "");
00584 roptions->setOptionExtraInfo("milp_strategy",64);
00585
00586 roptions->SetRegisteringCategory("Output and Loglevel", RegisteredOptions::BonminCategory);
00587 roptions->AddBoundedIntegerOption("milp_log_level",
00588 "specify MILP solver log level.",
00589 0,4,0,
00590 "Set the level of output of the MILP subsolver in OA : "
00591 "0 - none, 1 - minimal, 2 - normal low, 3 - normal high"
00592 );
00593 roptions->setOptionExtraInfo("milp_log_level",64);
00594
00595 }
00596 }