source: branches/devel/Cbc/src/CbcStrategy.cpp @ 545

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

for nonlinear

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 23.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(CoinMax(2,model.messageHandler()->logLevel()));
288    model.solver()->messageHandler()->setLogLevel(CoinMax(1,model.solver()->messageHandler()->logLevel()));
289    model.setPrintFrequency(CoinMin(50,model.printFrequency()));
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    // Pass in models message handler
302    process->passInMessageHandler(model.messageHandler());
303    OsiSolverInterface * solver = model.solver();
304    int logLevel = model.messageHandler()->logLevel();
305#ifdef COIN_HAS_CLP
306    OsiClpSolverInterface * clpSolver = dynamic_cast< OsiClpSolverInterface*> (solver);
307    ClpSimplex * lpSolver=NULL;
308    if (clpSolver) {
309      if (clpSolver->messageHandler()->logLevel())
310        clpSolver->messageHandler()->setLogLevel(1);
311      if (logLevel>-1)
312        clpSolver->messageHandler()->setLogLevel(CoinMin(logLevel,clpSolver->messageHandler()->logLevel()));
313      lpSolver = clpSolver->getModelPtr();
314      /// If user left factorization frequency then compute
315      lpSolver->defaultFactorizationFrequency();
316    }
317#endif
318    // Tell solver we are in Branch and Cut
319    solver->setHintParam(OsiDoInBranchAndCut,true,OsiHintDo) ;
320    // Default set of cut generators
321    CglProbing generator1;
322    generator1.setUsingObjective(true);
323    generator1.setMaxPass(3);
324    generator1.setMaxProbeRoot(solver->getNumCols());
325    generator1.setMaxElements(100);
326    generator1.setMaxLookRoot(50);
327    generator1.setRowCuts(3);
328    //generator1.messageHandler()->setLogLevel(logLevel);
329    // Not needed with pass in process->messageHandler()->setLogLevel(logLevel);
330    // Add in generators
331    process->addCutGenerator(&generator1);
332    int translate[]={9999,0,3,2,-1,-2};
333    OsiSolverInterface * solver2 = 
334      process->preProcessNonDefault(*solver,
335                                    translate[desiredPreProcess_],preProcessPasses_);
336    // Tell solver we are not in Branch and Cut
337    solver->setHintParam(OsiDoInBranchAndCut,false,OsiHintDo) ;
338    if (solver2)
339      solver2->setHintParam(OsiDoInBranchAndCut,false,OsiHintDo) ;
340    bool feasible=true;
341    if (!solver2) {
342      feasible = false;
343      //printf("Pre-processing says infeasible\n");
344      delete process;
345      preProcessState_=-1;
346      process_=NULL;
347    } else {
348      // now tighten bounds
349#ifdef COIN_HAS_CLP
350      if (clpSolver) {
351        // model has changed
352        solver = model.solver();
353        OsiClpSolverInterface * clpSolver = dynamic_cast< OsiClpSolverInterface*> (solver);
354        ClpSimplex * lpSolver = clpSolver->getModelPtr();
355        lpSolver->passInMessageHandler(solver->messageHandler());
356        if (lpSolver->tightenPrimalBounds()==0) {
357          lpSolver->dual();
358        } else {
359          feasible = false;
360        }
361      }
362#endif
363      if (feasible) {
364        preProcessState_=1;
365        process_=process;
366        /* Note that original solver will be kept (with false)
367           and that final solver will also be kept.
368           This is for post-processing
369        */
370        OsiSolverInterface * solver3 = solver2->clone();
371        model.assignSolver(solver3,false);
372        if (process_->numberSOS()) {
373          int numberSOS = process_->numberSOS();
374          int numberIntegers = model.numberIntegers();
375          /* model may not have created objects
376             If none then create
377             NOTE - put back to original column numbers as
378             CbcModel will pack down ALL as it doesn't know where from
379          */
380          bool someObjects = model.numberObjects()>0;
381          if (!numberIntegers||!model.numberObjects()) {
382            model.findIntegers(true);
383            numberIntegers = model.numberIntegers();
384          }
385          OsiObject ** oldObjects = model.objects();
386          // Do sets and priorities
387          OsiObject ** objects = new OsiObject * [numberSOS];
388          // set old objects to have low priority
389          int numberOldObjects = model.numberObjects();
390          int numberColumns = model.getNumCols();
391          for (int iObj = 0;iObj<numberOldObjects;iObj++) {
392            int oldPriority = oldObjects[iObj]->priority();
393            oldObjects[iObj]->setPriority(numberColumns+oldPriority);
394          }
395          const int * starts = process_->startSOS();
396          const int * which = process_->whichSOS();
397          const int * type = process_->typeSOS();
398          const double * weight = process_->weightSOS();
399          int iSOS;
400          for (iSOS =0;iSOS<numberSOS;iSOS++) {
401            int iStart = starts[iSOS];
402            int n=starts[iSOS+1]-iStart;
403            objects[iSOS] = new CbcSOS(&model,n,which+iStart,weight+iStart,
404                                       iSOS,type[iSOS]);
405            // branch on long sets first
406            objects[iSOS]->setPriority(numberColumns-n);
407          }
408          model.addObjects(numberSOS,objects);
409          for (iSOS=0;iSOS<numberSOS;iSOS++)
410            delete objects[iSOS];
411          delete [] objects;
412          if (!someObjects) {
413            // put back old column numbers
414            const int * originalColumns = process_->originalColumns();
415            // use reverse lookup to fake it
416            int n=originalColumns[numberColumns-1]+1;
417            int * fake = new int[n];
418            int i;
419            for ( i=0;i<n;i++)
420              fake[i]=-1;
421            for (i=0;i<numberColumns;i++)
422              fake[originalColumns[i]]=i;
423            for (int iObject=0;iObject<model.numberObjects();iObject++) {
424              // redo ids etc
425              CbcSimpleInteger * obj =
426                dynamic_cast <CbcSimpleInteger *>(model.modifiableObject(iObject)) ;
427              if (obj) {
428                obj->resetSequenceEtc(n,fake);
429              } else {
430                // redo ids etc
431                CbcObject * obj =
432                  dynamic_cast <CbcObject *>(model.modifiableObject(iObject)) ;
433                assert (obj);
434                obj->redoSequenceEtc(&model,n,fake);
435              }
436            }
437            delete [] fake;
438          }
439        }
440      } else {
441        //printf("Pre-processing says infeasible\n");
442        delete process;
443        preProcessState_=-1;
444        process_=NULL;
445      }
446    }
447  }
448  model.setNumberStrong(numberStrong_);
449  model.setNumberBeforeTrust(numberBeforeTrust_);
450}
451// Create C++ lines to get to current state
452void 
453CbcStrategyDefault::generateCpp( FILE * fp) 
454{
455  fprintf(fp,"0#include \"CbcStrategy.hpp\"\n");
456  fprintf(fp,"3  CbcStrategyDefault strategy(%s,%d,%d,%d);\n",
457          cutsOnlyAtRoot_ ? "true" : "false",
458          numberStrong_,
459          numberBeforeTrust_,
460          printLevel_);
461  fprintf(fp,"3  strategy.setupPreProcessing(%d,%d);\n",
462          desiredPreProcess_,preProcessPasses_);
463}
464// Default Constructor
465CbcStrategyDefaultSubTree::CbcStrategyDefaultSubTree(CbcModel * parent ,
466                                                     bool cutsOnlyAtRoot,
467                                       int numberStrong,
468                                       int numberBeforeTrust,
469                                       int printLevel)
470  :CbcStrategy(),
471   parentModel_(parent),
472   cutsOnlyAtRoot_(cutsOnlyAtRoot),
473   numberStrong_(numberStrong),
474   numberBeforeTrust_(numberBeforeTrust),
475   printLevel_(printLevel)
476{
477}
478
479
480// Destructor
481CbcStrategyDefaultSubTree::~CbcStrategyDefaultSubTree ()
482{
483}
484
485// Clone
486CbcStrategy *
487CbcStrategyDefaultSubTree::clone() const
488{
489  return new CbcStrategyDefaultSubTree(*this);
490}
491
492// Copy constructor
493CbcStrategyDefaultSubTree::CbcStrategyDefaultSubTree(const CbcStrategyDefaultSubTree & rhs)
494:
495  CbcStrategy(rhs),
496  parentModel_(rhs.parentModel_),
497  cutsOnlyAtRoot_(rhs.cutsOnlyAtRoot_),
498  numberStrong_(rhs.numberStrong_),
499  numberBeforeTrust_(rhs.numberBeforeTrust_),
500  printLevel_(rhs.printLevel_)
501{
502  setNested(rhs.getNested());
503}
504
505// Setup cut generators
506void 
507CbcStrategyDefaultSubTree::setupCutGenerators(CbcModel & model)
508{
509  // Set up some cut generators and defaults
510  // Probing first as gets tight bounds on continuous
511
512  CglProbing generator1;
513  generator1.setUsingObjective(true);
514  generator1.setMaxPass(1);
515  // Number of unsatisfied variables to look at
516  generator1.setMaxProbe(10);
517  // How far to follow the consequences
518  generator1.setMaxLook(10);
519  // Only look at rows with fewer than this number of elements
520  generator1.setMaxElements(200);
521  //generator1.setRowCuts(3);
522
523  CglGomory generator2;
524  // try larger limit
525  generator2.setLimit(300);
526
527  CglKnapsackCover generator3;
528
529  //CglOddHole generator4;
530  //generator4.setMinimumViolation(0.005);
531  //generator4.setMinimumViolationPer(0.00002);
532  // try larger limit
533  //generator4.setMaximumEntries(200);
534
535  CglClique generator5;
536  generator5.setStarCliqueReport(false);
537  generator5.setRowCliqueReport(false);
538
539  CglMixedIntegerRounding2 mixedGen;
540  CglFlowCover flowGen;
541 
542  // Add in generators
543  int setting = cutsOnlyAtRoot_ ? -99 : -1;
544  int numberGenerators = model.numberCutGenerators();
545  int numberParentGenerators = parentModel_->numberCutGenerators();
546  int iGenerator;
547  bool found;
548  found=false;
549  int howOften=0;
550  for (iGenerator=0;iGenerator<numberParentGenerators;iGenerator++) {
551    CglCutGenerator * generator = parentModel_->cutGenerator(iGenerator)->generator();
552    CglProbing * cgl = dynamic_cast<CglProbing *>(generator);
553    if (cgl) {
554      found=true;
555      howOften = parentModel_->cutGenerator(iGenerator)->howOften();
556      break;
557    }
558  }
559  if (found&&howOften>=0) {
560    found=false;
561    for (iGenerator=0;iGenerator<numberGenerators;iGenerator++) {
562      CglCutGenerator * generator = model.cutGenerator(iGenerator)->generator();
563      CglProbing * cgl = dynamic_cast<CglProbing *>(generator);
564      if (cgl) {
565        found=true;
566        break;
567      }
568    }
569    if (!found)
570      model.addCutGenerator(&generator1,setting,"Probing");
571  }
572  found=false;
573  for (iGenerator=0;iGenerator<numberParentGenerators;iGenerator++) {
574    CglCutGenerator * generator = parentModel_->cutGenerator(iGenerator)->generator();
575    CglGomory * cgl = dynamic_cast<CglGomory *>(generator);
576    if (cgl) {
577      found=true;
578      howOften = parentModel_->cutGenerator(iGenerator)->howOften();
579      break;
580    }
581  }
582  if (found&&howOften>=0) {
583    found=false;
584    for (iGenerator=0;iGenerator<numberGenerators;iGenerator++) {
585      CglCutGenerator * generator = model.cutGenerator(iGenerator)->generator();
586      CglGomory * cgl = dynamic_cast<CglGomory *>(generator);
587      if (cgl) {
588        found=true;
589        break;
590      }
591    }
592    if (!found)
593      model.addCutGenerator(&generator2,setting,"Gomory");
594  }
595  found=false;
596  for (iGenerator=0;iGenerator<numberParentGenerators;iGenerator++) {
597    CglCutGenerator * generator = parentModel_->cutGenerator(iGenerator)->generator();
598    CglKnapsackCover * cgl = dynamic_cast<CglKnapsackCover *>(generator);
599    if (cgl) {
600      found=true;
601      howOften = parentModel_->cutGenerator(iGenerator)->howOften();
602      break;
603    }
604  }
605  if (found&&howOften>=0) {
606    found=false;
607    for (iGenerator=0;iGenerator<numberGenerators;iGenerator++) {
608      CglCutGenerator * generator = model.cutGenerator(iGenerator)->generator();
609      CglKnapsackCover * cgl = dynamic_cast<CglKnapsackCover *>(generator);
610      if (cgl) {
611        found=true;
612        break;
613      }
614    }
615    if (!found)
616      model.addCutGenerator(&generator3,setting,"Knapsack");
617  }
618  found=false;
619  for (iGenerator=0;iGenerator<numberParentGenerators;iGenerator++) {
620    CglCutGenerator * generator = parentModel_->cutGenerator(iGenerator)->generator();
621    CglClique * cgl = dynamic_cast<CglClique *>(generator);
622    if (cgl) {
623      found=true;
624      howOften = parentModel_->cutGenerator(iGenerator)->howOften();
625      break;
626    }
627  }
628  if (found&&howOften>=0) {
629    found=false;
630    for (iGenerator=0;iGenerator<numberGenerators;iGenerator++) {
631      CglCutGenerator * generator = model.cutGenerator(iGenerator)->generator();
632      CglClique * cgl = dynamic_cast<CglClique *>(generator);
633      if (cgl) {
634        found=true;
635        break;
636      }
637    }
638    if (!found)
639      model.addCutGenerator(&generator5,setting,"Clique");
640  }
641  found=false;
642  for (iGenerator=0;iGenerator<numberParentGenerators;iGenerator++) {
643    CglCutGenerator * generator = parentModel_->cutGenerator(iGenerator)->generator();
644    CglFlowCover * cgl = dynamic_cast<CglFlowCover *>(generator);
645    if (cgl) {
646      found=true;
647      howOften = parentModel_->cutGenerator(iGenerator)->howOften();
648      break;
649    }
650  }
651  if (found&&howOften>=0) {
652    found=false;
653    for (iGenerator=0;iGenerator<numberGenerators;iGenerator++) {
654      CglCutGenerator * generator = model.cutGenerator(iGenerator)->generator();
655      CglFlowCover * cgl = dynamic_cast<CglFlowCover *>(generator);
656      if (cgl) {
657        found=true;
658        break;
659      }
660    }
661    if (!found)
662      model.addCutGenerator(&flowGen,setting,"FlowCover");
663    found=false;
664  }
665  for (iGenerator=0;iGenerator<numberParentGenerators;iGenerator++) {
666    CglCutGenerator * generator = parentModel_->cutGenerator(iGenerator)->generator();
667    CglMixedIntegerRounding2 * cgl = dynamic_cast<CglMixedIntegerRounding2 *>(generator);
668    if (cgl) {
669      found=true;
670      howOften = parentModel_->cutGenerator(iGenerator)->howOften();
671      break;
672    }
673  }
674  if (found&&howOften>=0) {
675    found=false;
676    for (iGenerator=0;iGenerator<numberGenerators;iGenerator++) {
677      CglCutGenerator * generator = model.cutGenerator(iGenerator)->generator();
678      CglMixedIntegerRounding2 * cgl = dynamic_cast<CglMixedIntegerRounding2 *>(generator);
679      if (cgl) {
680        found=true;
681        break;
682      }
683    }
684    if (!found)
685      model.addCutGenerator(&mixedGen,setting,"MixedIntegerRounding2");
686  }
687#if 0
688  // Say we want timings
689  int newNumberGenerators = model.numberCutGenerators();
690  for (iGenerator=numberGenerators;iGenerator<newNumberGenerators;iGenerator++) {
691    CbcCutGenerator * generator = model.cutGenerator(iGenerator);
692    generator->setTiming(true);
693  }
694#endif
695  if (model.getNumCols()<500)
696    model.setMaximumCutPassesAtRoot(-100); // always do 100 if possible
697  else if (model.getNumCols()<5000)
698    model.setMaximumCutPassesAtRoot(100); // use minimum drop
699  else
700    model.setMaximumCutPassesAtRoot(20);
701}
702// Setup heuristics
703void 
704CbcStrategyDefaultSubTree::setupHeuristics(CbcModel & model)
705{
706  // Allow rounding heuristic
707
708  CbcRounding heuristic1(model);
709  int numberHeuristics = model.numberHeuristics();
710  int iHeuristic;
711  bool found;
712  found=false;
713  for (iHeuristic=0;iHeuristic<numberHeuristics;iHeuristic++) {
714    CbcHeuristic * heuristic = model.heuristic(iHeuristic);
715    CbcRounding * cgl = dynamic_cast<CbcRounding *>(heuristic);
716    if (cgl) {
717      found=true;
718      break;
719    }
720  }
721  if (!found)
722    model.addHeuristic(&heuristic1);
723}
724// Do printing stuff
725void 
726CbcStrategyDefaultSubTree::setupPrinting(CbcModel & model,int modelLogLevel)
727{
728  if (!modelLogLevel) {
729    model.solver()->setHintParam(OsiDoReducePrint,true,OsiHintTry);
730    model.messageHandler()->setLogLevel(0);
731    model.solver()->messageHandler()->setLogLevel(0);
732  } else if (modelLogLevel==1) {
733    model.solver()->setHintParam(OsiDoReducePrint,true,OsiHintTry);
734    model.messageHandler()->setLogLevel(1);
735    model.solver()->messageHandler()->setLogLevel(0);
736  } else {
737    model.messageHandler()->setLogLevel(2);
738    model.solver()->messageHandler()->setLogLevel(1);
739    model.setPrintFrequency(50);
740  }
741}
742// Other stuff e.g. strong branching
743void 
744CbcStrategyDefaultSubTree::setupOther(CbcModel & model)
745{
746  model.setNumberStrong(numberStrong_);
747  model.setNumberBeforeTrust(numberBeforeTrust_);
748}
749
750
751 
Note: See TracBrowser for help on using the repository browser.