source: trunk/Couenne/src/main/BonCouenneSetup.cpp @ 85

Last change on this file since 85 was 85, checked in by pbelotti, 11 years ago

added popup blocker for unit test

File size: 20.7 KB
Line 
1// (C) Copyright International Business Machines Corporation 2007
2// All Rights Reserved.
3// This code is published under the Common Public License.
4//
5// Authors :
6// Pierre Bonami, International Business Machines Corporation
7//
8// Date : 04/18/2007
9
10#include "BonCouenneSetup.hpp"
11#include "BonInitHeuristic.hpp"
12#include "BonNlpHeuristic.hpp"
13#include "BonCouenneInterface.hpp"
14
15#include "BonGuessHeuristic.hpp"
16#include "CbcCompareActual.hpp"
17
18#include "CouenneObject.hpp"
19#include "CouenneComplObject.hpp"
20#include "CouenneVarObject.hpp"
21#include "CouenneVTObject.hpp"
22#include "CouenneChooseVariable.hpp"
23#include "CouenneChooseStrong.hpp"
24#include "CouenneSolverInterface.hpp"
25#include "CouenneCutGenerator.hpp"
26#include "CouenneDisjCuts.hpp"
27#include "BonCouenneInfo.hpp"
28#include "BonCbcNode.hpp"
29
30// MILP cuts
31#include "CglGomory.hpp"
32#include "CglProbing.hpp"
33#include "CglKnapsackCover.hpp"
34#include "CglOddHole.hpp"
35#include "CglClique.hpp"
36#include "CglFlowCover.hpp"
37#include "CglMixedIntegerRounding2.hpp"
38#include "CglTwomir.hpp"
39#include "CglPreProcess.hpp"
40#include "CglLandP.hpp"
41#include "CglRedSplit.hpp"
42
43// Ampl includes
44#ifdef COIN_HAS_ASL
45#include "asl.h"
46#include "getstub.h"
47#endif
48
49
50namespace Bonmin{
51 
52  SmartAsl::~SmartAsl(){
53#ifdef COIN_HAS_ASL
54    //Code from Ipopt::AmplTNLP to free asl
55    if(asl != NULL){
56        if (X0) {
57          delete [] X0;
58          X0 = NULL;
59        }
60        if (havex0) {
61          delete [] havex0;
62          havex0 = NULL;
63        }
64        if (pi0) {
65          delete [] pi0;
66          pi0 = NULL;
67        }
68        if (havepi0) {
69          delete [] havepi0;
70          havepi0 = NULL;
71        }
72        ASL* asl_to_free = (ASL*)asl;
73        ASL_free(&asl_to_free);
74        asl = NULL;
75    }
76    ASL_free(&asl);
77#endif
78  }
79 
80  CouenneSetup::~CouenneSetup(){
81    //if (CouennePtr_)
82    //delete CouennePtr_;
83  }
84
85  bool CouenneSetup::InitializeCouenne (char **& argv, 
86                                        CouenneProblem *couenneProb,
87                                        Bonmin::CouenneInterface *ci) {
88    /* Get the basic options. */
89    readOptionsFile();
90 
91    // in check mode, avoid pop-up error message (there are quite a few messages)
92    std::string test_mode;
93    options_ -> GetStringValue ("test_mode", test_mode, "couenne.");
94    if (test_mode == "yes")
95      WindowsErrorPopupBlocker();
96
97    /** Change default value for failure behavior so that code doesn't crash
98        when Ipopt does not solve a sub-problem.*/
99
100    options_->SetStringValue ("nlp_failure_behavior", "fathom", "bonmin.");
101
102    gatherParametersValues(options_);
103
104    continuousSolver_ = new CouenneSolverInterface;
105
106    if (!ci) {
107
108      ci = new CouenneInterface;
109
110      if (!couenneProb && argv) {
111#ifdef COIN_HAS_ASL
112        /* Read the model in various places. */
113        ci->readAmplNlFile(argv,roptions(),options(),journalist());
114        aslfg_ = new SmartAsl;
115        aslfg_->asl = readASLfg (argv);
116#else
117            std::cerr << "Couenne was compiled without AMPL Solver Library. Cannot initialize from AMPL NL File." << std::endl;
118            return false;
119#endif
120      } 
121    }
122
123    nonlinearSolver_ = ci;
124
125    /** Set the output level for the journalist for all Couenne
126     categories.  We probably want to make that a bit more flexible
127     later. */
128    int i;
129
130    options()->GetIntegerValue("boundtightening_print_level", i, "bonmin.");
131    journalist()->GetJournal("console")-> SetPrintLevel(J_BOUNDTIGHTENING, (EJournalLevel) i);
132
133    options()->GetIntegerValue("branching_print_level", i, "bonmin.");
134    journalist()->GetJournal("console")-> SetPrintLevel(J_BRANCHING, (EJournalLevel) i);
135
136    options()->GetIntegerValue("convexifying_print_level", i, "bonmin.");
137    journalist()->GetJournal("console")-> SetPrintLevel(J_CONVEXIFYING, (EJournalLevel) i);
138
139    options()->GetIntegerValue("problem_print_level", i, "bonmin.");
140    journalist()->GetJournal("console")-> SetPrintLevel(J_PROBLEM, (EJournalLevel) i);
141
142    options()->GetIntegerValue("nlpheur_print_level", i, "bonmin.");
143    journalist()->GetJournal("console")-> SetPrintLevel(J_NLPHEURISTIC, (EJournalLevel) i);
144
145    options()->GetIntegerValue("disjcuts_print_level", i, "bonmin.");
146    journalist()->GetJournal("console")-> SetPrintLevel(J_DISJCUTS, (EJournalLevel) i);
147
148    options()->GetIntegerValue("reformulate_print_level", i, "bonmin.");
149    journalist()->GetJournal("console")-> SetPrintLevel(J_REFORMULATE, (EJournalLevel) i);
150
151    /* Initialize Couenne cut generator.*/
152    //int ivalue, num_points;
153    //options()->GetEnumValue("convexification_type", ivalue,"bonmin.");
154    //options()->GetIntegerValue("convexification_points",num_points,"bonmin.");
155   
156    CouenneCutGenerator * couenneCg = 
157      new CouenneCutGenerator (ci, this, couenneProb ? NULL : aslfg_->asl);
158
159    if (!couenneProb) couenneProb = couenneCg -> Problem();
160    else {
161      couenneCg   -> setProblem (couenneProb);
162      couenneProb -> setBase    (this);
163    }
164
165    assert (couenneProb);
166
167    couenneProb -> reformulate ();
168
169    Bonmin::BabInfo * extraStuff = new Bonmin::CouenneInfo(0);
170
171    // as per instructions by John Forrest, to get changed bounds
172    extraStuff -> setExtraCharacteristics (extraStuff -> extraCharacteristics () | 2);
173
174    continuousSolver_ -> setAuxiliaryInfo (extraStuff);
175    delete extraStuff;
176   
177    extraStuff = dynamic_cast <Bonmin::BabInfo *> (continuousSolver_ -> getAuxiliaryInfo ());
178   
179    /* Setup log level*/
180    int lpLogLevel;
181    options()->GetIntegerValue("lp_log_level",lpLogLevel,"bonmin.");
182    continuousSolver_->messageHandler()->setLogLevel(lpLogLevel);
183
184    //////////////////////////////////////////////////////////////
185
186    couenneCg -> Problem () -> setMaxCpuTime (getDoubleParameter (BabSetupBase::MaxTime));
187
188    ci -> extractLinearRelaxation (*continuousSolver_, *couenneCg);
189
190    // In case there are no discrete variables, we have already a
191    // heuristic solution for which create a initialization heuristic
192    if (!(extraStuff -> infeasibleNode ()) &&
193        ci -> isProvenOptimal () && 
194        ci -> haveNlpSolution ()) {
195
196      /// setup initial heuristic (in principle it should only run once...)
197      InitHeuristic* initHeuristic = new InitHeuristic
198        (ci -> getObjValue (), ci -> getColSolution (), *couenneProb);
199      HeuristicMethod h;
200      h.id = "Init Rounding NLP";
201      h.heuristic = initHeuristic;
202      heuristics_.push_back(h);
203    }
204
205    if (extraStuff -> infeasibleNode ()){
206      std::cout<<"Initial linear relaxation constructed by Couenne is infeasible, exiting..."
207               <<std::endl;
208      return false;
209    }
210
211    //continuousSolver_ -> findIntegersAndSOS (false);
212    //addSos (); // only adds embedded SOS objects
213
214    // Add Couenne SOS ///////////////////////////////////////////////////////////////
215
216    std::string s;
217
218    int 
219      nSOS  = 0,
220      nVars = couenneProb -> nVars ();
221
222    OsiObject ** objects = NULL;
223
224    options () -> GetStringValue ("enable_sos", s, "couenne.");
225    if (s == "yes") {
226
227      // allocate sufficient space for both nonlinear variables and SOS's
228      objects = new OsiObject* [couenneProb -> nCons () + nVars];
229
230      nSOS = couenneProb -> findSOS (nonlinearSolver (), objects);
231      //printf ("==================== found %d SOS\n", nSOS);
232      //nonlinearSolver () -> addObjects (nSOS, objects);
233      //continuousSolver () -> addObjects (nSOS, objects);
234
235      //printf ("found %d SOS!\n", nSOS);
236
237      /*for (int i=0; i<nSOS; i++)
238        delete objects [i];
239        delete [] objects;*/
240
241      if (!nSOS) {
242        delete [] objects;
243        objects = NULL;
244      } 
245    }
246
247    //model -> assignSolver (continuousSolver_, true);
248    //continuousSolver_ = model -> solver();
249
250    // Add Couenne objects for branching /////////////////////////////////////////////
251
252    options () -> GetStringValue ("display_stats", s, "couenne.");
253    displayStats_ = (s == "yes");
254
255    options () -> GetStringValue ("branching_object", s, "couenne.");
256
257    enum CouenneObject::branch_obj objType = CouenneObject::VAR_OBJ;
258
259    if      (s ==   "vt_obj") objType = CouenneObject::VT_OBJ;
260    else if (s ==  "var_obj") objType = CouenneObject::VAR_OBJ;
261    else if (s == "expr_obj") objType = CouenneObject::EXPR_OBJ;
262    else {
263      printf ("CouenneSetup: Unknown branching object type\n");
264      exit (-1);
265    }
266
267    int 
268      nobj = nSOS; // if no SOS then objects is empty
269
270    if (!objects)
271      objects = new OsiObject* [nVars];
272
273    int contObjPriority = 2000; // default object priority -- it is 1000 for integers and 10 for SOS
274
275    options () -> GetIntegerValue ("cont_var_priority", contObjPriority, "bonmin.");
276
277    for (int i = 0; i < nVars; i++) { // for each variable
278
279      exprVar *var = couenneProb -> Var (i);
280
281      // we only want enabled variables
282      if (var -> Multiplicity () <= 0) 
283        continue;
284
285      switch (objType) {
286
287      case CouenneObject::EXPR_OBJ:
288
289        // if this variable is associated with a nonlinear function
290        if (var -> isInteger () || 
291            (var -> Type  () == AUX) && 
292            (var -> Image () -> Linearity () > LINEAR)) {
293
294          /*if ((var -> Image () -> code () == COU_EXPRMUL) &&
295              (var -> Image () -> ArgList () [0] -> Index () >= 0) &&
296              (var -> Image () -> ArgList () [1] -> Index () >= 0) &&
297              (fabs (var -> lb ()) < COUENNE_EPS) &&
298              (fabs (var -> ub ()) < COUENNE_EPS))
299
300            // it's a complementarity constraint object!
301            objects    [nobj] = new CouenneComplObject (couenneProb, var, this, journalist ());
302            else*/
303          objects [nobj] = new CouenneObject      (couenneProb, var, this, journalist ());
304
305          objects [nobj++] -> setPriority (contObjPriority);
306          //objects [nobj++] -> setPriority (contObjPriority + var -> rank ());
307        }
308
309        break;
310
311      case CouenneObject::VAR_OBJ:
312
313        // branching objects on variables
314        if // comment three lines below for linear variables too
315          (var -> isInteger () || 
316           (couenneProb -> Dependence () [var -> Index ()] . size () > 0)) {  // has indep
317           //|| ((var -> Type () == AUX) &&                                  // or, aux
318           //    (var -> Image () -> Linearity () > LINEAR))) {              // of nonlinear
319
320          objects [nobj] = new CouenneVarObject (couenneProb, var, this, journalist ());
321          objects [nobj++] -> setPriority (contObjPriority);
322          //objects [nobj++] -> setPriority (contObjPriority + var -> rank ());
323        }
324
325        break;
326
327      default:
328      case CouenneObject::VT_OBJ:
329
330        // branching objects on variables
331        if // comment three lines below for linear variables too
332          (var -> isInteger () || 
333           (couenneProb -> Dependence () [var -> Index ()] . size () > 0)) { // has indep
334          //|| ((var -> Type () == AUX) &&                      // or, aux
335          //(var -> Image () -> Linearity () > LINEAR))) { // of nonlinear
336
337          objects [nobj] = new CouenneVTObject (couenneProb, var, this, journalist ());
338          objects [nobj++] -> setPriority (contObjPriority);
339          //objects [nobj++] -> setPriority (contObjPriority + var -> rank ());
340        }
341
342        break;
343      }
344    }
345
346    // Add objects /////////////////////////////////
347
348    continuousSolver_ -> addObjects (nobj, objects);
349
350    for (int i = 0 ; i < nobj ; i++)
351      delete objects [i];
352
353    delete [] objects;
354
355    // Setup Convexifier generators ////////////////////////////////////////////////
356
357    int freq;
358
359    options()->GetIntegerValue("convexification_cuts",freq,"couenne.");
360
361    if (freq != 0) {
362
363      CuttingMethod cg;
364      cg.frequency = freq;
365      cg.cgl = couenneCg;
366      cg.id = "Couenne convexifier cuts";
367      cutGenerators().push_back(cg);
368
369      // set cut gen pointer
370      dynamic_cast <CouenneSolverInterface *> 
371        (continuousSolver_) -> setCutGenPtr (couenneCg);
372    }
373
374    // disjunctive cuts generator added AFTER
375
376    // add other cut generators -- test for integer variables first
377    if (couenneCg -> Problem () -> nIntVars () > 0)
378      addMilpCutGenerators ();
379
380    CouennePtr_ = couenneCg;
381
382    // Setup heuristic to solve nlp problems. /////////////////////////////////
383
384    int doNlpHeurisitic = 0;
385    options()->GetEnumValue("local_optimization_heuristic", doNlpHeurisitic, "couenne.");
386    if(doNlpHeurisitic)
387    {
388      int numSolve;
389      options()->GetIntegerValue("log_num_local_optimization_per_level",numSolve,"couenne.");
390      NlpSolveHeuristic * nlpHeuristic = new NlpSolveHeuristic;
391      nlpHeuristic->setNlp(*ci,false);
392      nlpHeuristic->setCouenneProblem(couenneProb);
393      //nlpHeuristic->setMaxNlpInf(1e-4);
394      nlpHeuristic->setMaxNlpInf(maxNlpInf_0);
395      nlpHeuristic->setNumberSolvePerLevel(numSolve);
396      HeuristicMethod h;
397      h.id = "Couenne Rounding NLP";
398      h.heuristic = nlpHeuristic;
399      heuristics_.push_back(h);
400    }
401
402#if 0
403    {
404      CbcCompareEstimate compare;
405      model -> setNodeComparison(compare);
406      GuessHeuristic * guessHeu = new GuessHeuristic (*model);
407      HeuristicMethod h;
408      h.id = "Bonmin Guessing";
409      h.heuristic = guessHeu;
410      heuristics_.push_back (h);
411      //model_.addHeuristic(guessHeu);
412      //delete guessHeu;
413    }
414#endif
415
416    // Add Branching rules ///////////////////////////////////////////////////////
417
418    int varSelection;
419    if (!options_->GetEnumValue("variable_selection",varSelection,"bonmin.")) {
420      // change the default for Couenne
421      varSelection = OSI_SIMPLE;
422    }
423
424    switch (varSelection) {
425
426    case OSI_STRONG: { // strong branching
427      CouenneChooseStrong * chooseVariable = new CouenneChooseStrong
428        (*this, couenneProb, journalist ());
429      chooseVariable->setTrustStrongForSolution(false);
430      chooseVariable->setTrustStrongForBound(false);
431      chooseVariable->setOnlyPseudoWhenTrusted(true);
432      branchingMethod_ = chooseVariable;
433      break;
434    }
435
436    case OSI_SIMPLE: // default choice
437      branchingMethod_ = new CouenneChooseVariable
438        (continuousSolver_, couenneProb, journalist ());
439      break;
440
441    default:
442      std::cerr << "Unknown variable_selection for Couenne\n" << std::endl;
443      throw;
444      break;
445    }
446
447    // Add disjunctive cuts ///////////////////////////////////////////////////////
448
449    options () -> GetIntegerValue ("minlp_disj_cuts", freq, "couenne.");
450
451    if (freq != 0) {
452
453      CouenneDisjCuts * couenneDisj = 
454        new CouenneDisjCuts (ci, this, 
455                             couenneCg, 
456                             branchingMethod_, 
457                             varSelection == OSI_STRONG, // if true, use strong branching candidates
458                             journalist (),
459                             options ());
460
461      CuttingMethod cg;
462      cg.frequency = freq;
463      cg.cgl = couenneDisj;
464      cg.id = "Couenne disjunctive cuts";
465      cutGenerators (). push_back(cg);
466    }
467
468    int ival;
469    if (!options_->GetEnumValue("node_comparison",ival,"bonmin.")) {
470      // change default for Couenne
471      nodeComparisonMethod_ = bestBound;
472    }
473    else {
474      nodeComparisonMethod_ = NodeComparison(ival);
475    }
476
477    if(intParam_[NumCutPasses] < 2)
478    intParam_[NumCutPasses] = 2;
479
480    // Tell Cbc not to check again if a solution returned from
481    // heuristic is indeed feasible
482    intParam_[BabSetupBase::SpecialOption] = 16 | 4;
483
484    return true;
485  }
486 
487  void CouenneSetup::registerOptions(){
488    registerAllOptions(roptions());
489  }
490
491
492  void
493  CouenneSetup::registerAllOptions(Ipopt::SmartPtr<Bonmin::RegisteredOptions> roptions){
494    BabSetupBase::registerAllOptions(roptions);
495    BonCbcFullNodeInfo::registerOptions(roptions);
496    CouenneCutGenerator::registerOptions (roptions);
497    CouenneDisjCuts::registerOptions (roptions);
498
499    roptions -> AddNumberOption
500      ("couenne_check",
501       "known value of a global optimum",
502       COIN_DBL_MAX,
503       "Default value is +infinity.");
504
505    roptions -> AddStringOption2 (
506      "display_stats",
507      "display statistics at the end of the run",
508      "no",
509      "yes", "",
510      "no", "");
511
512    roptions -> AddStringOption2 (
513      "test_mode",
514      "set to true if this is Couenne unit test",
515      "no",
516      "yes", "",
517      "no", "");
518
519    roptions->AddBoundedIntegerOption(
520      "branching_print_level", "Output level for braching code in Couenne",
521      -2, J_LAST_LEVEL-1, J_NONE, "");
522
523    roptions->AddBoundedIntegerOption(
524      "boundtightening_print_level", "Output level for bound tightening code in Couenne",
525      -2, J_LAST_LEVEL-1, J_NONE, "");
526
527    roptions->AddBoundedIntegerOption(
528      "convexifying_print_level", "Output level for convexifying code in Couenne",
529      -2, J_LAST_LEVEL-1, J_NONE, "");
530
531    roptions->AddBoundedIntegerOption(
532      "problem_print_level", "Output level for problem manipulation code in Couenne",
533      -2, J_LAST_LEVEL-1, J_WARNING, "");
534
535    roptions->AddBoundedIntegerOption(
536      "nlpheur_print_level", "Output level for NLP heuristic in Couenne",
537      -2, J_LAST_LEVEL-1, J_WARNING, "");
538
539    roptions->AddBoundedIntegerOption(
540    "disjcuts_print_level", "Output level for disjunctive cuts in Couenne",
541    -2, J_LAST_LEVEL-1, J_WARNING, "");
542
543    roptions->AddBoundedIntegerOption(
544    "reformulate_print_level", "Output level for reformulating problems in Couenne",
545    -2, J_LAST_LEVEL-1, J_WARNING, "");
546
547
548    // copied from BonminSetup::registerMilpCutGenerators(), in
549    // BonBonminSetup.cpp
550
551    struct cutOption_ {
552
553      const char *cgname;
554      int         defaultFreq;
555
556    } cutOption [] = {
557      {(const char *) "Gomory_cuts",             0},
558      {(const char *) "probing_cuts",            0},
559      {(const char *) "cover_cuts",              0},
560      {(const char *) "mir_cuts",                0},
561      {(const char *) "2mir_cuts",               0},
562      {(const char *) "flow_covers_cuts",        0},
563      {(const char *) "lift_and_project_cuts",   0},
564      {(const char *) "reduce_split_cuts",       0},
565      {(const char *) "clique_cuts",             0},
566      {NULL, 0}};
567
568    for (int i=0; cutOption [i].cgname; i++) {
569
570      char descr [150];
571
572      sprintf (descr, "Frequency k (in terms of nodes) for generating %s cuts in branch-and-cut.",
573               cutOption [i].cgname);
574
575      roptions -> AddLowerBoundedIntegerOption
576        (cutOption [i].cgname,
577         descr,
578         -100, cutOption [i].defaultFreq,
579         "If k > 0, cuts are generated every k nodes, "
580         "if -99 < k < 0 cuts are generated every -k nodes but "
581         "Cbc may decide to stop generating cuts, if not enough are generated at the root node, "
582         "if k=-99 generate cuts only at the root node, if k=0 or 100 do not generate cuts.");
583
584      roptions->setOptionExtraInfo (cutOption [i].cgname, 5);
585    }
586  }
587
588
589
590  /** Add milp cut generators according to options.*/
591  void CouenneSetup::addMilpCutGenerators () {
592
593    enum extraInfo_ {CUTINFO_NONE, CUTINFO_MIG, CUTINFO_PROBING, CUTINFO_CLIQUE};
594
595    struct cutInfo {
596
597      const char      *optname;
598      CglCutGenerator *cglptr;
599      const char      *cglId;
600      enum extraInfo_  extraInfo;
601
602    } cutList [] = {
603      {(const char*)"Gomory_cuts",new CglGomory,      (const char*)"Mixed Integer Gomory",CUTINFO_MIG},
604      {(const char*)"probing_cuts",new CglProbing,        (const char*) "Probing", CUTINFO_PROBING},
605      {(const char*)"mir_cuts",new CglMixedIntegerRounding2, (const char*) "Mixed Integer Rounding", 
606                                                                                        CUTINFO_NONE},
607      {(const char*)"2mir_cuts",    new CglTwomir,         (const char*) "2-MIR",    CUTINFO_NONE},
608      {(const char*)"cover_cuts",   new CglKnapsackCover,  (const char*) "Cover",    CUTINFO_NONE},
609      {(const char*)"clique_cuts",  new CglClique,         (const char*) "Clique",   CUTINFO_CLIQUE},
610      {(const char*)"lift_and_project_cuts",new CglLandP,(const char*)"Lift and Project",CUTINFO_NONE},
611      {(const char*)"reduce_split_cuts",new CglRedSplit,(const char*) "Reduce and Split",CUTINFO_NONE},
612      {(const char*)"flow_covers_cuts",new CglFlowCover,(const char*) "Flow cover cuts", CUTINFO_NONE},
613      {NULL, NULL, NULL, CUTINFO_NONE}};
614
615    int freq;
616
617    for (int i=0; cutList [i]. optname; i++) {
618
619      options_ -> GetIntegerValue (std::string (cutList [i]. optname), freq, "bonmin.");
620
621      if (!freq) {
622        delete cutList [i].cglptr;
623        continue;
624      }
625
626      CuttingMethod cg;
627      cg.frequency = freq;
628      cg.cgl       = cutList [i].cglptr;
629      cg.id        = std::string (cutList [i]. cglId);
630      cutGenerators_.push_back (cg);
631
632      // options for particular cases
633      switch (cutList [i].extraInfo) {
634
635      case CUTINFO_MIG: {
636        CglGomory *gc = dynamic_cast <CglGomory *> (cutList [i].cglptr);
637
638        if (!gc) break;
639
640        gc -> setLimitAtRoot(512);
641        gc -> setLimit(50);
642      }
643        break;
644
645      case CUTINFO_PROBING: {
646        CglProbing *pc = dynamic_cast <CglProbing *> (cutList [i].cglptr);
647
648        if (!pc) break;
649
650        pc->setUsingObjective(1);
651        pc->setMaxPass(3);
652        pc->setMaxPassRoot(3);
653        // Number of unsatisfied variables to look at
654        pc->setMaxProbe(10);
655        pc->setMaxProbeRoot(50);
656        // How far to follow the consequences
657        pc->setMaxLook(10);
658        pc->setMaxLookRoot(50);
659        pc->setMaxLookRoot(10);
660        // Only look at rows with fewer than this number of elements
661        pc->setMaxElements(200);
662        pc->setRowCuts(3);
663      }
664        break;
665
666      case CUTINFO_CLIQUE: {
667        CglClique *clique = dynamic_cast <CglClique *> (cutList [i].cglptr);
668
669        if (!clique) break;
670
671        clique -> setStarCliqueReport(false);
672        clique -> setRowCliqueReport(false);
673        clique -> setMinViolation(0.1);
674      }
675        break;
676
677        //case CUTINFO_NONE:
678      default:
679        break;
680      }
681    }
682  }
683}
Note: See TracBrowser for help on using the repository browser.