source: trunk/CbcStrategy.cpp @ 250

Last change on this file since 250 was 250, checked in by forrest, 14 years ago

for infeasible

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