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

Last change on this file since 1424 was 1424, checked in by pbonami, 11 years ago

Strategy for Lp

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