source: trunk/Cbc/src/CbcStrategy.cpp @ 310

Last change on this file since 310 was 310, checked in by andreasw, 13 years ago

first commit for autotools conversion to be able to move more files

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 22.3 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#include <cassert>
8#include <cmath>
9#include <cfloat>
10
11#include "OsiSolverInterface.hpp"
12#ifdef CBC_USE_CLP
13#include "OsiClpSolverInterface.hpp"
14#endif
15#include "CbcModel.hpp"
16#include "CbcMessage.hpp"
17#include "CbcStrategy.hpp"
18#include "CbcCutGenerator.hpp"
19#include "CbcBranchActual.hpp"
20#include "CbcNode.hpp"
21#include "CoinWarmStart.hpp"
22#include "CglPreProcess.hpp"
23// Cuts
24
25#include "CglGomory.hpp"
26#include "CglProbing.hpp"
27#include "CglKnapsackCover.hpp"
28#include "CglOddHole.hpp"
29#include "CglClique.hpp"
30#include "CglFlowCover.hpp"
31#include "CglMixedIntegerRounding2.hpp"
32
33// Heuristics
34
35#include "CbcHeuristic.hpp"
36
37// Default Constructor
38CbcStrategy::CbcStrategy() 
39  :depth_(0),
40   preProcessState_(0),
41   process_(NULL)
42{
43}
44
45// Destructor
46CbcStrategy::~CbcStrategy ()
47{
48  delete process_;
49}
50// Delete pre-processing object to save memory
51void 
52CbcStrategy::deletePreProcess()
53{ 
54  delete process_;
55  process_=NULL;
56}
57// Return a new Full node information pointer (descendant of CbcFullNodeInfo)
58CbcNodeInfo * 
59CbcStrategy::fullNodeInfo(CbcModel * model,int numberRowsAtContinuous) const
60{
61  return new CbcFullNodeInfo(model,numberRowsAtContinuous);
62}
63// Return a new Partial node information pointer (descendant of CbcPartialNodeInfo)
64CbcNodeInfo * 
65CbcStrategy::partialNodeInfo(CbcModel * model, CbcNodeInfo * parent, CbcNode * owner,
66                             int numberChangedBounds,const int * variables,
67                             const double * boundChanges,
68                             const CoinWarmStartDiff *basisDiff) const
69{
70  return new CbcPartialNodeInfo(parent, owner, numberChangedBounds, variables,
71                            boundChanges,basisDiff);
72}
73/* After a CbcModel::resolve this can return a status
74   -1 no effect
75   0 treat as optimal
76   1 as 0 but do not do any more resolves (i.e. no more cuts)
77   2 treat as infeasible
78*/
79int
80CbcStrategy::status(CbcModel * model, CbcNodeInfo * parent,int whereFrom)
81{
82  return -1;
83}
84
85// Default Constructor
86CbcStrategyDefault::CbcStrategyDefault(bool cutsOnlyAtRoot,
87                                       int numberStrong,
88                                       int numberBeforeTrust,
89                                       int printLevel)
90  :CbcStrategy(),
91   cutsOnlyAtRoot_(cutsOnlyAtRoot),
92   numberStrong_(numberStrong),
93   numberBeforeTrust_(numberBeforeTrust),
94   printLevel_(printLevel),
95   desiredPreProcess_(0),
96   preProcessPasses_(0)
97{
98}
99
100
101// Destructor
102CbcStrategyDefault::~CbcStrategyDefault ()
103{
104}
105
106// Clone
107CbcStrategy *
108CbcStrategyDefault::clone() const
109{
110  return new CbcStrategyDefault(*this);
111}
112
113// Copy constructor
114CbcStrategyDefault::CbcStrategyDefault(const CbcStrategyDefault & rhs)
115:
116  CbcStrategy(rhs),
117  cutsOnlyAtRoot_(rhs.cutsOnlyAtRoot_),
118  numberStrong_(rhs.numberStrong_),
119  numberBeforeTrust_(rhs.numberBeforeTrust_),
120  printLevel_(rhs.printLevel_),
121  desiredPreProcess_(rhs.desiredPreProcess_),
122  preProcessPasses_(rhs.preProcessPasses_)
123{
124  setNested(rhs.getNested());
125}
126
127// Setup cut generators
128void 
129CbcStrategyDefault::setupCutGenerators(CbcModel & model)
130{
131  // Set up some cut generators and defaults
132  // Probing first as gets tight bounds on continuous
133
134  CglProbing generator1;
135  generator1.setUsingObjective(true);
136  generator1.setMaxPass(1);
137  // Number of unsatisfied variables to look at
138  generator1.setMaxProbe(10);
139  // How far to follow the consequences
140  generator1.setMaxLook(10);
141  // Only look at rows with fewer than this number of elements
142  generator1.setMaxElements(200);
143  //generator1.setRowCuts(3);
144
145  CglGomory generator2;
146  // try larger limit
147  generator2.setLimit(300);
148
149  CglKnapsackCover generator3;
150
151  //CglOddHole generator4;
152  //generator4.setMinimumViolation(0.005);
153  //generator4.setMinimumViolationPer(0.00002);
154  // try larger limit
155  //generator4.setMaximumEntries(200);
156
157  CglClique generator5;
158  generator5.setStarCliqueReport(false);
159  generator5.setRowCliqueReport(false);
160
161  CglMixedIntegerRounding2 mixedGen;
162  CglFlowCover flowGen;
163 
164  // Add in generators
165  int setting = cutsOnlyAtRoot_ ? -99 : -1;
166  int numberGenerators = model.numberCutGenerators();
167  int iGenerator;
168  bool found;
169  found=false;
170  for (iGenerator=0;iGenerator<numberGenerators;iGenerator++) {
171    CglCutGenerator * generator = model.cutGenerator(iGenerator)->generator();
172    CglProbing * cgl = dynamic_cast<CglProbing *>(generator);
173    if (cgl) {
174      found=true;
175      break;
176    }
177  }
178  if (!found)
179    model.addCutGenerator(&generator1,setting,"Probing");
180  found=false;
181  for (iGenerator=0;iGenerator<numberGenerators;iGenerator++) {
182    CglCutGenerator * generator = model.cutGenerator(iGenerator)->generator();
183    CglGomory * cgl = dynamic_cast<CglGomory *>(generator);
184    if (cgl) {
185      found=true;
186      break;
187    }
188  }
189  if (!found)
190  model.addCutGenerator(&generator2,setting,"Gomory");
191  found=false;
192  for (iGenerator=0;iGenerator<numberGenerators;iGenerator++) {
193    CglCutGenerator * generator = model.cutGenerator(iGenerator)->generator();
194    CglKnapsackCover * cgl = dynamic_cast<CglKnapsackCover *>(generator);
195    if (cgl) {
196      found=true;
197      break;
198    }
199  }
200  if (!found)
201    model.addCutGenerator(&generator3,setting,"Knapsack");
202  //model.addCutGenerator(&generator4,setting,"OddHole");
203  found=false;
204  for (iGenerator=0;iGenerator<numberGenerators;iGenerator++) {
205    CglCutGenerator * generator = model.cutGenerator(iGenerator)->generator();
206    CglClique * cgl = dynamic_cast<CglClique *>(generator);
207    if (cgl) {
208      found=true;
209      break;
210    }
211  }
212  if (!found)
213    model.addCutGenerator(&generator5,setting,"Clique");
214  found=false;
215  for (iGenerator=0;iGenerator<numberGenerators;iGenerator++) {
216    CglCutGenerator * generator = model.cutGenerator(iGenerator)->generator();
217    CglFlowCover * cgl = dynamic_cast<CglFlowCover *>(generator);
218    if (cgl) {
219      found=true;
220      break;
221    }
222  }
223  if (!found)
224    model.addCutGenerator(&flowGen,setting,"FlowCover");
225  found=false;
226  for (iGenerator=0;iGenerator<numberGenerators;iGenerator++) {
227    CglCutGenerator * generator = model.cutGenerator(iGenerator)->generator();
228    CglMixedIntegerRounding2 * cgl = dynamic_cast<CglMixedIntegerRounding2 *>(generator);
229    if (cgl) {
230      found=true;
231      break;
232    }
233  }
234  if (!found)
235    model.addCutGenerator(&mixedGen,setting,"MixedIntegerRounding2");
236  // Say we want timings
237  int newNumberGenerators = model.numberCutGenerators();
238  for (iGenerator=numberGenerators;iGenerator<newNumberGenerators;iGenerator++) {
239    CbcCutGenerator * generator = model.cutGenerator(iGenerator);
240    generator->setTiming(true);
241  }
242  if (model.getNumCols()<500)
243    model.setMaximumCutPassesAtRoot(-100); // always do 100 if possible
244  else if (model.getNumCols()<5000)
245    model.setMaximumCutPassesAtRoot(100); // use minimum drop
246  else
247    model.setMaximumCutPassesAtRoot(20);
248}
249// Setup heuristics
250void 
251CbcStrategyDefault::setupHeuristics(CbcModel & model)
252{
253  // Allow rounding heuristic
254
255  CbcRounding heuristic1(model);
256  int numberHeuristics = model.numberHeuristics();
257  int iHeuristic;
258  bool found;
259  found=false;
260  for (iHeuristic=0;iHeuristic<numberHeuristics;iHeuristic++) {
261    CbcHeuristic * heuristic = model.heuristic(iHeuristic);
262    CbcRounding * cgl = dynamic_cast<CbcRounding *>(heuristic);
263    if (cgl) {
264      found=true;
265      break;
266    }
267  }
268  if (!found)
269    model.addHeuristic(&heuristic1);
270}
271// Do printing stuff
272void 
273CbcStrategyDefault::setupPrinting(CbcModel & model,int modelLogLevel)
274{
275  if (!modelLogLevel) {
276    model.solver()->setHintParam(OsiDoReducePrint,true,OsiHintTry);
277    model.messageHandler()->setLogLevel(0);
278    model.solver()->messageHandler()->setLogLevel(0);
279  } else if (modelLogLevel==1) {
280    model.solver()->setHintParam(OsiDoReducePrint,true,OsiHintTry);
281    model.messageHandler()->setLogLevel(1);
282    model.solver()->messageHandler()->setLogLevel(0);
283  } else {
284    model.messageHandler()->setLogLevel(2);
285    model.solver()->messageHandler()->setLogLevel(1);
286    model.setPrintFrequency(50);
287  }
288}
289// Other stuff e.g. strong branching
290void 
291CbcStrategyDefault::setupOther(CbcModel & model)
292{
293  // See if preprocessing wanted
294  if (desiredPreProcess_) {
295    delete process_;
296    // solver_ should have been cloned outside
297    CglPreProcess * process = new CglPreProcess();
298    OsiSolverInterface * solver = model.solver();
299    int logLevel = model.messageHandler()->logLevel();
300#ifdef CBC_USE_CLP
301    OsiClpSolverInterface * clpSolver = dynamic_cast< OsiClpSolverInterface*> (solver);
302    ClpSimplex * lpSolver=NULL;
303    if (clpSolver) {
304      if (clpSolver->messageHandler()->logLevel())
305        clpSolver->messageHandler()->setLogLevel(1);
306      if (logLevel>-1)
307        clpSolver->messageHandler()->setLogLevel(CoinMin(logLevel,clpSolver->messageHandler()->logLevel()));
308      lpSolver = clpSolver->getModelPtr();
309      /// If user left factorization frequency then compute
310      lpSolver->defaultFactorizationFrequency();
311    }
312#endif
313    // Tell solver we are in Branch and Cut
314    solver->setHintParam(OsiDoInBranchAndCut,true,OsiHintDo) ;
315    // Default set of cut generators
316    CglProbing generator1;
317    generator1.setUsingObjective(true);
318    generator1.setMaxPass(3);
319    generator1.setMaxProbeRoot(solver->getNumCols());
320    generator1.setMaxElements(100);
321    generator1.setMaxLookRoot(50);
322    generator1.setRowCuts(3);
323    //generator1.messageHandler()->setLogLevel(logLevel);
324    process->messageHandler()->setLogLevel(logLevel);
325    // Add in generators
326    process->addCutGenerator(&generator1);
327    int translate[]={9999,0,2,3};
328    OsiSolverInterface * solver2 = 
329      process->preProcessNonDefault(*solver,
330                                    translate[desiredPreProcess_],preProcessPasses_);
331    // Tell solver we are not in Branch and Cut
332    solver->setHintParam(OsiDoInBranchAndCut,false,OsiHintDo) ;
333    if (solver2)
334      solver2->setHintParam(OsiDoInBranchAndCut,false,OsiHintDo) ;
335    bool feasible=true;
336    if (!solver2) {
337      feasible = false;
338      //printf("Pre-processing says infeasible\n");
339      delete process;
340      preProcessState_=-1;
341      process_=NULL;
342    } else {
343      // now tighten bounds
344#ifdef CBC_USE_CLP
345      if (clpSolver) {
346        // model has changed
347        solver = model.solver();
348        OsiClpSolverInterface * clpSolver = dynamic_cast< OsiClpSolverInterface*> (solver);
349        ClpSimplex * lpSolver = clpSolver->getModelPtr();
350        if (lpSolver->tightenPrimalBounds()==0) {
351          lpSolver->dual();
352        } else {
353          feasible = false;
354        }
355      }
356#endif
357      if (feasible) {
358        preProcessState_=1;
359        process_=process;
360        /* Note that original solver will be kept (with false)
361           and that final solver will also be kept.
362           This is for post-processing
363        */
364        OsiSolverInterface * solver3 = solver2->clone();
365        model.assignSolver(solver3,false);
366        if (process_->numberSOS()) {
367          int numberSOS = process_->numberSOS();
368          int numberIntegers = model.numberIntegers();
369          /* model may not have created objects
370             If none then create
371             NOTE - put back to original column numbers as
372             CbcModel will pack down ALL as it doesn't know where from
373          */
374          bool someObjects = model.numberObjects()>0;
375          if (!numberIntegers||!model.numberObjects()) {
376            model.findIntegers(true);
377            numberIntegers = model.numberIntegers();
378          }
379          CbcObject ** oldObjects = model.objects();
380          // Do sets and priorities
381          CbcObject ** objects = new CbcObject * [numberSOS];
382          // set old objects to have low priority
383          int numberOldObjects = model.numberObjects();
384          int numberColumns = model.getNumCols();
385          for (int iObj = 0;iObj<numberOldObjects;iObj++) {
386            int oldPriority = oldObjects[iObj]->priority();
387            oldObjects[iObj]->setPriority(numberColumns+oldPriority);
388          }
389          const int * starts = process_->startSOS();
390          const int * which = process_->whichSOS();
391          const int * type = process_->typeSOS();
392          const double * weight = process_->weightSOS();
393          int iSOS;
394          for (iSOS =0;iSOS<numberSOS;iSOS++) {
395            int iStart = starts[iSOS];
396            int n=starts[iSOS+1]-iStart;
397            objects[iSOS] = new CbcSOS(&model,n,which+iStart,weight+iStart,
398                                       iSOS,type[iSOS]);
399            // branch on long sets first
400            objects[iSOS]->setPriority(numberColumns-n);
401          }
402          model.addObjects(numberSOS,objects);
403          for (iSOS=0;iSOS<numberSOS;iSOS++)
404            delete objects[iSOS];
405          delete [] objects;
406          if (!someObjects) {
407            // put back old column numbers
408            const int * originalColumns = process_->originalColumns();
409            // use reverse lookup to fake it
410            int n=originalColumns[numberColumns-1]+1;
411            int * fake = new int[n];
412            int i;
413            for ( i=0;i<n;i++)
414              fake[i]=-1;
415            for (i=0;i<numberColumns;i++)
416              fake[originalColumns[i]]=i;
417            for (int iObject=0;iObject<model.numberObjects();iObject++) {
418              // redo ids etc
419              model.modifiableObject(iObject)->redoSequenceEtc(&model,n,fake);
420            }
421            delete [] fake;
422          }
423        }
424      } else {
425        //printf("Pre-processing says infeasible\n");
426        delete process;
427        preProcessState_=-1;
428        process_=NULL;
429      }
430    }
431  }
432  model.setNumberStrong(numberStrong_);
433  model.setNumberBeforeTrust(numberBeforeTrust_);
434}
435// Default Constructor
436CbcStrategyDefaultSubTree::CbcStrategyDefaultSubTree(CbcModel * parent ,
437                                                     bool cutsOnlyAtRoot,
438                                       int numberStrong,
439                                       int numberBeforeTrust,
440                                       int printLevel)
441  :CbcStrategy(),
442   parentModel_(parent),
443   cutsOnlyAtRoot_(cutsOnlyAtRoot),
444   numberStrong_(numberStrong),
445   numberBeforeTrust_(numberBeforeTrust),
446   printLevel_(printLevel)
447{
448}
449
450
451// Destructor
452CbcStrategyDefaultSubTree::~CbcStrategyDefaultSubTree ()
453{
454}
455
456// Clone
457CbcStrategy *
458CbcStrategyDefaultSubTree::clone() const
459{
460  return new CbcStrategyDefaultSubTree(*this);
461}
462
463// Copy constructor
464CbcStrategyDefaultSubTree::CbcStrategyDefaultSubTree(const CbcStrategyDefaultSubTree & rhs)
465:
466  CbcStrategy(rhs),
467  parentModel_(rhs.parentModel_),
468  cutsOnlyAtRoot_(rhs.cutsOnlyAtRoot_),
469  numberStrong_(rhs.numberStrong_),
470  numberBeforeTrust_(rhs.numberBeforeTrust_),
471  printLevel_(rhs.printLevel_)
472{
473  setNested(rhs.getNested());
474}
475
476// Setup cut generators
477void 
478CbcStrategyDefaultSubTree::setupCutGenerators(CbcModel & model)
479{
480  // Set up some cut generators and defaults
481  // Probing first as gets tight bounds on continuous
482
483  CglProbing generator1;
484  generator1.setUsingObjective(true);
485  generator1.setMaxPass(1);
486  // Number of unsatisfied variables to look at
487  generator1.setMaxProbe(10);
488  // How far to follow the consequences
489  generator1.setMaxLook(10);
490  // Only look at rows with fewer than this number of elements
491  generator1.setMaxElements(200);
492  //generator1.setRowCuts(3);
493
494  CglGomory generator2;
495  // try larger limit
496  generator2.setLimit(300);
497
498  CglKnapsackCover generator3;
499
500  //CglOddHole generator4;
501  //generator4.setMinimumViolation(0.005);
502  //generator4.setMinimumViolationPer(0.00002);
503  // try larger limit
504  //generator4.setMaximumEntries(200);
505
506  CglClique generator5;
507  generator5.setStarCliqueReport(false);
508  generator5.setRowCliqueReport(false);
509
510  CglMixedIntegerRounding2 mixedGen;
511  CglFlowCover flowGen;
512 
513  // Add in generators
514  int setting = cutsOnlyAtRoot_ ? -99 : -1;
515  int numberGenerators = model.numberCutGenerators();
516  int numberParentGenerators = parentModel_->numberCutGenerators();
517  int iGenerator;
518  bool found;
519  found=false;
520  int howOften=0;
521  for (iGenerator=0;iGenerator<numberParentGenerators;iGenerator++) {
522    CglCutGenerator * generator = parentModel_->cutGenerator(iGenerator)->generator();
523    CglProbing * cgl = dynamic_cast<CglProbing *>(generator);
524    if (cgl) {
525      found=true;
526      howOften = parentModel_->cutGenerator(iGenerator)->howOften();
527      break;
528    }
529  }
530  if (found&&howOften>=0) {
531    found=false;
532    for (iGenerator=0;iGenerator<numberGenerators;iGenerator++) {
533      CglCutGenerator * generator = model.cutGenerator(iGenerator)->generator();
534      CglProbing * cgl = dynamic_cast<CglProbing *>(generator);
535      if (cgl) {
536        found=true;
537        break;
538      }
539    }
540    if (!found)
541      model.addCutGenerator(&generator1,setting,"Probing");
542  }
543  found=false;
544  for (iGenerator=0;iGenerator<numberParentGenerators;iGenerator++) {
545    CglCutGenerator * generator = parentModel_->cutGenerator(iGenerator)->generator();
546    CglGomory * cgl = dynamic_cast<CglGomory *>(generator);
547    if (cgl) {
548      found=true;
549      howOften = parentModel_->cutGenerator(iGenerator)->howOften();
550      break;
551    }
552  }
553  if (found&&howOften>=0) {
554    found=false;
555    for (iGenerator=0;iGenerator<numberGenerators;iGenerator++) {
556      CglCutGenerator * generator = model.cutGenerator(iGenerator)->generator();
557      CglGomory * cgl = dynamic_cast<CglGomory *>(generator);
558      if (cgl) {
559        found=true;
560        break;
561      }
562    }
563    if (!found)
564      model.addCutGenerator(&generator2,setting,"Gomory");
565  }
566  found=false;
567  for (iGenerator=0;iGenerator<numberParentGenerators;iGenerator++) {
568    CglCutGenerator * generator = parentModel_->cutGenerator(iGenerator)->generator();
569    CglKnapsackCover * cgl = dynamic_cast<CglKnapsackCover *>(generator);
570    if (cgl) {
571      found=true;
572      howOften = parentModel_->cutGenerator(iGenerator)->howOften();
573      break;
574    }
575  }
576  if (found&&howOften>=0) {
577    found=false;
578    for (iGenerator=0;iGenerator<numberGenerators;iGenerator++) {
579      CglCutGenerator * generator = model.cutGenerator(iGenerator)->generator();
580      CglKnapsackCover * cgl = dynamic_cast<CglKnapsackCover *>(generator);
581      if (cgl) {
582        found=true;
583        break;
584      }
585    }
586    if (!found)
587      model.addCutGenerator(&generator3,setting,"Knapsack");
588  }
589  found=false;
590  for (iGenerator=0;iGenerator<numberParentGenerators;iGenerator++) {
591    CglCutGenerator * generator = parentModel_->cutGenerator(iGenerator)->generator();
592    CglClique * cgl = dynamic_cast<CglClique *>(generator);
593    if (cgl) {
594      found=true;
595      howOften = parentModel_->cutGenerator(iGenerator)->howOften();
596      break;
597    }
598  }
599  if (found&&howOften>=0) {
600    found=false;
601    for (iGenerator=0;iGenerator<numberGenerators;iGenerator++) {
602      CglCutGenerator * generator = model.cutGenerator(iGenerator)->generator();
603      CglClique * cgl = dynamic_cast<CglClique *>(generator);
604      if (cgl) {
605        found=true;
606        break;
607      }
608    }
609    if (!found)
610      model.addCutGenerator(&generator5,setting,"Clique");
611  }
612  found=false;
613  for (iGenerator=0;iGenerator<numberParentGenerators;iGenerator++) {
614    CglCutGenerator * generator = parentModel_->cutGenerator(iGenerator)->generator();
615    CglFlowCover * cgl = dynamic_cast<CglFlowCover *>(generator);
616    if (cgl) {
617      found=true;
618      howOften = parentModel_->cutGenerator(iGenerator)->howOften();
619      break;
620    }
621  }
622  if (found&&howOften>=0) {
623    found=false;
624    for (iGenerator=0;iGenerator<numberGenerators;iGenerator++) {
625      CglCutGenerator * generator = model.cutGenerator(iGenerator)->generator();
626      CglFlowCover * cgl = dynamic_cast<CglFlowCover *>(generator);
627      if (cgl) {
628        found=true;
629        break;
630      }
631    }
632    if (!found)
633      model.addCutGenerator(&flowGen,setting,"FlowCover");
634    found=false;
635  }
636  for (iGenerator=0;iGenerator<numberParentGenerators;iGenerator++) {
637    CglCutGenerator * generator = parentModel_->cutGenerator(iGenerator)->generator();
638    CglMixedIntegerRounding2 * cgl = dynamic_cast<CglMixedIntegerRounding2 *>(generator);
639    if (cgl) {
640      found=true;
641      howOften = parentModel_->cutGenerator(iGenerator)->howOften();
642      break;
643    }
644  }
645  if (found&&howOften>=0) {
646    found=false;
647    for (iGenerator=0;iGenerator<numberGenerators;iGenerator++) {
648      CglCutGenerator * generator = model.cutGenerator(iGenerator)->generator();
649      CglMixedIntegerRounding2 * cgl = dynamic_cast<CglMixedIntegerRounding2 *>(generator);
650      if (cgl) {
651        found=true;
652        break;
653      }
654    }
655    if (!found)
656      model.addCutGenerator(&mixedGen,setting,"MixedIntegerRounding2");
657  }
658#if 0
659  // Say we want timings
660  int newNumberGenerators = model.numberCutGenerators();
661  for (iGenerator=numberGenerators;iGenerator<newNumberGenerators;iGenerator++) {
662    CbcCutGenerator * generator = model.cutGenerator(iGenerator);
663    generator->setTiming(true);
664  }
665#endif
666  if (model.getNumCols()<500)
667    model.setMaximumCutPassesAtRoot(-100); // always do 100 if possible
668  else if (model.getNumCols()<5000)
669    model.setMaximumCutPassesAtRoot(100); // use minimum drop
670  else
671    model.setMaximumCutPassesAtRoot(20);
672}
673// Setup heuristics
674void 
675CbcStrategyDefaultSubTree::setupHeuristics(CbcModel & model)
676{
677  // Allow rounding heuristic
678
679  CbcRounding heuristic1(model);
680  int numberHeuristics = model.numberHeuristics();
681  int iHeuristic;
682  bool found;
683  found=false;
684  for (iHeuristic=0;iHeuristic<numberHeuristics;iHeuristic++) {
685    CbcHeuristic * heuristic = model.heuristic(iHeuristic);
686    CbcRounding * cgl = dynamic_cast<CbcRounding *>(heuristic);
687    if (cgl) {
688      found=true;
689      break;
690    }
691  }
692  if (!found)
693    model.addHeuristic(&heuristic1);
694}
695// Do printing stuff
696void 
697CbcStrategyDefaultSubTree::setupPrinting(CbcModel & model,int modelLogLevel)
698{
699  if (!modelLogLevel) {
700    model.solver()->setHintParam(OsiDoReducePrint,true,OsiHintTry);
701    model.messageHandler()->setLogLevel(0);
702    model.solver()->messageHandler()->setLogLevel(0);
703  } else if (modelLogLevel==1) {
704    model.solver()->setHintParam(OsiDoReducePrint,true,OsiHintTry);
705    model.messageHandler()->setLogLevel(1);
706    model.solver()->messageHandler()->setLogLevel(0);
707  } else {
708    model.messageHandler()->setLogLevel(2);
709    model.solver()->messageHandler()->setLogLevel(1);
710    model.setPrintFrequency(50);
711  }
712}
713// Other stuff e.g. strong branching
714void 
715CbcStrategyDefaultSubTree::setupOther(CbcModel & model)
716{
717  model.setNumberStrong(numberStrong_);
718  model.setNumberBeforeTrust(numberBeforeTrust_);
719}
720
721
722 
Note: See TracBrowser for help on using the repository browser.