source: stable/0.2/Couenne/src/main/BonCouenneSetup.cpp @ 159

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

created new stable branch 0.2 from trunk (rev. 157)

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