source: branches/devel/Cbc/examples/strategy2.cpp @ 582

Last change on this file since 582 was 582, checked in by forrest, 13 years ago

for playing with strategy

File size: 8.3 KB
Line 
1// Copyright (C) 2007, International Business Machines
2// Corporation and others.  All Rights Reserved.
3#if defined(_MSC_VER)
4// Turn off compiler warning about long names
5#  pragma warning(disable:4786)
6#endif
7
8#include <cassert>
9#include <iomanip>
10
11
12// For Branch and bound
13#include "OsiClpSolverInterface.hpp"
14#include "CbcModel.hpp"
15#include "CbcStrategy.hpp"
16#include "CbcCutGenerator.hpp"
17#include "CoinTime.hpp"
18#include "CbcHeuristicLocal.hpp"
19#include "CbcHeuristicGreedy.hpp"
20#include "CbcHeuristicFPump.hpp"
21#include "CbcHeuristicRINS.hpp"
22
23//#############################################################################
24
25/** User class
26 */
27
28class CbcStrategyUser : public CbcStrategyDefault {
29public:
30
31  // Default Constructor
32  CbcStrategyUser (bool cutsOnlyAtRoot=true,
33                      int numberStrong=5,
34                      int numberBeforeTrust=0,
35                      int printLevel=0);
36
37  // Copy constructor
38  CbcStrategyUser ( const CbcStrategyUser &);
39   
40  // Destructor
41  ~CbcStrategyUser ();
42 
43  /// Clone
44  virtual CbcStrategy * clone() const;
45  /// Setup heuristics
46  virtual void setupHeuristics(CbcModel & model);
47
48protected:
49  // Data
50
51private:
52  /// Illegal Assignment operator
53  CbcStrategyUser & operator=(const CbcStrategyUser& rhs);
54};
55
56// Default Constructor
57CbcStrategyUser::CbcStrategyUser(bool cutsOnlyAtRoot,
58                                       int numberStrong,
59                                       int numberBeforeTrust,
60                                       int printLevel)
61  :CbcStrategyDefault(cutsOnlyAtRoot,numberStrong,
62                      numberBeforeTrust,printLevel)
63{
64}
65
66
67// Destructor
68CbcStrategyUser::~CbcStrategyUser ()
69{
70}
71
72// Clone
73CbcStrategy *
74CbcStrategyUser::clone() const
75{
76  return new CbcStrategyUser(*this);
77}
78
79// Copy constructor
80CbcStrategyUser::CbcStrategyUser(const CbcStrategyUser & rhs)
81:
82  CbcStrategyDefault(rhs)
83{
84}
85// Setup heuristics
86void 
87CbcStrategyUser::setupHeuristics(CbcModel & model)
88{
89  // FPump done first as it only works if no solution
90  int numberHeuristics = model.numberHeuristics();
91  int iHeuristic;
92  bool found;
93  found=false;
94  for (iHeuristic=0;iHeuristic<numberHeuristics;iHeuristic++) {
95    CbcHeuristic * heuristic = model.heuristic(iHeuristic);
96    CbcHeuristicFPump * cgl = dynamic_cast<CbcHeuristicFPump *>(heuristic);
97    if (cgl) {
98      found=true;
99      break;
100    }
101  }
102  if (!found) {
103    CbcHeuristicFPump heuristic(model);
104    heuristic.setMaximumPasses(20);
105    double value = model.solver()->getObjSense()*model.solver()->getObjValue();
106    // also set increment
107    heuristic.setAbsoluteIncrement(0.005*(fabs(value)+1.0e-12));
108    heuristic.setAccumulate(0);
109    heuristic.setMaximumRetries(2);
110    heuristic.setWhen(13);
111    model.addHeuristic(&heuristic);
112  }
113  // Allow CbcStrategyDefault heuristics
114  CbcStrategyDefault::setupHeuristics(model);
115
116  // Add if not there
117 
118  numberHeuristics = model.numberHeuristics();
119  found=false;
120  for (iHeuristic=0;iHeuristic<numberHeuristics;iHeuristic++) {
121    CbcHeuristic * heuristic = model.heuristic(iHeuristic);
122    CbcHeuristicLocal * cgl = dynamic_cast<CbcHeuristicLocal *>(heuristic);
123    if (cgl) {
124      found=true;
125      break;
126    }
127  }
128  if (!found) {
129    CbcHeuristicLocal heuristic(model);
130    heuristic.setSearchType(1);
131    model.addHeuristic(&heuristic);
132  }
133 
134  // Add if not there
135 
136  numberHeuristics = model.numberHeuristics();
137  found=false;
138  for (iHeuristic=0;iHeuristic<numberHeuristics;iHeuristic++) {
139    CbcHeuristic * heuristic = model.heuristic(iHeuristic);
140    CbcHeuristicGreedyCover * cgl = dynamic_cast<CbcHeuristicGreedyCover *>(heuristic);
141    if (cgl) {
142      found=true;
143      break;
144    }
145  }
146  if (!found) {
147    CbcHeuristicGreedyCover heuristic(model);
148    model.addHeuristic(&heuristic);
149  }
150 
151  // Add if not there
152 
153  numberHeuristics = model.numberHeuristics();
154  found=false;
155  for (iHeuristic=0;iHeuristic<numberHeuristics;iHeuristic++) {
156    CbcHeuristic * heuristic = model.heuristic(iHeuristic);
157    CbcHeuristicGreedyEquality * cgl = dynamic_cast<CbcHeuristicGreedyEquality *>(heuristic);
158    if (cgl) {
159      found=true;
160      break;
161    }
162  }
163  if (!found) {
164    CbcHeuristicGreedyEquality heuristic(model);
165    model.addHeuristic(&heuristic);
166  }
167 
168  // Add if not there
169 
170  numberHeuristics = model.numberHeuristics();
171  found=false;
172  for (iHeuristic=0;iHeuristic<numberHeuristics;iHeuristic++) {
173    CbcHeuristic * heuristic = model.heuristic(iHeuristic);
174    CbcHeuristicRINS * cgl = dynamic_cast<CbcHeuristicRINS *>(heuristic);
175    if (cgl) {
176      found=true;
177      break;
178    }
179  }
180  if (!found) {
181    CbcHeuristicRINS heuristic(model);
182    model.addHeuristic(&heuristic);
183  }
184}
185
186/************************************************************************
187
188This main program reads in an integer model from an mps file.
189
190It then sets up a strategy and solves a problem
191
192This inherits from CbcStrategyUser and adds in other heuristics
193************************************************************************/
194
195int main (int argc, const char *argv[])
196{
197
198  // Define your favorite OsiSolver
199 
200  OsiClpSolverInterface solver1;
201
202  // Read in model using argv[1]
203  // and assert that it is a clean model
204  std::string mpsFileName = "../../Data/Sample/p0033.mps";
205  if (argc>=2) mpsFileName = argv[1];
206  int numMpsReadErrors = solver1.readMps(mpsFileName.c_str(),"");
207  assert(numMpsReadErrors==0);
208  double time1 = CoinCpuTime();
209
210  solver1.initialSolve();
211  // Reduce printout
212  solver1.setHintParam(OsiDoReducePrint,true,OsiHintTry);
213  // See if we want preprocessing
214  OsiSolverInterface * solver2=&solver1;
215  CbcModel model(solver1);
216  // Stop after 20 minutes
217  int minutes=20;
218  std::cout<<"Stopping after "<<minutes<<" minutes"<<std::endl;
219  model.setDblParam(CbcModel::CbcMaximumSeconds,60.0*minutes);
220  ////////////////////////////////////////////////////////////
221
222  // Default strategy will leave cut generators as they exist already
223  // so cutsOnlyAtRoot (1) true
224  // numberStrong (2) is 5 (default)
225  // numberBeforeTrust (3) is 0 (default)
226  // printLevel (4) defaults (0)
227  // So same as CbcStrategyUser strategy(true,5,0,0);
228  // NO - add more cuts CbcStrategyUser strategy;
229  CbcStrategyUser strategy(false);
230  // Set up pre-processing if wanted
231  strategy.setupPreProcessing(1);
232  model.setStrategy(strategy);
233
234  ////////////////////////////////////////////////////////////
235  // Do complete search
236 
237  model.branchAndBound();
238
239  std::cout<<mpsFileName<<" took "<<CoinCpuTime()-time1<<" seconds, "
240           <<model.getNodeCount()<<" nodes with objective "
241           <<model.getObjValue()
242           <<(!model.status() ? " Finished" : " Not finished")
243           <<std::endl;
244
245  // Print more statistics
246  std::cout<<"Cuts at root node changed objective from "<<model.getContinuousObjective()
247           <<" to "<<model.rootObjectiveAfterCuts()<<std::endl;
248
249  for (int iGenerator=0;iGenerator<model.numberCutGenerators();iGenerator++) {
250    CbcCutGenerator * generator = model.cutGenerator(iGenerator);
251    std::cout<<generator->cutGeneratorName()<<" was tried "
252             <<generator->numberTimesEntered()<<" times and created "
253             <<generator->numberCutsInTotal()<<" cuts of which "
254             <<generator->numberCutsActive()<<" were active after adding rounds of cuts";
255    if (generator->timing())
256      std::cout<<" ( "<<generator->timeInCutGenerator()<<" seconds)"<<std::endl;
257    else
258      std::cout<<std::endl;
259  }
260  // Print solution if finished - we can't get names from Osi! - so get from OsiClp
261
262  if (model.getMinimizationObjValue()<1.0e50) {
263    OsiSolverInterface * solver = model.solver();
264    int numberColumns = solver->getNumCols();
265   
266    const double * solution = solver->getColSolution();
267
268    // Get names from solver1 (as OsiSolverInterface may lose)
269    std::vector<std::string> columnNames = *solver1.getModelPtr()->columnNames();
270   
271    int iColumn;
272    std::cout<<std::setiosflags(std::ios::fixed|std::ios::showpoint)<<std::setw(14);
273   
274    std::cout<<"--------------------------------------"<<std::endl;
275    for (iColumn=0;iColumn<numberColumns;iColumn++) {
276      double value=solution[iColumn];
277      if (fabs(value)>1.0e-7&&solver->isInteger(iColumn)) 
278        std::cout<<std::setw(6)<<iColumn<<" "
279                 <<columnNames[iColumn]<<" "
280                 <<value<<std::endl;
281    }
282    std::cout<<"--------------------------------------"<<std::endl;
283 
284    std::cout<<std::resetiosflags(std::ios::fixed|std::ios::showpoint|std::ios::scientific);
285  }
286  return 0;
287}   
Note: See TracBrowser for help on using the repository browser.