source: trunk/Bonmin/src/Algorithms/BonSubMipSolver.cpp @ 1536

Last change on this file since 1536 was 1536, checked in by pbonami, 10 years ago

Port Claudia's code to trunk

File size: 9.3 KB
Line 
1// (C) Copyright International Business Machines (IBM) 2006
2// All Rights Reserved.
3// This code is published under the Common 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 "CbcModel.hpp"
14#include "CbcStrategy.hpp"
15#include "OsiAuxInfo.hpp"
16#include "OsiClpSolverInterface.hpp"
17
18#ifdef COIN_HAS_CPX
19#include "OsiCpxSolverInterface.hpp"
20
21#define CHECK_CPX_STAT(a,b) if(b) throw CoinError("Error in CPLEX call",__FILE__,a);
22
23#endif
24
25#include "BonRegisteredOptions.hpp"
26
27namespace Bonmin {
28  /** Constructor */
29  SubMipSolver::SubMipSolver(OsiSolverInterface * lp,
30      const CbcStrategy * strategy):
31      lp_(lp),
32      clp_(NULL),
33      cpx_(NULL),
34      cbc_(NULL),
35      lowBound_(-COIN_DBL_MAX),
36      optimal_(false),
37      integerSolution_(NULL),
38      strategy_(NULL)
39  {
40    clp_ = (lp_ == NULL)? NULL :
41        dynamic_cast<OsiClpSolverInterface *>(lp_);
42#ifdef COIN_HAS_CPX
43    cpx_ = (lp_ == NULL)? NULL :
44        dynamic_cast<OsiCpxSolverInterface *>(lp_);
45#endif
46    if (strategy) {
47      strategy_ = dynamic_cast<CbcStrategyDefault *>(strategy->clone());
48      assert(strategy_);
49    }
50  }
51  SubMipSolver::~SubMipSolver()
52  {
53    if (strategy_) delete strategy_;
54    if (integerSolution_) delete [] integerSolution_;
55    if (cbc_) delete cbc_;
56  }
57
58  /** Assign lp solver. */
59  void
60  SubMipSolver::setLpSolver(OsiSolverInterface * lp)
61  {
62    lp_ = lp;
63    clp_ = (lp_ == NULL) ? NULL :
64        dynamic_cast<OsiClpSolverInterface *>(lp_);
65#ifdef COIN_HAS_CPX
66    cpx_ = (lp_ == NULL) ? NULL :
67        dynamic_cast<OsiCpxSolverInterface *>(lp_);
68#endif
69    lowBound_ = -COIN_DBL_MAX;
70    optimal_ = false;
71    if (integerSolution_) {
72      delete [] integerSolution_;
73      integerSolution_ = NULL;
74    }
75  }
76
77
78 void 
79 SubMipSolver::find_good_sol(double cutoff, int loglevel, double max_time){
80
81     if(clp_){
82      CbcStrategyDefault * strat_default = NULL;
83      if (!strategy_){
84        strat_default = new CbcStrategyDefault(1,5,5, loglevel);
85        strat_default->setupPreProcessing();
86        strategy_ = strat_default;
87      }
88      OsiBabSolver empty;
89      if (cbc_) delete cbc_;
90      cbc_ = new CbcModel(*clp_);
91      cbc_->solver()->setAuxiliaryInfo(&empty);
92
93      //Change Cbc messages prefixes
94      strcpy(cbc_->messagesPointer()->source_,"OaCbc");
95
96      cbc_->setLogLevel(loglevel);
97      cbc_->solver()->messageHandler()->setLogLevel(0);
98      clp_->resolve();
99      cbc_->setStrategy(*strategy_);
100      cbc_->setLogLevel(loglevel);
101      cbc_->solver()->messageHandler()->setLogLevel(0);
102      cbc_->setMaximumSeconds(max_time);
103      cbc_->setMaximumSolutions(1);
104      cbc_->setCutoff(cutoff);
105
106      //cbc_->solver()->writeMpsNative("FP.mps", NULL, NULL, 1);
107     
108      cbc_->branchAndBound();
109      lowBound_ = cbc_->getBestPossibleObjValue();
110
111      if (cbc_->isProvenOptimal() || cbc_->isProvenInfeasible())
112        optimal_ = true;
113      else optimal_ = false;
114
115      if (cbc_->getSolutionCount()) {
116        if (!integerSolution_)
117          integerSolution_ = new double[lp_->getNumCols()];
118        CoinCopyN(cbc_->bestSolution(), lp_->getNumCols(), integerSolution_);
119      }
120      else if (integerSolution_) {
121        delete [] integerSolution_;
122        integerSolution_ = NULL;
123      }
124      nodeCount_ = cbc_->getNodeCount();
125      iterationCount_ = cbc_->getIterationCount();
126
127      if(strat_default != NULL){
128        delete strat_default;
129        strategy_ = NULL;
130      }
131     }
132     else if (cpx_){
133#ifndef COIN_HAS_CPX
134        throw CoinError("Unsuported solver, for local searches you should use clp or cplex",
135            "performLocalSearch",
136            "OaDecompositionBase::SubMipSolver");
137#else
138        CPXENVptr env = cpx_->getEnvironmentPtr();
139        CPXLPptr cpxlp = cpx_->getLpPtr(OsiCpxSolverInterface::KEEPCACHED_ALL);
140        CPXsetdblparam(env, CPX_PARAM_TILIM, max_time);
141        CPXsetdblparam(env, CPX_PARAM_CUTUP, cutoff);
142
143        CPXsetintparam(env,CPX_PARAM_INTSOLLIM, 10000);
144        CPXsetintparam(env,CPX_PARAM_NODELIM, 100000);
145        CPXsetdblparam(env,CPX_PARAM_TILIM, max_time);
146
147        cpx_->branchAndBound();
148
149        int status = CPXgetbestobjval(env, cpxlp, &lowBound_);
150     
151        int stat = CPXgetstat( env, cpxlp);
152        optimal_ |= (stat == CPXMIP_INFEASIBLE); 
153        nodeCount_ = CPXgetnodecnt(env , cpxlp);
154        iterationCount_ = CPXgetmipitcnt(env , cpxlp);
155
156        CPXsetintparam(env, CPX_PARAM_INTSOLLIM, 1);
157        CPXsetintparam(env,CPX_PARAM_NODELIM, 1000);
158        while(stat == CPXMIP_NODE_LIM_INFEAS){
159           cpx_->branchAndBound();
160           int stat = CPXgetstat( env, cpxlp);
161           optimal_ |= (stat == CPXMIP_INFEASIBLE);
162           nodeCount_ = CPXgetnodecnt(env , cpxlp);
163           iterationCount_ = CPXgetmipitcnt(env , cpxlp);
164        }
165     
166        if (status)
167          throw CoinError("Error in getting some CPLEX information",
168                          "OaDecompositionBase::SubMipSolver",
169                          "performLocalSearch");
170#endif
171    }
172  }
173
174  void
175  SubMipSolver::optimize(double cutoff, int loglevel, double maxTime)
176  {
177    if (clp_) {
178      assert(strategy_);
179      CbcStrategyDefault * strat_default = dynamic_cast<CbcStrategyDefault *>(strategy_->clone());
180      assert(strat_default);
181      strat_default->setupPreProcessing();
182
183      OsiBabSolver empty;
184      if (cbc_) delete cbc_;
185      cbc_ = new CbcModel(*clp_);
186      cbc_->solver()->setAuxiliaryInfo(&empty);
187
188      //Change Cbc messages prefixes
189      strcpy(cbc_->messagesPointer()->source_,"OaCbc");
190
191      cbc_->setLogLevel(loglevel);
192      cbc_->solver()->messageHandler()->setLogLevel(0);
193      clp_->resolve();
194      cbc_->setStrategy(*strategy_);
195      cbc_->setLogLevel(loglevel);
196      cbc_->solver()->messageHandler()->setLogLevel(0);
197      cbc_->setMaximumSeconds(maxTime);
198      cbc_->setCutoff(cutoff);
199
200      //cbc_->solver()->writeMpsNative("FP.mps", NULL, NULL, 1);
201      cbc_->branchAndBound();
202      lowBound_ = cbc_->getBestPossibleObjValue();
203
204      if (cbc_->isProvenOptimal() || cbc_->isProvenInfeasible())
205        optimal_ = true;
206      else optimal_ = false;
207
208      if (cbc_->getSolutionCount()) {
209        if (!integerSolution_)
210          integerSolution_ = new double[lp_->getNumCols()];
211        CoinCopyN(cbc_->bestSolution(), lp_->getNumCols(), integerSolution_);
212      }
213      else if (integerSolution_) {
214        delete [] integerSolution_;
215        integerSolution_ = NULL;
216      }
217      nodeCount_ = cbc_->getNodeCount();
218      iterationCount_ = cbc_->getIterationCount();
219      delete strat_default;
220    }
221    else {
222      lp_->messageHandler()->setLogLevel(loglevel);
223#ifdef COIN_HAS_CPX
224      if (cpx_) {
225        CPXENVptr env = cpx_->getEnvironmentPtr();
226        CPXsetdblparam(env, CPX_PARAM_TILIM, maxTime);
227        CPXsetdblparam(env, CPX_PARAM_CUTUP, cutoff);
228        //CpxModel = cpx_;
229      }
230      else
231#endif
232     {
233        throw CoinError("Unsuported solver, for local searches you should use clp or cplex",
234            "performLocalSearch",
235            "OaDecompositionBase::SubMipSolver");
236    }
237
238    lp_->branchAndBound();
239
240    optimal_ = lp_->isProvenOptimal();
241#ifdef COIN_HAS_CPX
242    if (cpx_) {
243      //CpxModel = NULL;
244      CPXENVptr env = cpx_->getEnvironmentPtr();
245      CPXLPptr cpxlp = cpx_->getLpPtr(OsiCpxSolverInterface::KEEPCACHED_ALL);
246
247      int status = CPXgetbestobjval(env, cpxlp, &lowBound_);
248     
249      int stat = CPXgetstat( env, cpxlp);
250      optimal_ |= (stat == CPXMIP_INFEASIBLE); 
251       nodeCount_ = CPXgetnodecnt(env , cpxlp);
252      iterationCount_ = CPXgetmipitcnt(env , cpxlp);
253      if (status)
254        throw CoinError("Error in getting some CPLEX information","OaDecompositionBase::SubMipSolver","performLocalSearch");
255    }
256#endif
257
258      if (lp_->getFractionalIndices().size() == 0) {
259        if (!integerSolution_)
260          integerSolution_ = new double[lp_->getNumCols()];
261        CoinCopyN(lp_->getColSolution(), lp_->getNumCols() , integerSolution_);
262      }
263      else if (integerSolution_) {
264        delete [] integerSolution_;
265        integerSolution_ = NULL;
266      }
267    }
268  }
269
270   /** Assign a strategy. */
271   void 
272   SubMipSolver::setStrategy(CbcStrategyDefault * strategy)
273   {
274     if (strategy_) delete strategy_;
275     strategy_ = dynamic_cast<CbcStrategyDefault *>(strategy->clone());
276     assert(strategy_);
277   }
278
279  /** Register options.*/
280  void
281  SubMipSolver::registerOptions(Ipopt::SmartPtr<Bonmin::RegisteredOptions> roptions)
282  {
283    roptions->SetRegisteringCategory("Options for MILP solver", RegisteredOptions::BonminCategory);
284    roptions->AddStringOption3("milp_solver",
285        "Choose the subsolver to solve MILP sub-problems in OA decompositions.",
286        "Cbc_D",
287        "Cbc_D","Coin Branch and Cut with its default",
288        "Cbc_Par", "Coin Branch and Cut with passed parameters",
289        "Cplex","Ilog Cplex",
290        " To use Cplex, a valid license is required and you should have compiled OsiCpx in COIN-OR  (see Osi documentation).");
291    roptions->setOptionExtraInfo("milp_solver",5);
292
293    roptions->AddBoundedIntegerOption("milp_log_level",
294        "specify MILP solver log level.",
295        0,3,0,
296        "Set the level of output of the MILP subsolver in OA : "
297        "0 - none, 1 - minimal, 2 - normal low, 3 - normal high"
298                                     );
299    roptions->setOptionExtraInfo("milp_log_level",5);
300
301
302  }
303}/* Ends Bonmin namespace.*/
Note: See TracBrowser for help on using the repository browser.