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

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

changed Config.h behavior

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