source: trunk/CbcStrategy.cpp @ 182

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

more parameters

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 14.9 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#include "CbcModel.hpp"
13#include "CbcMessage.hpp"
14#include "CbcStrategy.hpp"
15#include "CbcCutGenerator.hpp"
16// Cuts
17
18#include "CglGomory.hpp"
19#include "CglProbing.hpp"
20#include "CglKnapsackCover.hpp"
21#include "CglOddHole.hpp"
22#include "CglClique.hpp"
23#include "CglFlowCover.hpp"
24#include "CglMixedIntegerRounding.hpp"
25
26// Heuristics
27
28#include "CbcHeuristic.hpp"
29
30// Default Constructor
31CbcStrategy::CbcStrategy() 
32  :depth_(0)
33{
34}
35
36// Destructor
37CbcStrategy::~CbcStrategy ()
38{
39}
40
41// Default Constructor
42CbcStrategyDefault::CbcStrategyDefault(bool cutsOnlyAtRoot,
43                                       int numberStrong,
44                                       int numberBeforeTrust,
45                                       int printLevel)
46  :CbcStrategy(),
47   cutsOnlyAtRoot_(cutsOnlyAtRoot),
48   numberStrong_(numberStrong),
49   numberBeforeTrust_(numberBeforeTrust),
50   printLevel_(printLevel)
51{
52}
53
54
55// Destructor
56CbcStrategyDefault::~CbcStrategyDefault ()
57{
58}
59
60// Clone
61CbcStrategy *
62CbcStrategyDefault::clone() const
63{
64  return new CbcStrategyDefault(*this);
65}
66
67// Copy constructor
68CbcStrategyDefault::CbcStrategyDefault(const CbcStrategyDefault & rhs)
69:
70  CbcStrategy(rhs),
71  cutsOnlyAtRoot_(rhs.cutsOnlyAtRoot_),
72  numberStrong_(rhs.numberStrong_),
73  numberBeforeTrust_(rhs.numberBeforeTrust_),
74  printLevel_(rhs.printLevel_)
75{
76  setNested(rhs.getNested());
77}
78
79// Setup cut generators
80void 
81CbcStrategyDefault::setupCutGenerators(CbcModel & model)
82{
83  // Set up some cut generators and defaults
84  // Probing first as gets tight bounds on continuous
85
86  CglProbing generator1;
87  generator1.setUsingObjective(true);
88  generator1.setMaxPass(1);
89  // Number of unsatisfied variables to look at
90  generator1.setMaxProbe(10);
91  // How far to follow the consequences
92  generator1.setMaxLook(10);
93  // Only look at rows with fewer than this number of elements
94  generator1.setMaxElements(200);
95  //generator1.setRowCuts(3);
96
97  CglGomory generator2;
98  // try larger limit
99  generator2.setLimit(300);
100
101  CglKnapsackCover generator3;
102
103  //CglOddHole generator4;
104  //generator4.setMinimumViolation(0.005);
105  //generator4.setMinimumViolationPer(0.00002);
106  // try larger limit
107  //generator4.setMaximumEntries(200);
108
109  CglClique generator5;
110  generator5.setStarCliqueReport(false);
111  generator5.setRowCliqueReport(false);
112
113  CglMixedIntegerRounding mixedGen;
114  CglFlowCover flowGen;
115 
116  // Add in generators
117  int setting = cutsOnlyAtRoot_ ? -99 : -1;
118  int numberGenerators = model.numberCutGenerators();
119  int iGenerator;
120  bool found;
121  found=false;
122  for (iGenerator=0;iGenerator<numberGenerators;iGenerator++) {
123    CglCutGenerator * generator = model.cutGenerator(iGenerator)->generator();
124    CglProbing * cgl = dynamic_cast<CglProbing *>(generator);
125    if (cgl) {
126      found=true;
127      break;
128    }
129  }
130  if (!found)
131    model.addCutGenerator(&generator1,setting,"Probing");
132  found=false;
133  for (iGenerator=0;iGenerator<numberGenerators;iGenerator++) {
134    CglCutGenerator * generator = model.cutGenerator(iGenerator)->generator();
135    CglGomory * cgl = dynamic_cast<CglGomory *>(generator);
136    if (cgl) {
137      found=true;
138      break;
139    }
140  }
141  if (!found)
142  model.addCutGenerator(&generator2,setting,"Gomory");
143  found=false;
144  for (iGenerator=0;iGenerator<numberGenerators;iGenerator++) {
145    CglCutGenerator * generator = model.cutGenerator(iGenerator)->generator();
146    CglKnapsackCover * cgl = dynamic_cast<CglKnapsackCover *>(generator);
147    if (cgl) {
148      found=true;
149      break;
150    }
151  }
152  if (!found)
153    model.addCutGenerator(&generator3,setting,"Knapsack");
154  //model.addCutGenerator(&generator4,setting,"OddHole");
155  found=false;
156  for (iGenerator=0;iGenerator<numberGenerators;iGenerator++) {
157    CglCutGenerator * generator = model.cutGenerator(iGenerator)->generator();
158    CglClique * cgl = dynamic_cast<CglClique *>(generator);
159    if (cgl) {
160      found=true;
161      break;
162    }
163  }
164  if (!found)
165    model.addCutGenerator(&generator5,setting,"Clique");
166  found=false;
167  for (iGenerator=0;iGenerator<numberGenerators;iGenerator++) {
168    CglCutGenerator * generator = model.cutGenerator(iGenerator)->generator();
169    CglFlowCover * cgl = dynamic_cast<CglFlowCover *>(generator);
170    if (cgl) {
171      found=true;
172      break;
173    }
174  }
175  if (!found)
176    model.addCutGenerator(&flowGen,setting,"FlowCover");
177  found=false;
178  for (iGenerator=0;iGenerator<numberGenerators;iGenerator++) {
179    CglCutGenerator * generator = model.cutGenerator(iGenerator)->generator();
180    CglMixedIntegerRounding * cgl = dynamic_cast<CglMixedIntegerRounding *>(generator);
181    if (cgl) {
182      found=true;
183      break;
184    }
185  }
186  if (!found)
187    model.addCutGenerator(&mixedGen,setting,"MixedIntegerRounding");
188  // Say we want timings
189  int newNumberGenerators = model.numberCutGenerators();
190  for (iGenerator=numberGenerators;iGenerator<newNumberGenerators;iGenerator++) {
191    CbcCutGenerator * generator = model.cutGenerator(iGenerator);
192    generator->setTiming(true);
193  }
194  if (model.getNumCols()<500)
195    model.setMaximumCutPassesAtRoot(-100); // always do 100 if possible
196  else if (model.getNumCols()<5000)
197    model.setMaximumCutPassesAtRoot(100); // use minimum drop
198  else
199    model.setMaximumCutPassesAtRoot(20);
200}
201// Setup heuristics
202void 
203CbcStrategyDefault::setupHeuristics(CbcModel & model)
204{
205  // Allow rounding heuristic
206
207  CbcRounding heuristic1(model);
208  int numberHeuristics = model.numberHeuristics();
209  int iHeuristic;
210  bool found;
211  found=false;
212  for (iHeuristic=0;iHeuristic<numberHeuristics;iHeuristic++) {
213    CbcHeuristic * heuristic = model.heuristic(iHeuristic);
214    CbcRounding * cgl = dynamic_cast<CbcRounding *>(heuristic);
215    if (cgl) {
216      found=true;
217      break;
218    }
219  }
220  if (!found)
221    model.addHeuristic(&heuristic1);
222}
223// Do printing stuff
224void 
225CbcStrategyDefault::setupPrinting(CbcModel & model,int modelLogLevel)
226{
227  if (!modelLogLevel) {
228    model.solver()->setHintParam(OsiDoReducePrint,true,OsiHintTry);
229    model.messageHandler()->setLogLevel(0);
230    model.solver()->messageHandler()->setLogLevel(0);
231  } else if (modelLogLevel==1) {
232    model.solver()->setHintParam(OsiDoReducePrint,true,OsiHintTry);
233    model.messageHandler()->setLogLevel(1);
234    model.solver()->messageHandler()->setLogLevel(0);
235  } else {
236    model.messageHandler()->setLogLevel(2);
237    model.solver()->messageHandler()->setLogLevel(1);
238    model.setPrintFrequency(50);
239  }
240}
241// Other stuff e.g. strong branching
242void 
243CbcStrategyDefault::setupOther(CbcModel & model)
244{
245  model.setNumberStrong(numberStrong_);
246  model.setNumberBeforeTrust(numberBeforeTrust_);
247}
248// Default Constructor
249CbcStrategyDefaultSubTree::CbcStrategyDefaultSubTree(CbcModel * parent ,
250                                                     bool cutsOnlyAtRoot,
251                                       int numberStrong,
252                                       int numberBeforeTrust,
253                                       int printLevel)
254  :CbcStrategy(),
255   parentModel_(parent),
256   cutsOnlyAtRoot_(cutsOnlyAtRoot),
257   numberStrong_(numberStrong),
258   numberBeforeTrust_(numberBeforeTrust),
259   printLevel_(printLevel)
260{
261}
262
263
264// Destructor
265CbcStrategyDefaultSubTree::~CbcStrategyDefaultSubTree ()
266{
267}
268
269// Clone
270CbcStrategy *
271CbcStrategyDefaultSubTree::clone() const
272{
273  return new CbcStrategyDefaultSubTree(*this);
274}
275
276// Copy constructor
277CbcStrategyDefaultSubTree::CbcStrategyDefaultSubTree(const CbcStrategyDefaultSubTree & rhs)
278:
279  CbcStrategy(rhs),
280  parentModel_(rhs.parentModel_),
281  cutsOnlyAtRoot_(rhs.cutsOnlyAtRoot_),
282  numberStrong_(rhs.numberStrong_),
283  numberBeforeTrust_(rhs.numberBeforeTrust_),
284  printLevel_(rhs.printLevel_)
285{
286  setNested(rhs.getNested());
287}
288
289// Setup cut generators
290void 
291CbcStrategyDefaultSubTree::setupCutGenerators(CbcModel & model)
292{
293  // Set up some cut generators and defaults
294  // Probing first as gets tight bounds on continuous
295
296  CglProbing generator1;
297  generator1.setUsingObjective(true);
298  generator1.setMaxPass(1);
299  // Number of unsatisfied variables to look at
300  generator1.setMaxProbe(10);
301  // How far to follow the consequences
302  generator1.setMaxLook(10);
303  // Only look at rows with fewer than this number of elements
304  generator1.setMaxElements(200);
305  //generator1.setRowCuts(3);
306
307  CglGomory generator2;
308  // try larger limit
309  generator2.setLimit(300);
310
311  CglKnapsackCover generator3;
312
313  //CglOddHole generator4;
314  //generator4.setMinimumViolation(0.005);
315  //generator4.setMinimumViolationPer(0.00002);
316  // try larger limit
317  //generator4.setMaximumEntries(200);
318
319  CglClique generator5;
320  generator5.setStarCliqueReport(false);
321  generator5.setRowCliqueReport(false);
322
323  CglMixedIntegerRounding mixedGen;
324  CglFlowCover flowGen;
325 
326  // Add in generators
327  int setting = cutsOnlyAtRoot_ ? -99 : -1;
328  int numberGenerators = model.numberCutGenerators();
329  int numberParentGenerators = parentModel_->numberCutGenerators();
330  int iGenerator;
331  bool found;
332  found=false;
333  for (iGenerator=0;iGenerator<numberParentGenerators;iGenerator++) {
334    CglCutGenerator * generator = parentModel_->cutGenerator(iGenerator)->generator();
335    CglProbing * cgl = dynamic_cast<CglProbing *>(generator);
336    if (cgl) {
337      found=true;
338      break;
339    }
340  }
341  if (found) {
342    found=false;
343    for (iGenerator=0;iGenerator<numberGenerators;iGenerator++) {
344      CglCutGenerator * generator = model.cutGenerator(iGenerator)->generator();
345      CglProbing * cgl = dynamic_cast<CglProbing *>(generator);
346      if (cgl) {
347        found=true;
348        break;
349      }
350    }
351    if (!found)
352      model.addCutGenerator(&generator1,setting,"Probing");
353  }
354  found=false;
355  for (iGenerator=0;iGenerator<numberParentGenerators;iGenerator++) {
356    CglCutGenerator * generator = parentModel_->cutGenerator(iGenerator)->generator();
357    CglGomory * cgl = dynamic_cast<CglGomory *>(generator);
358    if (cgl) {
359      found=true;
360      break;
361    }
362  }
363  if (found) {
364    found=false;
365    for (iGenerator=0;iGenerator<numberGenerators;iGenerator++) {
366      CglCutGenerator * generator = model.cutGenerator(iGenerator)->generator();
367      CglGomory * cgl = dynamic_cast<CglGomory *>(generator);
368      if (cgl) {
369        found=true;
370        break;
371      }
372    }
373    if (!found)
374      model.addCutGenerator(&generator2,setting,"Gomory");
375  }
376  found=false;
377  for (iGenerator=0;iGenerator<numberParentGenerators;iGenerator++) {
378    CglCutGenerator * generator = parentModel_->cutGenerator(iGenerator)->generator();
379    CglKnapsackCover * cgl = dynamic_cast<CglKnapsackCover *>(generator);
380    if (cgl) {
381      found=true;
382      break;
383    }
384  }
385  if (found) {
386    found=false;
387    for (iGenerator=0;iGenerator<numberGenerators;iGenerator++) {
388      CglCutGenerator * generator = model.cutGenerator(iGenerator)->generator();
389      CglKnapsackCover * cgl = dynamic_cast<CglKnapsackCover *>(generator);
390      if (cgl) {
391        found=true;
392        break;
393      }
394    }
395    if (!found)
396      model.addCutGenerator(&generator3,setting,"Knapsack");
397  }
398  found=false;
399  for (iGenerator=0;iGenerator<numberParentGenerators;iGenerator++) {
400    CglCutGenerator * generator = parentModel_->cutGenerator(iGenerator)->generator();
401    CglClique * cgl = dynamic_cast<CglClique *>(generator);
402    if (cgl) {
403      found=true;
404      break;
405    }
406  }
407  if (found) {
408    found=false;
409    for (iGenerator=0;iGenerator<numberGenerators;iGenerator++) {
410      CglCutGenerator * generator = model.cutGenerator(iGenerator)->generator();
411      CglClique * cgl = dynamic_cast<CglClique *>(generator);
412      if (cgl) {
413        found=true;
414        break;
415      }
416    }
417    if (!found)
418      model.addCutGenerator(&generator5,setting,"Clique");
419  }
420  found=false;
421  for (iGenerator=0;iGenerator<numberParentGenerators;iGenerator++) {
422    CglCutGenerator * generator = parentModel_->cutGenerator(iGenerator)->generator();
423    CglFlowCover * cgl = dynamic_cast<CglFlowCover *>(generator);
424    if (cgl) {
425      found=true;
426      break;
427    }
428  }
429  if (found) {
430    found=false;
431    for (iGenerator=0;iGenerator<numberGenerators;iGenerator++) {
432      CglCutGenerator * generator = model.cutGenerator(iGenerator)->generator();
433      CglFlowCover * cgl = dynamic_cast<CglFlowCover *>(generator);
434      if (cgl) {
435        found=true;
436        break;
437      }
438    }
439    if (!found)
440      model.addCutGenerator(&flowGen,setting,"FlowCover");
441    found=false;
442  }
443  for (iGenerator=0;iGenerator<numberParentGenerators;iGenerator++) {
444    CglCutGenerator * generator = parentModel_->cutGenerator(iGenerator)->generator();
445    CglMixedIntegerRounding * cgl = dynamic_cast<CglMixedIntegerRounding *>(generator);
446    if (cgl) {
447      found=true;
448      break;
449    }
450  }
451  if (found) {
452    found=false;
453    for (iGenerator=0;iGenerator<numberGenerators;iGenerator++) {
454      CglCutGenerator * generator = model.cutGenerator(iGenerator)->generator();
455      CglMixedIntegerRounding * cgl = dynamic_cast<CglMixedIntegerRounding *>(generator);
456      if (cgl) {
457        found=true;
458        break;
459      }
460    }
461    if (!found)
462      model.addCutGenerator(&mixedGen,setting,"MixedIntegerRounding");
463  }
464  // Say we want timings
465  int newNumberGenerators = model.numberCutGenerators();
466  for (iGenerator=numberGenerators;iGenerator<newNumberGenerators;iGenerator++) {
467    CbcCutGenerator * generator = model.cutGenerator(iGenerator);
468    generator->setTiming(true);
469  }
470  if (model.getNumCols()<500)
471    model.setMaximumCutPassesAtRoot(-100); // always do 100 if possible
472  else if (model.getNumCols()<5000)
473    model.setMaximumCutPassesAtRoot(100); // use minimum drop
474  else
475    model.setMaximumCutPassesAtRoot(20);
476}
477// Setup heuristics
478void 
479CbcStrategyDefaultSubTree::setupHeuristics(CbcModel & model)
480{
481  // Allow rounding heuristic
482
483  CbcRounding heuristic1(model);
484  int numberHeuristics = model.numberHeuristics();
485  int iHeuristic;
486  bool found;
487  found=false;
488  for (iHeuristic=0;iHeuristic<numberHeuristics;iHeuristic++) {
489    CbcHeuristic * heuristic = model.heuristic(iHeuristic);
490    CbcRounding * cgl = dynamic_cast<CbcRounding *>(heuristic);
491    if (cgl) {
492      found=true;
493      break;
494    }
495  }
496  if (!found)
497    model.addHeuristic(&heuristic1);
498}
499// Do printing stuff
500void 
501CbcStrategyDefaultSubTree::setupPrinting(CbcModel & model,int modelLogLevel)
502{
503  if (!modelLogLevel) {
504    model.solver()->setHintParam(OsiDoReducePrint,true,OsiHintTry);
505    model.messageHandler()->setLogLevel(0);
506    model.solver()->messageHandler()->setLogLevel(0);
507  } else if (modelLogLevel==1) {
508    model.solver()->setHintParam(OsiDoReducePrint,true,OsiHintTry);
509    model.messageHandler()->setLogLevel(1);
510    model.solver()->messageHandler()->setLogLevel(0);
511  } else {
512    model.messageHandler()->setLogLevel(2);
513    model.solver()->messageHandler()->setLogLevel(1);
514    model.setPrintFrequency(50);
515  }
516}
517// Other stuff e.g. strong branching
518void 
519CbcStrategyDefaultSubTree::setupOther(CbcModel & model)
520{
521  model.setNumberStrong(numberStrong_);
522  model.setNumberBeforeTrust(numberBeforeTrust_);
523}
524
525
526 
Note: See TracBrowser for help on using the repository browser.