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);
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);
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 copied_prob;
00374 CPXLPptr cpxlp = CPXcloneprob(env, orig_lp, &copied_prob);
00375 if (copied_prob != 0){
00376 cpxlp = orig_lp;
00377 }
00378 double gap_tol = std::max(0.,gap_tol_- gap_tol_*(1e-01));
00379
00380 #ifdef SHIFT_CUTOFF
00381 if(cutoff < 1e20){
00382 cutoff = cutoff-fabs(cutoff)*gap_tol_*0.2;
00383 gap_tol = gap_tol_*0.8;
00384 }
00385 #endif
00386
00387 CPXsetdblparam(env, CPX_PARAM_TILIM, maxTime);
00388 CPXsetintparam(env, CPX_PARAM_CLOCKTYPE, 1);
00389 CPXsetdblparam(env, CPX_PARAM_CUTUP, cutoff);
00390 CPXsetdblparam(env, CPX_PARAM_EPGAP, gap_tol);
00391 CPXsetintparam( env, CPX_PARAM_PREIND, CPX_ON );
00392
00393
00394
00395
00396
00397 cpx_->messageHandler()->setLogLevel(loglevel);
00398
00399 int status = CPXmipopt(env,cpxlp);
00400 CHECK_CPX_STAT("mipopt",status)
00401
00402 int stat = CPXgetstat( env, cpxlp);
00403 bool infeasible = (stat == CPXMIP_INFEASIBLE) || (stat == CPXMIP_ABORT_INFEAS) || (stat == CPXMIP_TIME_LIM_INFEAS) || (stat == CPXMIP_NODE_LIM_INFEAS) || (stat == CPXMIP_FAIL_INFEAS)
00404 || (stat == CPXMIP_MEM_LIM_INFEAS) || (stat == CPXMIP_INForUNBD);
00405 optimal_ = (stat == CPXMIP_INFEASIBLE) || (stat == CPXMIP_OPTIMAL) || (stat == CPXMIP_OPTIMAL_TOL);
00406 nodeCount_ = CPXgetnodecnt(env , cpxlp);
00407 iterationCount_ = CPXgetmipitcnt(env , cpxlp);
00408 status = CPXgetbestobjval(env, cpxlp, &lowBound_);
00409 CHECK_CPX_STAT("getbestobjval",status)
00410
00411 if(!infeasible){
00412 if(!integerSolution_){
00413 integerSolution_ = new double[cpx_->getNumCols()];
00414 }
00415 CPXgetmipx(env, cpxlp, integerSolution_, 0, cpx_->getNumCols() -1);
00416 CHECK_CPX_STAT("getmipx",status)
00417 }
00418 else {
00419 if (integerSolution_) {
00420 delete [] integerSolution_;
00421 integerSolution_ = NULL;
00422 }
00423 }
00424 if (copied_prob == 0){
00425 CPXfreeprob(env, &cpxlp);
00426 }
00427 cpx_->switchToLP();
00428 }
00429 else {
00430 #else
00431 {
00432 #endif
00433 throw CoinError("Unsuported solver, for local searches you should use clp or cplex",
00434 "performLocalSearch",
00435 "OaDecompositionBase::SubMipSolver");
00436 }
00437 }
00438
00439 void
00440 SubMipSolver::optimize_with_lazy_constraints(double cutoff, int loglevel, double maxTime, const OsiCuts &cs)
00441 {
00442 if (clp_) {
00443 fprintf(stderr, "Function optimize_with_lazy_constraints can only be used with CPLEX\n");
00444 optimize(cutoff,loglevel, maxTime);
00445 }
00446 else
00447 #ifdef COIN_HAS_CPX
00448 if (cpx_) {
00449 cpx_->switchToMIP();
00450 CPXENVptr env = cpx_->getEnvironmentPtr();
00451 CPXLPptr cpxlp = cpx_->getLpPtr(OsiCpxSolverInterface::KEEPCACHED_ALL);
00452
00453
00454
00455 int orig_nrows = CPXgetnumrows(env, cpxlp) - cs.sizeRowCuts();
00456 printf("Number of rows %i\n", cs.sizeRowCuts());
00457 CPXdelrows(env, cpxlp, orig_nrows, CPXgetnumrows(env, cpxlp) - 1);
00458
00459 int rcnt = cs.sizeRowCuts(), nzcnt = 0;
00460 vector<double> rhs(rcnt);
00461 vector<char> sense(rcnt);
00462 vector<int> beg(rcnt);
00463 vector<int> ind;
00464 vector<double> val;
00465 double infty = cpx_->getInfinity();
00466
00467 for(int i =0 ; i < rcnt ; i++){
00468 const OsiRowCut &r = cs.rowCut(i);
00469 const double lb = r.lb(), ub=r.ub();
00470 if(ub >= infty) {
00471 sense[i] = 'G';
00472 rhs[i] = lb;
00473 }
00474 else if (lb <= infty) {
00475 sense[i] = 'L';
00476 rhs[i] = ub;
00477 }
00478 else {
00479 assert(lb == ub);
00480 sense[i] = 'E';
00481 rhs[i] = ub;
00482 }
00483 beg[i] = nzcnt;
00484 nzcnt += r.row().getNumElements();
00485 }
00486
00487 ind.resize(nzcnt);
00488 val.resize(nzcnt);
00489 for(int i =0 ; i < rcnt ; i++){
00490 const OsiRowCut &r = cs.rowCut(i);
00491 const double * el = r.row().getElements();
00492 const int * id = r.row().getIndices();
00493 int nz = r.row().getNumElements();
00494 std::copy(el, el + nz, val() + beg[i]);
00495 std::copy(id, id + nz, ind() + beg[i]);
00496 }
00497
00498 CPXaddlazyconstraints(env, cpxlp, rcnt, nzcnt, rhs(), sense(), beg(), ind(), val(), NULL);
00499 CPXsetintparam(env, CPX_PARAM_REDUCE, CPX_PREREDUCE_PRIMALONLY);
00500
00501 CPXsetdblparam(env, CPX_PARAM_TILIM, maxTime);
00502 CPXsetintparam(env, CPX_PARAM_CLOCKTYPE, 1);
00503 CPXsetdblparam(env, CPX_PARAM_CUTUP, cutoff);
00504 CPXsetdblparam(env, CPX_PARAM_EPGAP, gap_tol_);
00505 cpx_->messageHandler()->setLogLevel(loglevel);
00506 int status = CPXmipopt(env,cpxlp);
00507 CHECK_CPX_STAT("mipopt",status)
00508
00509 int stat = CPXgetstat( env, cpxlp);
00510 bool infeasible = (stat == CPXMIP_INFEASIBLE) || (stat == CPXMIP_ABORT_INFEAS) || (stat == CPXMIP_TIME_LIM_INFEAS) || (stat == CPXMIP_NODE_LIM_INFEAS) || (stat == CPXMIP_FAIL_INFEAS)
00511 || (stat == CPXMIP_MEM_LIM_INFEAS) || (stat == CPXMIP_INForUNBD);
00512 optimal_ = (stat == CPXMIP_INFEASIBLE) || (stat == CPXMIP_OPTIMAL) || (stat == CPXMIP_OPTIMAL_TOL);
00513 nodeCount_ = CPXgetnodecnt(env , cpxlp);
00514 iterationCount_ = CPXgetmipitcnt(env , cpxlp);
00515 status = CPXgetbestobjval(env, cpxlp, &lowBound_);
00516 CHECK_CPX_STAT("getbestobjval",status)
00517
00518 if(!infeasible){
00519 if(!integerSolution_){
00520 integerSolution_ = new double[cpx_->getNumCols()];
00521 }
00522 CPXgetmipx(env, cpxlp, integerSolution_, 0, cpx_->getNumCols() -1);
00523 CHECK_CPX_STAT("getmipx",status)
00524 }
00525 else {
00526 if (integerSolution_) {
00527 delete [] integerSolution_;
00528 integerSolution_ = NULL;
00529 }
00530 }
00531 cpx_->switchToLP();
00532 CPXfreelazyconstraints(env, cpxlp);
00533 CPXaddrows(env, cpxlp, 0, rcnt, nzcnt, rhs(), sense(), beg(), ind(), val(), NULL, NULL);
00534 }
00535 else {
00536 #else
00537 {
00538 #endif
00539 throw CoinError("Unsuported solver, for local searches you should use clp or cplex",
00540 "performLocalSearch",
00541 "OaDecompositionBase::SubMipSolver");
00542 }
00543 }
00544
00546 void
00547 SubMipSolver::setStrategy(CbcStrategyDefault * strategy)
00548 {
00549 if (strategy_) delete strategy_;
00550 strategy_ = dynamic_cast<CbcStrategyDefault *>(strategy->clone());
00551 assert(strategy_);
00552 }
00553
00555 void
00556 SubMipSolver::registerOptions(Ipopt::SmartPtr<Bonmin::RegisteredOptions> roptions)
00557 {
00558 roptions->SetRegisteringCategory("Options for MILP solver", RegisteredOptions::BonminCategory);
00559 roptions->AddStringOption3("milp_solver",
00560 "Choose the subsolver to solve MILP sub-problems in OA decompositions.",
00561 "Cbc_D",
00562 "Cbc_D","Coin Branch and Cut with its default",
00563 "Cbc_Par", "Coin Branch and Cut with passed parameters",
00564 "Cplex","Ilog Cplex",
00565 " To use Cplex, a valid license is required and you should have compiled OsiCpx in COIN-OR (see Osi documentation).");
00566 roptions->setOptionExtraInfo("milp_solver",64);
00567
00568 roptions->AddBoundedIntegerOption("milp_log_level",
00569 "specify MILP solver log level.",
00570 0,4,0,
00571 "Set the level of output of the MILP subsolver in OA : "
00572 "0 - none, 1 - minimal, 2 - normal low, 3 - normal high"
00573 );
00574 roptions->setOptionExtraInfo("milp_log_level",64);
00575
00576 roptions->AddBoundedIntegerOption("cpx_parallel_strategy",
00577 "Strategy of parallel search mode in CPLEX.",
00578 -1, 1, 0,
00579 "-1 = opportunistic, 0 = automatic, 1 = deterministic (refer to CPLEX documentation)"
00580 );
00581 roptions->setOptionExtraInfo("cpx_parallel_strategy",64);
00582
00583 roptions->AddLowerBoundedIntegerOption("number_cpx_threads",
00584 "Set number of threads to use with cplex.",
00585 0, 0,
00586 "(refer to CPLEX documentation)"
00587 );
00588 roptions->setOptionExtraInfo("number_cpx_threads",64);
00589
00590
00591 roptions->AddStringOption2("milp_strategy",
00592 "Choose a strategy for MILPs.",
00593 "find_good_sol",
00594 "find_good_sol","Stop sub milps when a solution improving the incumbent is found",
00595 "solve_to_optimality", "Solve MILPs to optimality",
00596 "");
00597 roptions->setOptionExtraInfo("milp_strategy",64);
00598
00599 }
00600 }