BonSubMipSolver.cpp
Go to the documentation of this file.
1 // (C) Copyright International Business Machines (IBM) 2006
2 // All Rights Reserved.
3 // This code is published under the Eclipse Public License.
4 //
5 // Authors :
6 // P. Bonami, International Business Machines
7 //
8 // Date : 12/07/2006
9 
10 
11 // Code separated from BonOaDecBase to try to clarify OAs
12 #include "BonSubMipSolver.hpp"
13 #include "BonminConfig.h"
14 #include "CbcModel.hpp"
15 #include "CbcStrategy.hpp"
16 #include "OsiAuxInfo.hpp"
17 #include "OsiClpSolverInterface.hpp"
18 
19 #include <climits>
20 #ifdef COIN_HAS_CPX
21 #include "OsiCpxSolverInterface.hpp"
22 #include "cplex.h"
23 void throw_error(const std::string &s, const std::string &f, const std::string &func){
24 throw CoinError(s,f,func);
25 }
26 #define CHECK_CPX_STAT(a,b) if(b) throw_error("Error in CPLEX call",__FILE__,a);
27 
28 #endif
29 
30 #include "BonRegisteredOptions.hpp"
31 #include "BonBabSetupBase.hpp"
32 #include "BonCbcLpStrategy.hpp"
33 
34 
35 namespace Bonmin {
38  clp_(NULL),
39  cpx_(NULL),
40  lowBound_(-DBL_MAX),
41  optimal_(false),
42  integerSolution_(NULL),
43  strategy_(NULL),
44  ownClp_(false)
45  {
46 
47  int logLevel;
48  b.options()->GetIntegerValue("milp_log_level", logLevel, prefix);
49 
50  int ivalue;
51  b.options()->GetEnumValue("milp_solver",ivalue,prefix);
52  if (ivalue <= 0) {//uses cbc
53  strategy_ = new CbcStrategyDefault;
54  clp_ = new OsiClpSolverInterface;
55  ownClp_ = true;
56  clp_->messageHandler()->setLogLevel(logLevel);
57  }
58  else if (ivalue == 1) {
59  CbcStrategyChooseCuts strategy(b, prefix);
60  strategy_ = new CbcStrategyChooseCuts(b, prefix);
61  clp_ = new OsiClpSolverInterface;
62  ownClp_ = true;
63  clp_->messageHandler()->setLogLevel(logLevel);
64  }
65  else if (ivalue == 2) {
66 #ifdef COIN_HAS_CPX
67  OsiCpxSolverInterface * cpxSolver = new OsiCpxSolverInterface;
68 #if 1
69 
70  b.options()->GetIntegerValue("number_cpx_threads",ivalue,prefix);
71  CPXsetintparam(cpxSolver->getEnvironmentPtr(), CPX_PARAM_THREADS, ivalue);
72  b.options()->GetIntegerValue("cpx_parallel_strategy",ivalue,prefix);
73  CPXsetintparam(cpxSolver->getEnvironmentPtr(), CPX_PARAM_PARALLELMODE, ivalue);
74 #endif
75  cpx_ = cpxSolver;
76  cpx_->messageHandler()->setLogLevel(logLevel);
77 #else
78  std::cerr << "You have set an option to use CPLEX as the milp\n"
79  << "subsolver in oa decomposition. However, apparently\n"
80  << "CPLEX is not configured to be used in bonmin.\n"
81  << "See the manual for configuring CPLEX\n";
82  throw -1;
83 #endif
84  }
85 
86  b.options()->GetEnumValue("milp_strategy",ivalue,prefix);
87  if(ivalue == 0){
89  }
90  else {
92  }
93 
94  b.options()->GetNumericValue("allowable_fraction_gap", gap_tol_, prefix);
95 
96 
97  }
99  clp_(NULL),
100  cpx_(NULL),
101  lowBound_(-DBL_MAX),
102  optimal_(false),
103  integerSolution_(NULL),
104  strategy_(NULL),
105  milp_strat_(copy.milp_strat_),
106  gap_tol_(copy.gap_tol_),
107  ownClp_(copy.ownClp_)
108  {
109 #ifdef COIN_HAS_CPX
110  if(copy.cpx_ != NULL){
111  cpx_ = new OsiCpxSolverInterface(*copy.cpx_);
112  int ival;
113  CPXgetintparam(copy.cpx_->getEnvironmentPtr(), CPX_PARAM_THREADS, &ival);
114  CPXsetintparam(cpx_->getEnvironmentPtr(), CPX_PARAM_THREADS, ival);
115  CPXgetintparam(copy.cpx_->getEnvironmentPtr(), CPX_PARAM_PARALLELMODE, &ival);
116  CPXsetintparam(cpx_->getEnvironmentPtr(), CPX_PARAM_PARALLELMODE, ival);
117  }
118 #endif
119  if(copy.clp_ != NULL){
120  if(ownClp_) clp_ = new OsiClpSolverInterface(*copy.clp_);
121  else clp_ = copy.clp_;
122  }
123  if(copy.strategy_){
124  strategy_ = dynamic_cast<CbcStrategyDefault *>(copy.strategy_->clone());
125  assert(strategy_);
126  }
127  }
129  {
130  if (strategy_) delete strategy_;
131  if (integerSolution_) delete [] integerSolution_;
132  #ifdef COIN_HAS_CPX
133  if(cpx_) delete cpx_;
134  #endif
135  if(ownClp_) delete clp_;
136  }
137 
139  void
140  SubMipSolver::setLpSolver(OsiSolverInterface * lp)
141  {
142 #ifdef COIN_HAS_CPX
143  if(cpx_){
144  clp_ = NULL;
145  cpx_->loadProblem(*lp->getMatrixByCol(), lp->getColLower(), lp->getColUpper(), lp->getObjCoefficients(), lp->getRowLower(), lp->getRowUpper());
146  int ncols = lp->getNumCols();
147  for(int i = 0 ; i < ncols ; i++){
148  if(lp->isInteger(i) || lp->isBinary(i))
149  cpx_->setInteger(i);
150  else
151  cpx_->setContinuous(i);
152  }
153  }
154  else {
155 #endif
156  if(ownClp_) delete clp_;
157  ownClp_ = false;
158  clp_ = (lp == NULL) ? NULL :
159  dynamic_cast<OsiClpSolverInterface *>(lp);
160  assert(clp_);
161 #ifdef COIN_HAS_CPX
162  }
163 #endif
164  lowBound_ = -COIN_DBL_MAX;
165  optimal_ = false;
166  if (integerSolution_) {
167  delete [] integerSolution_;
168  integerSolution_ = NULL;
169  }
170  }
171 
172  OsiSolverInterface *
174  if(clp_ != NULL)
175  return clp_;
176  else
177 #ifdef COIN_HAS_CPX
178  return cpx_;
179 #else
180  return NULL;
181 #endif
182  }
183 
184  void
185  SubMipSolver::find_good_sol(double cutoff, int loglevel, double max_time){
186 
187  if(clp_){
188  CbcStrategyDefault * strat_default = NULL;
189  if (!strategy_){
190  strat_default = new CbcStrategyDefault(1,5,5, loglevel);
191  strat_default->setupPreProcessing();
192  strategy_ = strat_default;
193  }
194  OsiBabSolver empty;
195  CbcModel cbc(*clp_);
196  cbc.solver()->setAuxiliaryInfo(&empty);
197 
198  //Change Cbc messages prefixes
199  strcpy(cbc.messagesPointer()->source_,"OCbc");
200 
201  cbc.setLogLevel(loglevel);
202  cbc.solver()->messageHandler()->setLogLevel(0);
203  clp_->resolve();
204  cbc.setStrategy(*strategy_);
205  cbc.setLogLevel(loglevel);
206  cbc.solver()->messageHandler()->setLogLevel(0);
207  cbc.setMaximumSeconds(max_time);
208  cbc.setMaximumSolutions(1);
209  cbc.setCutoff(cutoff);
210 
211 
212  cbc.branchAndBound();
213  lowBound_ = cbc.getBestPossibleObjValue();
214 
215  if (cbc.isProvenOptimal() || cbc.isProvenInfeasible())
216  optimal_ = true;
217  else optimal_ = false;
218 
219  if (cbc.getSolutionCount()) {
220  if (!integerSolution_)
221  integerSolution_ = new double[clp_->getNumCols()];
222  CoinCopyN(cbc.bestSolution(), clp_->getNumCols(), integerSolution_);
223  }
224  else if (integerSolution_) {
225  delete [] integerSolution_;
226  integerSolution_ = NULL;
227  }
228  nodeCount_ = cbc.getNodeCount();
229  iterationCount_ = cbc.getIterationCount();
230 
231  if(strat_default != NULL){
232  delete strat_default;
233  strategy_ = NULL;
234  }
235  }
236  else if (cpx_){
237 #ifndef COIN_HAS_CPX
238  throw CoinError("Unsuported solver, for local searches you should use clp or cplex",
239  "performLocalSearch",
240  "OaDecompositionBase::SubMipSolver");
241 #else
242  cpx_->messageHandler()->setLogLevel(loglevel);
243  cpx_->switchToMIP();
244  CPXENVptr env = cpx_->getEnvironmentPtr();
245  CPXLPptr cpxlp = cpx_->getLpPtr(OsiCpxSolverInterface::KEEPCACHED_ALL);
246  CPXsetdblparam(env, CPX_PARAM_TILIM, max_time);
247  CPXsetintparam(env, CPX_PARAM_CLOCKTYPE, 1);
248  CPXsetdblparam(env, CPX_PARAM_EPINT, 1e-08);
249  CPXsetdblparam(env, CPX_PARAM_CUTUP, cutoff);
250  CPXsetdblparam(env, CPX_PARAM_EPGAP, gap_tol_);
251 
252  double start_time = CoinCpuTime();
253 
254  CPXsetintparam(env,CPX_PARAM_INTSOLLIM, 10);
255  CPXsetintparam(env,CPX_PARAM_NODELIM, 1000);
256 
257  nodeCount_ = 0;
258  iterationCount_ = 0;
259  int status = CPXmipopt(env,cpxlp);
260  CHECK_CPX_STAT("mipopt",status)
261 
262 
263  status = CPXgetbestobjval(env, cpxlp, &lowBound_);
264  CHECK_CPX_STAT("bestobjvalue",status)
265 
266  int stat = CPXgetstat( env, cpxlp);
267  optimal_ = (stat == CPXMIP_INFEASIBLE) || (stat == CPXMIP_OPTIMAL) || (stat == CPXMIP_OPTIMAL_TOL) || (stat == CPXMIP_INForUNBD) ;
268  nodeCount_ = CPXgetnodecnt(env , cpxlp);
269  iterationCount_ = CPXgetmipitcnt(env , cpxlp);
270 
271  int type;
272  status = CPXsolninfo(env, cpxlp, NULL, &type, NULL, NULL);
273  CHECK_CPX_STAT("solninfo", status);
274  while(!optimal_ && type == CPX_NO_SOLN && stat != CPXMIP_SOL_LIM && stat != CPXMIP_TIME_LIM_INFEAS
275  && stat != CPXMIP_TIME_LIM_FEAS && (CoinCpuTime() - start_time) <= max_time){
276  CPXsetintparam(env, CPX_PARAM_INTSOLLIM, 1);
277  CPXsetdblparam(env, CPX_PARAM_TILIM, max_time - CoinCpuTime() + start_time);
278  CPXsetintparam(env,CPX_PARAM_NODELIM, 2100000000);
279  status = CPXmipopt(env,cpxlp);
280  CHECK_CPX_STAT("mipopt",status)
281 
282  stat = CPXgetstat( env, cpxlp);
283  optimal_ = (stat == CPXMIP_INFEASIBLE) || (stat == CPXMIP_OPTIMAL) || (stat == CPXMIP_OPTIMAL_TOL) || (stat == CPXMIP_INForUNBD) ;
284  nodeCount_ = CPXgetnodecnt(env , cpxlp);
285  iterationCount_ = CPXgetmipitcnt(env , cpxlp);
286  }
287  bool infeasible = (stat == CPXMIP_INFEASIBLE) || (stat == CPXMIP_ABORT_INFEAS) || (stat == CPXMIP_TIME_LIM_INFEAS)
288  || (stat == CPXMIP_NODE_LIM_INFEAS) || (stat == CPXMIP_FAIL_INFEAS)
289  || (stat == CPXMIP_MEM_LIM_INFEAS) || (stat == CPXMIP_INForUNBD);
290 
291 
292  status = CPXgetbestobjval(env, cpxlp, &lowBound_);
293  CHECK_CPX_STAT("getbestobjval",status)
294  if(!infeasible){
295  nodeCount_ += CPXgetnodecnt(env, cpxlp);
296  //iterationCount_ += CPXgetitcnt(env, cpxlp);
297  if(!integerSolution_){
298  integerSolution_ = new double[cpx_->getNumCols()];
299  }
300  CPXgetmipx(env, cpxlp, integerSolution_, 0, cpx_->getNumCols() -1);
301  CHECK_CPX_STAT("getmipx",status)
302  }
303  else {
304  if (integerSolution_) {
305  delete [] integerSolution_;
306  integerSolution_ = NULL;
307  }
308  }
309  cpx_->switchToLP();
310 #endif
311  }
312  else {
313  throw CoinError("Unsuported solver, for local searches you should use clp or cplex",
314  "performLocalSearch",
315  "OaDecompositionBase::SubMipSolver");
316  }
317  }
318 
319  void
320  SubMipSolver::optimize(double cutoff, int loglevel, double maxTime)
321  {
322  if (clp_) {
323  assert(strategy_);
324  CbcStrategyDefault * strat_default = dynamic_cast<CbcStrategyDefault *>(strategy_->clone());
325  assert(strat_default);
326  strat_default->setupPreProcessing();
327 
328  OsiBabSolver empty;
329  CbcModel cbc(*clp_);
330  cbc.solver()->setAuxiliaryInfo(&empty);
331 
332  //Change Cbc messages prefixes
333  strcpy(cbc.messagesPointer()->source_,"OCbc");
334 
335  cbc.setLogLevel(loglevel);
336  cbc.solver()->messageHandler()->setLogLevel(0);
337  clp_->resolve();
338  cbc.setStrategy(*strategy_);
339  cbc.setLogLevel(loglevel);
340  cbc.solver()->messageHandler()->setLogLevel(0);
341  cbc.setMaximumSeconds(maxTime);
342  cbc.setCutoff(cutoff);
343  cbc.setDblParam( CbcModel::CbcAllowableFractionGap, gap_tol_);
344 
345  //cbc.solver()->writeMpsNative("FP.mps", NULL, NULL, 1);
346  cbc.branchAndBound();
347  lowBound_ = cbc.getBestPossibleObjValue();
348 
349  if (cbc.isProvenOptimal() || cbc.isProvenInfeasible())
350  optimal_ = true;
351  else optimal_ = false;
352 
353  if (cbc.getSolutionCount()) {
354  if (!integerSolution_)
355  integerSolution_ = new double[clp_->getNumCols()];
356  CoinCopyN(cbc.bestSolution(), clp_->getNumCols(), integerSolution_);
357  }
358  else if (integerSolution_) {
359  delete [] integerSolution_;
360  integerSolution_ = NULL;
361  }
362  nodeCount_ = cbc.getNodeCount();
363  iterationCount_ = cbc.getIterationCount();
364  delete strat_default;
365  }
366  else
367 #ifdef COIN_HAS_CPX
368  if (cpx_) {
369  cpx_->switchToMIP();
370  CPXENVptr env = cpx_->getEnvironmentPtr();
371  CPXLPptr orig_lp = cpx_->getLpPtr(OsiCpxSolverInterface::KEEPCACHED_ALL);
372 
373  int s;
374  CPXLPptr cpxlp = CPXcloneprob(env, orig_lp, &s);
375  double gap_tol = std::max(0.,gap_tol_- gap_tol_*(1e-01));
376 
377 #ifdef SHIFT_CUTOFF
378  if(cutoff < 1e20){
379  cutoff = cutoff-fabs(cutoff)*gap_tol_*0.2;
380  gap_tol = gap_tol_*0.8;
381  }
382 #endif
383 
384  CPXsetdblparam(env, CPX_PARAM_TILIM, maxTime);
385  CPXsetintparam(env, CPX_PARAM_CLOCKTYPE, 1);
386  CPXsetdblparam(env, CPX_PARAM_CUTUP, cutoff);
387  CPXsetdblparam(env, CPX_PARAM_EPGAP, gap_tol);
388  CPXsetintparam( env, CPX_PARAM_PREIND, CPX_ON );
389 
390  //CPXwriteprob(env, cpxlp, "OA_trunk","MPS");
391  //CPXwriteparam(env, "params.txt");
392 
393 
394  cpx_->messageHandler()->setLogLevel(loglevel);
395 
396  int status = CPXmipopt(env,cpxlp);
397  CHECK_CPX_STAT("mipopt",status)
398 
399  int stat = CPXgetstat( env, cpxlp);
400  bool infeasible = (stat == CPXMIP_INFEASIBLE) || (stat == CPXMIP_ABORT_INFEAS) || (stat == CPXMIP_TIME_LIM_INFEAS) || (stat == CPXMIP_NODE_LIM_INFEAS) || (stat == CPXMIP_FAIL_INFEAS)
401  || (stat == CPXMIP_MEM_LIM_INFEAS) || (stat == CPXMIP_INForUNBD);
402  optimal_ = (stat == CPXMIP_INFEASIBLE) || (stat == CPXMIP_OPTIMAL) || (stat == CPXMIP_OPTIMAL_TOL) || (stat == CPXMIP_INForUNBD);
403  nodeCount_ = CPXgetnodecnt(env , cpxlp);
404  iterationCount_ = CPXgetmipitcnt(env , cpxlp);
405  status = CPXgetbestobjval(env, cpxlp, &lowBound_);
406  CHECK_CPX_STAT("getbestobjval",status)
407 
408  if(!infeasible){
409  if(!integerSolution_){
410  integerSolution_ = new double[cpx_->getNumCols()];
411  }
412  CPXgetmipx(env, cpxlp, integerSolution_, 0, cpx_->getNumCols() -1);
413  CHECK_CPX_STAT("getmipx",status)
414  }
415  else {
416  if (integerSolution_) {
417  delete [] integerSolution_;
418  integerSolution_ = NULL;
419  }
420  }
421  CPXfreeprob(env, &cpxlp);
422  cpx_->switchToLP();
423  }
424  else {
425 #else
426  {
427 #endif
428  throw CoinError("Unsuported solver, for local searches you should use clp or cplex",
429  "performLocalSearch",
430  "OaDecompositionBase::SubMipSolver");
431  }
432 }
433 
434  void
435  SubMipSolver::optimize_with_lazy_constraints(double cutoff, int loglevel, double maxTime, const OsiCuts &cs)
436  {
437  if (clp_) {
438  fprintf(stderr, "Function optimize_with_lazy_constraints can only be used with CPLEX\n");
439  optimize(cutoff,loglevel, maxTime);
440  }
441  else
442 #ifdef COIN_HAS_CPX
443  if (cpx_) {
444  cpx_->switchToMIP();
445  CPXENVptr env = cpx_->getEnvironmentPtr();
446  CPXLPptr cpxlp = cpx_->getLpPtr(OsiCpxSolverInterface::KEEPCACHED_ALL);
447 
448 // Remove all the cuts and declare them as lazy constraints
449 
450  int orig_nrows = CPXgetnumrows(env, cpxlp) - cs.sizeRowCuts();
451  /* printf("Number of rows %i\n", cs.sizeRowCuts()); */
452  CPXdelrows(env, cpxlp, orig_nrows, CPXgetnumrows(env, cpxlp) - 1);
453 
454  int rcnt = cs.sizeRowCuts(), nzcnt = 0;
455  vector<double> rhs(rcnt);
456  vector<char> sense(rcnt);
457  vector<int> beg(rcnt);
458  vector<int> ind;
459  vector<double> val;
460  double infty = cpx_->getInfinity();
461 
462  for(int i =0 ; i < rcnt ; i++){
463  const OsiRowCut &r = cs.rowCut(i);
464  const double lb = r.lb(), ub=r.ub();
465  if(ub >= infty) {
466  sense[i] = 'G';
467  rhs[i] = lb;
468  }
469  else if (lb <= infty) {
470  sense[i] = 'L';
471  rhs[i] = ub;
472  }
473  else {
474  assert(lb == ub);
475  sense[i] = 'E';
476  rhs[i] = ub;
477  }
478  beg[i] = nzcnt;
479  nzcnt += r.row().getNumElements();
480  }
481 
482  ind.resize(nzcnt);
483  val.resize(nzcnt);
484  for(int i =0 ; i < rcnt ; i++){
485  const OsiRowCut &r = cs.rowCut(i);
486  const double * el = r.row().getElements();
487  const int * id = r.row().getIndices();
488  int nz = r.row().getNumElements();
489  std::copy(el, el + nz, val() + beg[i]);
490  std::copy(id, id + nz, ind() + beg[i]);
491  }
492 
493  CPXaddlazyconstraints(env, cpxlp, rcnt, nzcnt, rhs(), sense(), beg(), ind(), val(), NULL);
494  CPXsetintparam(env, CPX_PARAM_REDUCE, CPX_PREREDUCE_PRIMALONLY);
495 
496  CPXsetdblparam(env, CPX_PARAM_TILIM, maxTime);
497  CPXsetintparam(env, CPX_PARAM_CLOCKTYPE, 1);
498  CPXsetdblparam(env, CPX_PARAM_CUTUP, cutoff);
499  CPXsetdblparam(env, CPX_PARAM_EPGAP, gap_tol_);
500  cpx_->messageHandler()->setLogLevel(loglevel);
501  int status = CPXmipopt(env,cpxlp);
502  CHECK_CPX_STAT("mipopt",status)
503 
504  int stat = CPXgetstat( env, cpxlp);
505  bool infeasible = (stat == CPXMIP_INFEASIBLE) || (stat == CPXMIP_ABORT_INFEAS) || (stat == CPXMIP_TIME_LIM_INFEAS) || (stat == CPXMIP_NODE_LIM_INFEAS) || (stat == CPXMIP_FAIL_INFEAS)
506  || (stat == CPXMIP_MEM_LIM_INFEAS) || (stat == CPXMIP_INForUNBD);
507  optimal_ = (stat == CPXMIP_INFEASIBLE) || (stat == CPXMIP_OPTIMAL) || (stat == CPXMIP_OPTIMAL_TOL) || (stat == CPXMIP_INForUNBD);
508  nodeCount_ = CPXgetnodecnt(env , cpxlp);
509  iterationCount_ = CPXgetmipitcnt(env , cpxlp);
510  status = CPXgetbestobjval(env, cpxlp, &lowBound_);
511  CHECK_CPX_STAT("getbestobjval",status)
512 
513  if(!infeasible){
514  if(!integerSolution_){
515  integerSolution_ = new double[cpx_->getNumCols()];
516  }
517  CPXgetmipx(env, cpxlp, integerSolution_, 0, cpx_->getNumCols() -1);
518  CHECK_CPX_STAT("getmipx",status)
519  }
520  else {
521  if (integerSolution_) {
522  delete [] integerSolution_;
523  integerSolution_ = NULL;
524  }
525  }
526  cpx_->switchToLP();
527  CPXfreelazyconstraints(env, cpxlp);
528  CPXaddrows(env, cpxlp, 0, rcnt, nzcnt, rhs(), sense(), beg(), ind(), val(), NULL, NULL);
529  }
530  else {
531 #else
532  {
533 #endif
534  throw CoinError("Unsuported solver, for local searches you should use clp or cplex",
535  "performLocalSearch",
536  "OaDecompositionBase::SubMipSolver");
537  }
538 }
539 
541  void
542  SubMipSolver::setStrategy(CbcStrategyDefault * strategy)
543  {
544  if (strategy_) delete strategy_;
545  strategy_ = dynamic_cast<CbcStrategyDefault *>(strategy->clone());
546  assert(strategy_);
547  }
548 
550  void
552  {
553  roptions->SetRegisteringCategory("MILP Solver", RegisteredOptions::BonminCategory);
554  roptions->AddStringOption3("milp_solver",
555  "Choose the subsolver to solve MILP sub-problems in OA decompositions.",
556  "Cbc_D",
557  "Cbc_D","Coin Branch and Cut with its default",
558  "Cbc_Par", "Coin Branch and Cut with passed parameters",
559  "Cplex","IBM Cplex",
560  " To use Cplex, a valid license is required and you should have compiled OsiCpx in COIN-OR (see Osi documentation).");
561  roptions->setOptionExtraInfo("milp_solver",64);
562 
563  roptions->AddBoundedIntegerOption("cpx_parallel_strategy",
564  "Strategy of parallel search mode in CPLEX.",
565  -1, 1, 0,
566  "-1 = opportunistic, 0 = automatic, 1 = deterministic (refer to CPLEX documentation)"
567  );
568  roptions->setOptionExtraInfo("cpx_parallel_strategy",64);
569 
570  roptions->AddLowerBoundedIntegerOption("number_cpx_threads",
571  "Set number of threads to use with cplex.",
572  0, 0,
573  "(refer to CPLEX documentation)"
574  );
575  roptions->setOptionExtraInfo("number_cpx_threads",64);
576 
577 
578  roptions->AddStringOption2("milp_strategy",
579  "Choose a strategy for MILPs.",
580  "solve_to_optimality",
581  "find_good_sol","Stop sub milps when a solution improving the incumbent is found",
582  "solve_to_optimality", "Solve MILPs to optimality",
583  "");
584  roptions->setOptionExtraInfo("milp_strategy",64);
585 
586  roptions->SetRegisteringCategory("Output and Loglevel", RegisteredOptions::BonminCategory);
587  roptions->AddBoundedIntegerOption("milp_log_level",
588  "specify MILP solver log level.",
589  0,4,0,
590  "Set the level of output of the MILP subsolver in OA : "
591  "0 - none, 1 - minimal, 2 - normal low, 3 - normal high"
592  );
593  roptions->setOptionExtraInfo("milp_log_level",64);
594 
595  }
596 }/* Ends Bonmin namespace.*/
bool ownClp_
say if owns copy of clp_.
void setStrategy(CbcStrategyDefault *strategy)
Assign a strategy.
int nodeCount_
number of nodes in last mip solved.
double * integerSolution_
Has an integer solution? then it is here.
double gap_tol_
setting for gap tolerance.
A class to setup default strategy for Cbc specifying which cut generators to use. ...
bool optimal_
Is optimality proven?
void fint fint fint real fint real real real real * f
void fint fint fint real fint real real real real real real real real real * e
A very simple class to provide a common interface for solving MIPs with Cplex and Cbc...
A class to have all elements necessary to setup a branch-and-bound.
MILP_solve_strategy milp_strat_
MILP search strategy.
void fint fint fint real fint real real real real real real real real real fint real fint * lp
OsiClpSolverInterface * clp_
If lp solver is clp (then have to use Cbc) (not owned).
void fint fint fint fint fint fint fint fint fint fint real real real real real real real real * s
double lowBound_
lower bound obtained
void fint fint fint real fint real real real real real real real * r
OsiSolverInterface * solver()
int iterationCount_
number of simplex iteration in last mip solved.
static const int infeasible
Definition: Couenne.cpp:68
SubMipSolver(BabSetupBase &b, const std::string &prefix)
Constructor.
void find_good_sol(double cutoff, int loglevel, double maxTime)
update cutoff and perform a local search to a good solution.
Ipopt::SmartPtr< Ipopt::OptionsList > options()
Acces list of Options.
static char prefix[100]
Definition: BM_lp.cpp:26
static void registerOptions(Ipopt::SmartPtr< Bonmin::RegisteredOptions > roptions)
Register options for that Oa based cut generation method.
void optimize(double cutoff, int loglevel, double maxTime)
update cutoff and optimize MIP.
return b
Definition: OSdtoa.cpp:1719
void setLpSolver(OsiSolverInterface *lp)
Assign lp solver.
real infty
CbcStrategyDefault * strategy_
Strategy for solving sub mips with cbc.
void optimize_with_lazy_constraints(double cutoff, int loglevel, double maxTime, const OsiCuts &cs)
update cutoff, put OA constraints in cs as lazy constraints and optimize MIP.
OsiCpxSolverInterface * cpx_
If mip solver is cpx this is it (owned).