source: branches/devel/Cbc/examples/hotstart.cpp @ 425

Last change on this file since 425 was 333, checked in by andreasw, 14 years ago

finished examples subdir

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 9.2 KB
Line 
1// Copyright (C) 2005, 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 "OsiSolverInterface.hpp"
14#include "CbcModel.hpp"
15#include "CbcStrategy.hpp"
16#include "CbcBranchUser.hpp"
17#include "CbcCompareUser.hpp"
18#include "CbcCutGenerator.hpp"
19#include "OsiClpSolverInterface.hpp"
20
21// Cuts
22
23#include "CglGomory.hpp"
24#include "CglProbing.hpp"
25#include "CglKnapsackCover.hpp"
26#include "CglRedSplit.hpp"
27#include "CglClique.hpp"
28#include "CglFlowCover.hpp"
29#include "CglMixedIntegerRounding2.hpp"
30// Preprocessing
31#include "CglPreProcess.hpp"
32
33// Heuristics
34
35#include "CbcHeuristic.hpp"
36
37#include  "CoinTime.hpp"
38
39//#############################################################################
40
41
42/************************************************************************
43
44This main program reads in an integer model from an mps file.
45
46It then sets up some Cgl cut generators and calls branch and cut.
47
48Then it uses solution as hot start
49
50************************************************************************/
51
52
53int main (int argc, const char *argv[])
54{
55
56  // Define your favorite OsiSolver
57 
58  OsiClpSolverInterface solver1;
59
60  // Read in model using argv[1]
61  // and assert that it is a clean model
62  std::string mpsFileName = "../../Data/Sample/p0033.mps";
63  if (argc>=2) mpsFileName = argv[1];
64  int numMpsReadErrors = solver1.readMps(mpsFileName.c_str(),"");
65  assert(numMpsReadErrors==0);
66  double time1 = CoinCpuTime();
67
68  /* Options are:
69     preprocess to do preprocessing
70     time in minutes
71     if 2 parameters and numeric taken as time
72  */
73  bool preProcess=false;
74  double minutes=-1.0;
75  int nGoodParam=0;
76  for (int iParam=2; iParam<argc;iParam++) {
77    if (!strcmp(argv[iParam],"preprocess")) {
78      preProcess=true;
79      nGoodParam++;
80    } else if (!strcmp(argv[iParam],"time")) {
81      if (iParam+1<argc&&isdigit(argv[iParam+1][0])) {
82        minutes=atof(argv[iParam+1]);
83        if (minutes>=0.0) {
84          nGoodParam+=2;
85          iParam++; // skip time
86        }
87      }
88    }
89  }
90  if (nGoodParam==0&&argc==3&&isdigit(argv[2][0])) {
91    // If time is given then stop after that number of minutes
92    minutes = atof(argv[2]);
93    if (minutes>=0.0) 
94      nGoodParam=1;
95  }
96  if (nGoodParam!=argc-2&&argc>=2) {
97    printf("Usage <file> [preprocess] [time <minutes>] or <file> <minutes>\n");
98    exit(1);
99  }
100  //solver1.getModelPtr()->setLogLevel(0);
101  solver1.messageHandler()->setLogLevel(0);
102  solver1.initialSolve();
103  // Reduce printout
104  solver1.setHintParam(OsiDoReducePrint,true,OsiHintTry);
105  CbcModel model(solver1);
106  model.solver()->setHintParam(OsiDoReducePrint,true,OsiHintTry);
107  // Set up some cut generators and defaults
108  // Probing first as gets tight bounds on continuous
109
110  CglProbing generator1;
111  generator1.setUsingObjective(true);
112  generator1.setMaxPass(1);
113  generator1.setMaxPassRoot(5);
114  // Number of unsatisfied variables to look at
115  generator1.setMaxProbe(10);
116  generator1.setMaxProbeRoot(1000);
117  // How far to follow the consequences
118  generator1.setMaxLook(50);
119  generator1.setMaxLookRoot(500);
120  // Only look at rows with fewer than this number of elements
121  generator1.setMaxElements(200);
122  generator1.setRowCuts(3);
123
124  CglGomory generator2;
125  // try larger limit
126  generator2.setLimit(300);
127
128  CglKnapsackCover generator3;
129
130  CglRedSplit generator4;
131  // try larger limit
132  generator4.setLimit(200);
133
134  CglClique generator5;
135  generator5.setStarCliqueReport(false);
136  generator5.setRowCliqueReport(false);
137
138  CglMixedIntegerRounding2 mixedGen;
139  CglFlowCover flowGen;
140 
141  // Add in generators
142  // Experiment with -1 and -99 etc
143  model.addCutGenerator(&generator1,-1,"Probing");
144  model.addCutGenerator(&generator2,-1,"Gomory");
145  model.addCutGenerator(&generator3,-1,"Knapsack");
146  // model.addCutGenerator(&generator4,-1,"RedSplit");
147  model.addCutGenerator(&generator5,-1,"Clique");
148  model.addCutGenerator(&flowGen,-1,"FlowCover");
149  model.addCutGenerator(&mixedGen,-1,"MixedIntegerRounding");
150  OsiClpSolverInterface * osiclp = dynamic_cast< OsiClpSolverInterface*> (model.solver());
151  // go faster stripes
152  if (osiclp) {
153    // Turn this off if you get problems
154    // Used to be automatically set
155    osiclp->setSpecialOptions(128);
156    if(osiclp->getNumRows()<300&&osiclp->getNumCols()<500) {
157      //osiclp->setupForRepeatedUse(2,1);
158      osiclp->setupForRepeatedUse(0,1);
159    }
160  } 
161  // Uncommenting this should switch off most CBC messages
162  //model.messagesPointer()->setDetailMessages(10,5,5000);
163  // Allow rounding heuristic
164
165  CbcRounding heuristic1(model);
166  model.addHeuristic(&heuristic1);
167
168  // Redundant definition of default branching (as Default == User)
169  CbcBranchUserDecision branch;
170  model.setBranchingMethod(&branch);
171
172  // Definition of node choice
173  CbcCompareUser compare;
174  model.setNodeComparison(compare);
175
176  // Do initial solve to continuous
177  model.initialSolve();
178
179  // Could tune more
180  double objValue = model.solver()->getObjSense()*model.solver()->getObjValue();
181  double minimumDropA=CoinMin(1.0,fabs(objValue)*1.0e-3+1.0e-4);
182  double minimumDrop= fabs(objValue)*1.0e-4+1.0e-4;
183  printf("min drop %g (A %g)\n",minimumDrop,minimumDropA);
184  model.setMinimumDrop(minimumDrop);
185
186  if (model.getNumCols()<500)
187    model.setMaximumCutPassesAtRoot(-100); // always do 100 if possible
188  else if (model.getNumCols()<5000)
189    model.setMaximumCutPassesAtRoot(100); // use minimum drop
190  else
191    model.setMaximumCutPassesAtRoot(20);
192  model.setMaximumCutPasses(10);
193  //model.setMaximumCutPasses(2);
194
195  // Switch off strong branching if wanted
196  // model.setNumberStrong(0);
197  // Do more strong branching if small
198  if (model.getNumCols()<5000)
199    model.setNumberStrong(10);
200  model.setNumberStrong(20);
201  //model.setNumberStrong(5);
202  model.setNumberBeforeTrust(5);
203  //model.setSizeMiniTree(2);
204
205  model.solver()->setIntParam(OsiMaxNumIterationHotStart,100);
206
207  // Switch off most output
208  if (model.getNumCols()<3000) {
209    model.messageHandler()->setLogLevel(1);
210    //model.solver()->messageHandler()->setLogLevel(0);
211  } else {
212    model.messageHandler()->setLogLevel(2);
213    model.solver()->messageHandler()->setLogLevel(1);
214  }
215  model.messageHandler()->setLogLevel(6);
216  model.solver()->messageHandler()->setLogLevel(1);
217  // If time is given then stop after that number of minutes
218  if (minutes>=0.0) {
219    std::cout<<"Stopping after "<<minutes<<" minutes"<<std::endl;
220    model.setDblParam(CbcModel::CbcMaximumSeconds,60.0*minutes);
221  }
222  // Default strategy will leave cut generators as they exist already
223  // so cutsOnlyAtRoot (1) ignored
224  // numberStrong (2) is 5 (default)
225  // numberBeforeTrust (3) is 5 (default is 0)
226  // printLevel (4) defaults (0)
227  CbcStrategyDefault strategy(true,5,5);
228  // Set up pre-processing to find sos if wanted
229  if (preProcess)
230    strategy.setupPreProcessing(2);
231  model.setStrategy(strategy);
232  int numberColumns = model.solver()->getNumCols();
233  double * bestSolution=NULL;
234  int * priority = new int[numberColumns];
235  // Do two passes
236  for (int iPass=0;iPass<2;iPass++) {
237    time1 = CoinCpuTime();
238    // Do hot start on second pass
239    if (bestSolution) {
240      model.setHotstartSolution(bestSolution,priority);
241      delete [] bestSolution;
242      bestSolution=NULL;
243      delete [] priority;
244      model.setMaximumNodes(40000);
245    } else {
246      model.setMaximumNodes(40000);
247    }
248    // Do complete search
249    model.branchAndBound();
250   
251    std::cout<<mpsFileName<<" took "<<CoinCpuTime()-time1<<" seconds, "
252             <<model.getNodeCount()<<" nodes with objective "
253             <<model.getObjValue()
254             <<(!model.status() ? " Finished" : " Not finished")
255             <<std::endl;
256    // Print solution if finished - we can't get names from Osi! - so get from OsiClp
257   
258    assert (model.getMinimizationObjValue()<1.0e50);
259    OsiSolverInterface * solver = model.solver();
260    int numberColumns = solver->getNumCols();
261   
262    const double * solution = solver->getColSolution();
263    // save solution
264    if (!iPass) {
265      bestSolution = CoinCopyOfArray(solution,numberColumns);
266      for (int i=0;i<numberColumns;i++) {
267        if (solution[i]>0.5)
268          priority[i]=-1;
269        else
270          priority[i]=2;
271      }
272    }
273    //const double * lower = solver->getColLower();
274    //const double * upper = solver->getColUpper();
275
276    // Get names from solver1 (as OsiSolverInterface may lose)
277    std::vector<std::string> columnNames = *solver1.getModelPtr()->columnNames();
278   
279    int iColumn;
280    std::cout<<std::setiosflags(std::ios::fixed|std::ios::showpoint)<<std::setw(14);
281   
282    std::cout<<"--------------------------------------"<<std::endl;
283    for (iColumn=0;iColumn<numberColumns;iColumn++) {
284      double value=solution[iColumn];
285      if (fabs(value)>1.0e-7&&solver->isInteger(iColumn)) 
286        std::cout<<std::setw(6)<<iColumn<<" "
287                 <<columnNames[iColumn]<<" "
288                 <<value
289          //<<" "<<lower[iColumn]<<" "<<upper[iColumn]
290                 <<std::endl;
291    }
292    std::cout<<"--------------------------------------"<<std::endl;
293 
294    std::cout<<std::resetiosflags(std::ios::fixed|std::ios::showpoint|std::ios::scientific);
295    model.resetToReferenceSolver();
296  }
297  return 0;
298}   
Note: See TracBrowser for help on using the repository browser.