1
// Copyright (C) 2005, International Business Machines
2
// Corporation and others. All Rights Reserved.
4
// Turn off compiler warning about long names
5
# pragma warning(disable:4786)
15
#include "OsiSolverInterface.hpp"
17
#include "OsiClpSolverInterface.hpp"
19
#include "CbcModel.hpp"
20
#include "CbcMessage.hpp"
21
#include "CbcStrategy.hpp"
22
#include "CbcCutGenerator.hpp"
23
#include "CbcBranchActual.hpp"
24
#include "CbcNode.hpp"
25
#include "CoinWarmStart.hpp"
26
#include "CglPreProcess.hpp"
29
#include "CglGomory.hpp"
30
#include "CglProbing.hpp"
31
#include "CglKnapsackCover.hpp"
32
#include "CglOddHole.hpp"
33
#include "CglClique.hpp"
34
#include "CglFlowCover.hpp"
35
#include "CglMixedIntegerRounding2.hpp"
39
#include "CbcHeuristic.hpp"
40
#include "CbcHeuristicLocal.hpp"
42
// Default Constructor
43
CbcStrategy::CbcStrategy()
51
CbcStrategy::~CbcStrategy ()
55
// Delete pre-processing object to save memory
57
CbcStrategy::deletePreProcess()
62
// Return a new Full node information pointer (descendant of CbcFullNodeInfo)
64
CbcStrategy::fullNodeInfo(CbcModel * model,int numberRowsAtContinuous) const
66
return new CbcFullNodeInfo(model,numberRowsAtContinuous);
68
// Return a new Partial node information pointer (descendant of CbcPartialNodeInfo)
70
CbcStrategy::partialNodeInfo(CbcModel * model, CbcNodeInfo * parent, CbcNode * owner,
71
int numberChangedBounds,const int * variables,
72
const double * boundChanges,
73
const CoinWarmStartDiff *basisDiff) const
75
return new CbcPartialNodeInfo(parent, owner, numberChangedBounds, variables,
76
boundChanges,basisDiff);
78
/* After a CbcModel::resolve this can return a status
81
1 as 0 but do not do any more resolves (i.e. no more cuts)
85
CbcStrategy::status(CbcModel * model, CbcNodeInfo * parent,int whereFrom)
90
// Default Constructor
91
CbcStrategyDefault::CbcStrategyDefault(int cutsOnlyAtRoot,
93
int numberBeforeTrust,
96
cutsOnlyAtRoot_(cutsOnlyAtRoot),
97
numberStrong_(numberStrong),
98
numberBeforeTrust_(numberBeforeTrust),
99
printLevel_(printLevel),
100
desiredPreProcess_(0),
107
CbcStrategyDefault::~CbcStrategyDefault ()
113
CbcStrategyDefault::clone() const
115
return new CbcStrategyDefault(*this);
119
CbcStrategyDefault::CbcStrategyDefault(const CbcStrategyDefault & rhs)
122
cutsOnlyAtRoot_(rhs.cutsOnlyAtRoot_),
123
numberStrong_(rhs.numberStrong_),
124
numberBeforeTrust_(rhs.numberBeforeTrust_),
125
printLevel_(rhs.printLevel_),
126
desiredPreProcess_(rhs.desiredPreProcess_),
127
preProcessPasses_(rhs.preProcessPasses_)
129
setNested(rhs.getNested());
132
// Setup cut generators
134
CbcStrategyDefault::setupCutGenerators(CbcModel & model)
136
if (cutsOnlyAtRoot_<0)
137
return; // no cuts wanted
138
// Set up some cut generators and defaults
139
// Probing first as gets tight bounds on continuous
141
//#define CBC_GENERATE_TEST
142
#ifdef CBC_GENERATE_TEST
143
int nNodes = model.getMaximumNodes();
144
if (nNodes>=190000&&nNodes<190064)
145
genFlags = nNodes-190000;
148
CglProbing generator1;
149
generator1.setUsingObjective(true);
150
generator1.setMaxPass(1);
151
generator1.setMaxPassRoot(1);
152
// Number of unsatisfied variables to look at
153
generator1.setMaxProbe(10);
154
// How far to follow the consequences
155
generator1.setMaxLook(10);
156
// Only look at rows with fewer than this number of elements
157
generator1.setMaxElements(200);
158
generator1.setMaxElementsRoot(300);
159
//generator1.setRowCuts(3);
161
CglGomory generator2;
163
generator2.setLimit(300);
165
CglKnapsackCover generator3;
167
//CglOddHole generator4;
168
//generator4.setMinimumViolation(0.005);
169
//generator4.setMinimumViolationPer(0.00002);
171
//generator4.setMaximumEntries(200);
173
CglClique generator5;
174
generator5.setStarCliqueReport(false);
175
generator5.setRowCliqueReport(false);
177
CglMixedIntegerRounding2 mixedGen;
178
CglFlowCover flowGen;
181
int setting = cutsOnlyAtRoot_ ? -99 : -1;
182
int numberGenerators = model.numberCutGenerators();
186
for (iGenerator=0;iGenerator<numberGenerators;iGenerator++) {
187
CglCutGenerator * generator = model.cutGenerator(iGenerator)->generator();
188
CglProbing * cgl = dynamic_cast<CglProbing *>(generator);
194
if (!found&&(genFlags&1)!=0)
195
model.addCutGenerator(&generator1,setting,"Probing");
197
for (iGenerator=0;iGenerator<numberGenerators;iGenerator++) {
198
CglCutGenerator * generator = model.cutGenerator(iGenerator)->generator();
199
CglGomory * cgl = dynamic_cast<CglGomory *>(generator);
205
if (!found&&(genFlags&2)!=0)
206
model.addCutGenerator(&generator2,setting,"Gomory");
208
for (iGenerator=0;iGenerator<numberGenerators;iGenerator++) {
209
CglCutGenerator * generator = model.cutGenerator(iGenerator)->generator();
210
CglKnapsackCover * cgl = dynamic_cast<CglKnapsackCover *>(generator);
216
if (!found&&(genFlags&4)!=0)
217
model.addCutGenerator(&generator3,setting,"Knapsack");
218
//model.addCutGenerator(&generator4,setting,"OddHole");
220
for (iGenerator=0;iGenerator<numberGenerators;iGenerator++) {
221
CglCutGenerator * generator = model.cutGenerator(iGenerator)->generator();
222
CglClique * cgl = dynamic_cast<CglClique *>(generator);
228
if (!found&&(genFlags&8)!=0)
229
model.addCutGenerator(&generator5,setting,"Clique");
231
for (iGenerator=0;iGenerator<numberGenerators;iGenerator++) {
232
CglCutGenerator * generator = model.cutGenerator(iGenerator)->generator();
233
CglFlowCover * cgl = dynamic_cast<CglFlowCover *>(generator);
239
if (!found&&(genFlags&16)!=0)
240
model.addCutGenerator(&flowGen,setting,"FlowCover");
242
for (iGenerator=0;iGenerator<numberGenerators;iGenerator++) {
243
CglCutGenerator * generator = model.cutGenerator(iGenerator)->generator();
244
CglMixedIntegerRounding2 * cgl = dynamic_cast<CglMixedIntegerRounding2 *>(generator);
250
if (!found&&(genFlags&32)!=0)
251
model.addCutGenerator(&mixedGen,setting,"MixedIntegerRounding2");
252
// Say we want timings
253
int newNumberGenerators = model.numberCutGenerators();
254
for (iGenerator=numberGenerators;iGenerator<newNumberGenerators;iGenerator++) {
255
CbcCutGenerator * generator = model.cutGenerator(iGenerator);
256
generator->setTiming(true);
258
int currentPasses = model.getMaximumCutPassesAtRoot();
259
if (currentPasses>=0) {
260
if (model.getNumCols()<500)
261
model.setMaximumCutPassesAtRoot(-CoinMax(100,currentPasses)); // always do 100 if possible
262
else if (model.getNumCols()<5000)
263
model.setMaximumCutPassesAtRoot(CoinMax(100,currentPasses)); // use minimum drop
265
model.setMaximumCutPassesAtRoot(CoinMax(20,currentPasses));
267
currentPasses=-currentPasses;
268
if (model.getNumCols()<500)
269
model.setMaximumCutPassesAtRoot(-CoinMax(100,currentPasses)); // always do 100 if possible
271
model.setMaximumCutPassesAtRoot(-CoinMax(20,currentPasses));
276
CbcStrategyDefault::setupHeuristics(CbcModel & model)
278
// Allow rounding heuristic
280
CbcRounding heuristic1(model);
281
heuristic1.setHeuristicName("rounding");
282
int numberHeuristics = model.numberHeuristics();
286
for (iHeuristic=0;iHeuristic<numberHeuristics;iHeuristic++) {
287
CbcHeuristic * heuristic = model.heuristic(iHeuristic);
288
CbcRounding * cgl = dynamic_cast<CbcRounding *>(heuristic);
295
model.addHeuristic(&heuristic1);
297
// Allow join solutions
298
CbcHeuristicLocal heuristic2(model);
299
heuristic2.setHeuristicName("join solutions");
300
heuristic2.setSearchType(1);
302
for (iHeuristic=0;iHeuristic<numberHeuristics;iHeuristic++) {
303
CbcHeuristic * heuristic = model.heuristic(iHeuristic);
304
CbcHeuristicLocal * cgl = dynamic_cast<CbcHeuristicLocal *>(heuristic);
311
model.addHeuristic(&heuristic2);
316
CbcStrategyDefault::setupPrinting(CbcModel & model,int modelLogLevel)
318
if (!modelLogLevel) {
319
model.solver()->setHintParam(OsiDoReducePrint,true,OsiHintTry);
320
model.messageHandler()->setLogLevel(0);
321
model.solver()->messageHandler()->setLogLevel(0);
322
} else if (modelLogLevel==1) {
323
model.solver()->setHintParam(OsiDoReducePrint,true,OsiHintTry);
324
model.messageHandler()->setLogLevel(1);
325
model.solver()->messageHandler()->setLogLevel(0);
327
model.messageHandler()->setLogLevel(CoinMax(2,model.messageHandler()->logLevel()));
328
model.solver()->messageHandler()->setLogLevel(CoinMax(1,model.solver()->messageHandler()->logLevel()));
329
model.setPrintFrequency(CoinMin(50,model.printFrequency()));
332
// Other stuff e.g. strong branching
334
CbcStrategyDefault::setupOther(CbcModel & model)
336
// See if preprocessing wanted
337
if (desiredPreProcess_) {
339
// solver_ should have been cloned outside
340
CglPreProcess * process = new CglPreProcess();
341
// Pass in models message handler
342
process->passInMessageHandler(model.messageHandler());
343
OsiSolverInterface * solver = model.solver();
345
OsiClpSolverInterface * clpSolver = dynamic_cast< OsiClpSolverInterface*> (solver);
346
if (clpSolver&&false) {
347
// see if all coefficients multiple of 0.01 (close enough)
348
CoinPackedMatrix * matrix = clpSolver->getModelPtr()->matrix();
349
double * element = matrix->getMutableElements();
350
//const int * row = matrix->getIndices();
351
const CoinBigIndex * columnStart = matrix->getVectorStarts();
352
const int * columnLength = matrix->getVectorLengths();
356
int numberColumns = clpSolver->getNumCols();
358
for (iColumn=0;iColumn<numberColumns;iColumn++) {
359
for (int j=columnStart[iColumn];
360
j<columnStart[iColumn]+columnLength[iColumn];j++) {
362
double value1 = element[j];
363
double value = fabs(value1);
365
if(value!=floor(value))
370
int iValue = static_cast<int>( 100*(value+0.005));
371
double value2 = iValue;
372
if (value2==100.0*value) {
374
} else if (fabs(value2-100.0*value)<1.0e-5) {
382
if (!numberNon&&numberClose) {
383
printf("Tidying %d multiples of 0.01, %d close\n",
384
numberInt,numberClose);
385
for (iColumn=0;iColumn<numberColumns;iColumn++) {
386
for (int j=columnStart[iColumn];
387
j<columnStart[iColumn]+columnLength[iColumn];j++) {
389
double value1 = element[j];
390
double value = fabs(value1);
392
int iValue = static_cast<int>( 100*(value+0.005));
393
double value2 = iValue;
394
if (value2!=100.0*value) {
396
if (fabs(value-floor(value+0.5))<=1.0e-7)
397
value2 = floor(value+0.5);
409
// mark some columns as ineligible for presolve
410
int numberColumns = solver->getNumCols();
411
char * prohibited = new char[numberColumns];
412
memset(prohibited,0,numberColumns);
413
int numberProhibited=0;
414
// convert to Cbc integers
415
model.findIntegers(false);
416
int numberObjects = model.numberObjects();
418
OsiObject ** objects = model.objects();
419
for (int iObject=0;iObject<numberObjects;iObject++) {
421
dynamic_cast <CbcSOS *>(objects[iObject]) ;
424
int n = obj->numberMembers();
425
const int * which = obj->members();
426
for (int i=0;i<n;i++) {
427
int iColumn = which[i];
428
prohibited[iColumn]=1;
434
if (numberProhibited)
435
process->passInProhibited(prohibited,numberColumns);
436
delete [] prohibited;
438
int logLevel = model.messageHandler()->logLevel();
440
//OsiClpSolverInterface * clpSolver = dynamic_cast< OsiClpSolverInterface*> (solver);
441
ClpSimplex * lpSolver=NULL;
443
if (clpSolver->messageHandler()->logLevel())
444
clpSolver->messageHandler()->setLogLevel(1);
446
clpSolver->messageHandler()->setLogLevel(CoinMin(logLevel,clpSolver->messageHandler()->logLevel()));
447
lpSolver = clpSolver->getModelPtr();
448
/// If user left factorization frequency then compute
449
lpSolver->defaultFactorizationFrequency();
452
// Tell solver we are in Branch and Cut
453
solver->setHintParam(OsiDoInBranchAndCut,true,OsiHintDo) ;
454
// Default set of cut generators
455
CglProbing generator1;
456
generator1.setUsingObjective(true);
457
generator1.setMaxPass(1);
458
generator1.setMaxPassRoot(1);
459
generator1.setMaxProbeRoot(CoinMin(3000,solver->getNumCols()));
460
generator1.setMaxProbeRoot(123);
461
generator1.setMaxElements(100);
462
generator1.setMaxElementsRoot(200);
463
generator1.setMaxLookRoot(50);
464
generator1.setRowCuts(3);
465
//generator1.messageHandler()->setLogLevel(logLevel);
466
// Not needed with pass in process->messageHandler()->setLogLevel(logLevel);
468
process->addCutGenerator(&generator1);
469
int translate[]={9999,0,2,-2,3,4,4,4};
470
OsiSolverInterface * solver2 =
471
process->preProcessNonDefault(*solver,
472
translate[desiredPreProcess_],preProcessPasses_,6);
473
// Tell solver we are not in Branch and Cut
474
solver->setHintParam(OsiDoInBranchAndCut,false,OsiHintDo) ;
476
solver2->setHintParam(OsiDoInBranchAndCut,false,OsiHintDo) ;
480
//printf("Pre-processing says infeasible\n");
485
// now tighten bounds
489
solver = model.solver();
490
OsiClpSolverInterface * clpSolver = dynamic_cast< OsiClpSolverInterface*> (solver);
491
ClpSimplex * lpSolver = clpSolver->getModelPtr();
492
lpSolver->passInMessageHandler(solver->messageHandler());
493
if (lpSolver->tightenPrimalBounds()==0) {
503
/* Note that original solver will be kept (with false)
504
and that final solver will also be kept.
505
This is for post-processing
507
OsiSolverInterface * solver3 = solver2->clone();
508
model.assignSolver(solver3,false);
509
if (process_->numberSOS()) {
510
int numberSOS = process_->numberSOS();
511
int numberIntegers = model.numberIntegers();
512
/* model may not have created objects
514
NOTE - put back to original column numbers as
515
CbcModel will pack down ALL as it doesn't know where from
517
bool someObjects = model.numberObjects()>0;
518
if (!numberIntegers||!model.numberObjects()) {
519
model.findIntegers(true);
520
numberIntegers = model.numberIntegers();
522
OsiObject ** oldObjects = model.objects();
523
// Do sets and priorities
524
OsiObject ** objects = new OsiObject * [numberSOS];
525
// set old objects to have low priority
526
int numberOldObjects = model.numberObjects();
527
int numberColumns = model.getNumCols();
528
for (int iObj = 0;iObj<numberOldObjects;iObj++) {
529
int oldPriority = oldObjects[iObj]->priority();
530
oldObjects[iObj]->setPriority(numberColumns+oldPriority);
532
const int * starts = process_->startSOS();
533
const int * which = process_->whichSOS();
534
const int * type = process_->typeSOS();
535
const double * weight = process_->weightSOS();
537
for (iSOS =0;iSOS<numberSOS;iSOS++) {
538
int iStart = starts[iSOS];
539
int n=starts[iSOS+1]-iStart;
540
objects[iSOS] = new CbcSOS(&model,n,which+iStart,weight+iStart,
542
// branch on long sets first
543
objects[iSOS]->setPriority(numberColumns-n);
545
model.addObjects(numberSOS,objects);
546
for (iSOS=0;iSOS<numberSOS;iSOS++)
547
delete objects[iSOS];
550
// put back old column numbers
551
const int * originalColumns = process_->originalColumns();
552
// use reverse lookup to fake it
553
int n=originalColumns[numberColumns-1]+1;
554
int * fake = new int[n];
556
// This was wrong (now is correct) - so could never have been called
560
for (i=0;i<numberColumns;i++)
561
fake[originalColumns[i]]=i;
562
for (int iObject=0;iObject<model.numberObjects();iObject++) {
564
CbcSimpleInteger * obj =
565
dynamic_cast <CbcSimpleInteger *>(model.modifiableObject(iObject)) ;
567
obj->resetSequenceEtc(n,fake);
571
dynamic_cast <CbcObject *>(model.modifiableObject(iObject)) ;
573
obj->redoSequenceEtc(&model,n,fake);
580
//printf("Pre-processing says infeasible\n");
587
model.setNumberStrong(numberStrong_);
588
model.setNumberBeforeTrust(numberBeforeTrust_);
590
// Create C++ lines to get to current state
592
CbcStrategyDefault::generateCpp( FILE * fp)
594
fprintf(fp,"0#include \"CbcStrategy.hpp\"\n");
595
fprintf(fp,"3 CbcStrategyDefault strategy(%s,%d,%d,%d);\n",
596
cutsOnlyAtRoot_ ? "1" : "0",
600
fprintf(fp,"3 strategy.setupPreProcessing(%d,%d);\n",
601
desiredPreProcess_,preProcessPasses_);
603
// Default Constructor
604
CbcStrategyDefaultSubTree::CbcStrategyDefaultSubTree(CbcModel * parent ,
607
int numberBeforeTrust,
610
parentModel_(parent),
611
cutsOnlyAtRoot_(cutsOnlyAtRoot),
612
numberStrong_(numberStrong),
613
numberBeforeTrust_(numberBeforeTrust),
614
printLevel_(printLevel)
620
CbcStrategyDefaultSubTree::~CbcStrategyDefaultSubTree ()
626
CbcStrategyDefaultSubTree::clone() const
628
return new CbcStrategyDefaultSubTree(*this);
632
CbcStrategyDefaultSubTree::CbcStrategyDefaultSubTree(const CbcStrategyDefaultSubTree & rhs)
635
parentModel_(rhs.parentModel_),
636
cutsOnlyAtRoot_(rhs.cutsOnlyAtRoot_),
637
numberStrong_(rhs.numberStrong_),
638
numberBeforeTrust_(rhs.numberBeforeTrust_),
639
printLevel_(rhs.printLevel_)
641
setNested(rhs.getNested());
644
// Setup cut generators
646
CbcStrategyDefaultSubTree::setupCutGenerators(CbcModel & model)
648
// Set up some cut generators and defaults
649
if (cutsOnlyAtRoot_<0)
650
return; // no cuts wanted
651
// Probing first as gets tight bounds on continuous
653
CglProbing generator1;
654
generator1.setUsingObjective(true);
655
generator1.setMaxPass(1);
656
// Number of unsatisfied variables to look at
657
generator1.setMaxProbe(10);
658
// How far to follow the consequences
659
generator1.setMaxLook(10);
660
// Only look at rows with fewer than this number of elements
661
generator1.setMaxElements(200);
662
//generator1.setRowCuts(3);
664
CglGomory generator2;
666
generator2.setLimit(300);
668
CglKnapsackCover generator3;
670
//CglOddHole generator4;
671
//generator4.setMinimumViolation(0.005);
672
//generator4.setMinimumViolationPer(0.00002);
674
//generator4.setMaximumEntries(200);
676
CglClique generator5;
677
generator5.setStarCliqueReport(false);
678
generator5.setRowCliqueReport(false);
680
CglMixedIntegerRounding2 mixedGen;
681
CglFlowCover flowGen;
684
int setting = cutsOnlyAtRoot_ ? -99 : -1;
685
int numberGenerators = model.numberCutGenerators();
686
int numberParentGenerators = parentModel_->numberCutGenerators();
691
for (iGenerator=0;iGenerator<numberParentGenerators;iGenerator++) {
692
CglCutGenerator * generator = parentModel_->cutGenerator(iGenerator)->generator();
693
CglProbing * cgl = dynamic_cast<CglProbing *>(generator);
696
howOften = parentModel_->cutGenerator(iGenerator)->howOften();
701
if (found&&(howOften>=-1||howOften==-98)) {
703
for (iGenerator=0;iGenerator<numberGenerators;iGenerator++) {
704
CglCutGenerator * generator = model.cutGenerator(iGenerator)->generator();
705
CglProbing * cgl = dynamic_cast<CglProbing *>(generator);
714
else if (howOften==-98)
716
model.addCutGenerator(&generator1,setting,"Probing");
717
CbcCutGenerator * generator =
718
model.cutGenerator(numberGenerators);
719
generator->setHowOften(howOften);
724
for (iGenerator=0;iGenerator<numberParentGenerators;iGenerator++) {
725
CglCutGenerator * generator = parentModel_->cutGenerator(iGenerator)->generator();
726
CglGomory * cgl = dynamic_cast<CglGomory *>(generator);
729
howOften = parentModel_->cutGenerator(iGenerator)->howOften();
733
if (found&&howOften>=0) {
735
for (iGenerator=0;iGenerator<numberGenerators;iGenerator++) {
736
CglCutGenerator * generator = model.cutGenerator(iGenerator)->generator();
737
CglGomory * cgl = dynamic_cast<CglGomory *>(generator);
744
model.addCutGenerator(&generator2,setting,"Gomory");
747
for (iGenerator=0;iGenerator<numberParentGenerators;iGenerator++) {
748
CglCutGenerator * generator = parentModel_->cutGenerator(iGenerator)->generator();
749
CglKnapsackCover * cgl = dynamic_cast<CglKnapsackCover *>(generator);
752
howOften = parentModel_->cutGenerator(iGenerator)->howOften();
756
if (found&&howOften>=0) {
758
for (iGenerator=0;iGenerator<numberGenerators;iGenerator++) {
759
CglCutGenerator * generator = model.cutGenerator(iGenerator)->generator();
760
CglKnapsackCover * cgl = dynamic_cast<CglKnapsackCover *>(generator);
767
model.addCutGenerator(&generator3,setting,"Knapsack");
770
for (iGenerator=0;iGenerator<numberParentGenerators;iGenerator++) {
771
CglCutGenerator * generator = parentModel_->cutGenerator(iGenerator)->generator();
772
CglClique * cgl = dynamic_cast<CglClique *>(generator);
775
howOften = parentModel_->cutGenerator(iGenerator)->howOften();
779
if (found&&howOften>=0) {
781
for (iGenerator=0;iGenerator<numberGenerators;iGenerator++) {
782
CglCutGenerator * generator = model.cutGenerator(iGenerator)->generator();
783
CglClique * cgl = dynamic_cast<CglClique *>(generator);
790
model.addCutGenerator(&generator5,setting,"Clique");
793
for (iGenerator=0;iGenerator<numberParentGenerators;iGenerator++) {
794
CglCutGenerator * generator = parentModel_->cutGenerator(iGenerator)->generator();
795
CglFlowCover * cgl = dynamic_cast<CglFlowCover *>(generator);
798
howOften = parentModel_->cutGenerator(iGenerator)->howOften();
802
if (found&&howOften>=0) {
804
for (iGenerator=0;iGenerator<numberGenerators;iGenerator++) {
805
CglCutGenerator * generator = model.cutGenerator(iGenerator)->generator();
806
CglFlowCover * cgl = dynamic_cast<CglFlowCover *>(generator);
813
model.addCutGenerator(&flowGen,setting,"FlowCover");
816
for (iGenerator=0;iGenerator<numberParentGenerators;iGenerator++) {
817
CglCutGenerator * generator = parentModel_->cutGenerator(iGenerator)->generator();
818
CglMixedIntegerRounding2 * cgl = dynamic_cast<CglMixedIntegerRounding2 *>(generator);
821
howOften = parentModel_->cutGenerator(iGenerator)->howOften();
825
if (found&&howOften>=0) {
827
for (iGenerator=0;iGenerator<numberGenerators;iGenerator++) {
828
CglCutGenerator * generator = model.cutGenerator(iGenerator)->generator();
829
CglMixedIntegerRounding2 * cgl = dynamic_cast<CglMixedIntegerRounding2 *>(generator);
836
model.addCutGenerator(&mixedGen,setting,"MixedIntegerRounding2");
839
// Say we want timings
840
int newNumberGenerators = model.numberCutGenerators();
841
for (iGenerator=numberGenerators;iGenerator<newNumberGenerators;iGenerator++) {
842
CbcCutGenerator * generator = model.cutGenerator(iGenerator);
843
generator->setTiming(true);
846
if (model.getNumCols()<500)
847
model.setMaximumCutPassesAtRoot(-100); // always do 100 if possible
848
else if (model.getNumCols()<5000)
849
model.setMaximumCutPassesAtRoot(100); // use minimum drop
851
model.setMaximumCutPassesAtRoot(20);
855
CbcStrategyDefaultSubTree::setupHeuristics(CbcModel & model)
857
// Allow rounding heuristic
859
CbcRounding heuristic1(model);
860
heuristic1.setHeuristicName("rounding");
861
int numberHeuristics = model.numberHeuristics();
865
for (iHeuristic=0;iHeuristic<numberHeuristics;iHeuristic++) {
866
CbcHeuristic * heuristic = model.heuristic(iHeuristic);
867
CbcRounding * cgl = dynamic_cast<CbcRounding *>(heuristic);
874
model.addHeuristic(&heuristic1);
878
CbcStrategyDefaultSubTree::setupPrinting(CbcModel & model,int modelLogLevel)
880
if (!modelLogLevel) {
881
model.solver()->setHintParam(OsiDoReducePrint,true,OsiHintTry);
882
model.messageHandler()->setLogLevel(0);
883
model.solver()->messageHandler()->setLogLevel(0);
884
} else if (modelLogLevel==1) {
885
model.solver()->setHintParam(OsiDoReducePrint,true,OsiHintTry);
886
model.messageHandler()->setLogLevel(1);
887
model.solver()->messageHandler()->setLogLevel(0);
889
model.messageHandler()->setLogLevel(2);
890
model.solver()->messageHandler()->setLogLevel(1);
891
model.setPrintFrequency(50);
894
// Other stuff e.g. strong branching
896
CbcStrategyDefaultSubTree::setupOther(CbcModel & model)
898
model.setNumberStrong(numberStrong_);
899
model.setNumberBeforeTrust(numberBeforeTrust_);
901
// For uniform setting of cut and heuristic options
903
setCutAndHeuristicOptions(CbcModel & model)
905
int numberGenerators = model.numberCutGenerators();
907
for (iGenerator=0;iGenerator<numberGenerators;iGenerator++) {
908
CglCutGenerator * generator = model.cutGenerator(iGenerator)->generator();
909
CglProbing * cglProbing = dynamic_cast<CglProbing *>(generator);
911
cglProbing->setUsingObjective(1);
912
cglProbing->setMaxPass(1);
913
cglProbing->setMaxPassRoot(1);
914
// Number of unsatisfied variables to look at
915
cglProbing->setMaxProbe(10);
916
cglProbing->setMaxProbeRoot(50);
917
//cglProbing->setMaxProbeRoot(123);
918
// How far to follow the consequences
919
cglProbing->setMaxLook(5);
920
cglProbing->setMaxLookRoot(50);
921
cglProbing->setMaxLookRoot(10);
922
// Only look at rows with fewer than this number of elements
923
cglProbing->setMaxElements(200);
924
cglProbing->setMaxElementsRoot(300);
925
cglProbing->setRowCuts(3);
928
CglGomory * cglGomory = dynamic_cast<CglGomory *>(generator);
931
cglGomory->setLimitAtRoot(1000);
932
cglGomory->setLimit(50);
934
CglKnapsackCover * cglKnapsackCover = dynamic_cast<CglKnapsackCover *>(generator);
935
if (cglKnapsackCover) {