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

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

Change cutoff for iFP

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