/home/coin/SVN-release/OS-2.0.0/Couenne/src/main/BonCouenneSetup.cpp

Go to the documentation of this file.
00001 /* $Id: BonCouenneSetup.cpp 154 2009-06-16 18:52:53Z pbelotti $ */
00002 // (C) Copyright International Business Machines Corporation 2007
00003 // All Rights Reserved.
00004 // This code is published under the Common Public License.
00005 //
00006 // Authors :
00007 // Pierre Bonami, International Business Machines Corporation
00008 //
00009 // Date : 04/18/2007
00010 
00011 #include "BonCouenneSetup.hpp"
00012 #include "BonInitHeuristic.hpp"
00013 #include "BonNlpHeuristic.hpp"
00014 #include "BonCouenneInterface.hpp"
00015 
00016 #include "BonGuessHeuristic.hpp"
00017 #include "CbcCompareActual.hpp"
00018 
00019 #include "CouenneObject.hpp"
00020 #include "CouenneComplObject.hpp"
00021 #include "CouenneVarObject.hpp"
00022 #include "CouenneVTObject.hpp"
00023 #include "CouenneChooseVariable.hpp"
00024 #include "CouenneChooseStrong.hpp"
00025 #include "CouenneSolverInterface.hpp"
00026 #include "CouenneCutGenerator.hpp"
00027 #include "CouenneDisjCuts.hpp"
00028 #include "BonCouenneInfo.hpp"
00029 #include "BonCbcNode.hpp"
00030 
00031 // MILP cuts
00032 #include "CglGomory.hpp"
00033 #include "CglProbing.hpp"
00034 #include "CglKnapsackCover.hpp"
00035 #include "CglOddHole.hpp"
00036 #include "CglClique.hpp"
00037 #include "CglFlowCover.hpp"
00038 #include "CglMixedIntegerRounding2.hpp"
00039 #include "CglTwomir.hpp"
00040 #include "CglPreProcess.hpp"
00041 #include "CglLandP.hpp"
00042 #include "CglRedSplit.hpp"
00043 
00044 // Ampl includes
00045 #ifdef COIN_HAS_ASL
00046 #include "asl.h"
00047 #include "getstub.h"
00048 #endif
00049 
00050 
00051 namespace Bonmin{
00052   
00053   SmartAsl::~SmartAsl(){
00054 #ifdef COIN_HAS_ASL
00055     //Code from Ipopt::AmplTNLP to free asl
00056     if(asl != NULL){
00057         if (X0) {
00058           delete [] X0;
00059           X0 = NULL;
00060         }
00061         if (havex0) {
00062           delete [] havex0;
00063           havex0 = NULL;
00064         }
00065         if (pi0) {
00066           delete [] pi0;
00067           pi0 = NULL;
00068         }
00069         if (havepi0) {
00070           delete [] havepi0;
00071           havepi0 = NULL;
00072         }
00073         ASL* asl_to_free = (ASL*)asl;
00074         ASL_free(&asl_to_free);
00075         asl = NULL;
00076     }
00077     ASL_free(&asl);
00078 #endif
00079   }
00080   
00081   CouenneSetup::~CouenneSetup(){
00082     //if (CouennePtr_)
00083     //delete CouennePtr_;
00084   }
00085 
00086   bool CouenneSetup::InitializeCouenne (char **& argv, 
00087                                         CouenneProblem *couenneProb,
00088                                         Bonmin::CouenneInterface *ci) {
00089     /* Get the basic options. */
00090     readOptionsFile();
00091  
00092     // in check mode, avoid pop-up error message (there are quite a few messages)
00093     std::string test_mode;
00094     options_ -> GetStringValue ("test_mode", test_mode, "couenne.");
00095     if (test_mode == "yes")
00096       WindowsErrorPopupBlocker();
00097 
00101     options_->SetStringValue ("nlp_failure_behavior", "fathom", "bonmin.");
00102 
00103     gatherParametersValues(options_);
00104 
00105     continuousSolver_ = new CouenneSolverInterface;
00106 
00107     if (!ci) {
00108 
00109       ci = new CouenneInterface;
00110 
00111       if (!couenneProb && argv) {
00112 #ifdef COIN_HAS_ASL
00113         /* Read the model in various places. */
00114         ci->readAmplNlFile(argv,roptions(),options(),journalist());
00115         aslfg_ = new SmartAsl;
00116         aslfg_->asl = readASLfg (argv);
00117 #else
00118             std::cerr << "Couenne was compiled without AMPL Solver Library. Cannot initialize from AMPL NL File." << std::endl;
00119             return false;
00120 #endif
00121       } 
00122     }
00123 
00124     nonlinearSolver_ = ci;
00125 
00129     int i;
00130 
00131     options()->GetIntegerValue("boundtightening_print_level", i, "bonmin.");
00132     journalist()->GetJournal("console")-> SetPrintLevel(J_BOUNDTIGHTENING, (EJournalLevel) i);
00133 
00134     options()->GetIntegerValue("branching_print_level", i, "bonmin.");
00135     journalist()->GetJournal("console")-> SetPrintLevel(J_BRANCHING, (EJournalLevel) i);
00136 
00137     options()->GetIntegerValue("convexifying_print_level", i, "bonmin.");
00138     journalist()->GetJournal("console")-> SetPrintLevel(J_CONVEXIFYING, (EJournalLevel) i);
00139 
00140     options()->GetIntegerValue("problem_print_level", i, "bonmin.");
00141     journalist()->GetJournal("console")-> SetPrintLevel(J_PROBLEM, (EJournalLevel) i);
00142 
00143     options()->GetIntegerValue("nlpheur_print_level", i, "bonmin.");
00144     journalist()->GetJournal("console")-> SetPrintLevel(J_NLPHEURISTIC, (EJournalLevel) i);
00145 
00146     options()->GetIntegerValue("disjcuts_print_level", i, "bonmin.");
00147     journalist()->GetJournal("console")-> SetPrintLevel(J_DISJCUTS, (EJournalLevel) i);
00148 
00149     options()->GetIntegerValue("reformulate_print_level", i, "bonmin.");
00150     journalist()->GetJournal("console")-> SetPrintLevel(J_REFORMULATE, (EJournalLevel) i);
00151 
00152     /* Initialize Couenne cut generator.*/
00153     //int ivalue, num_points;
00154     //options()->GetEnumValue("convexification_type", ivalue,"bonmin.");
00155     //options()->GetIntegerValue("convexification_points",num_points,"bonmin.");
00156     
00157     CouenneCutGenerator * couenneCg = 
00158       new CouenneCutGenerator (ci, this, couenneProb ? NULL : aslfg_->asl);
00159 
00160     if (!couenneProb) couenneProb = couenneCg -> Problem();
00161     else {
00162       couenneCg   -> setProblem (couenneProb);
00163       couenneProb -> setBase    (this);
00164     }
00165 
00166     assert (couenneProb);
00167 
00168     couenneProb -> reformulate ();
00169 
00170     Bonmin::BabInfo * extraStuff = new Bonmin::CouenneInfo(0);
00171 
00172     // as per instructions by John Forrest, to get changed bounds
00173     extraStuff -> setExtraCharacteristics (extraStuff -> extraCharacteristics () | 2);
00174 
00175     continuousSolver_ -> setAuxiliaryInfo (extraStuff);
00176     delete extraStuff;
00177     
00178     extraStuff = dynamic_cast <Bonmin::BabInfo *> (continuousSolver_ -> getAuxiliaryInfo ());
00179 
00180     /* Setup log level*/
00181     int lpLogLevel;
00182     options()->GetIntegerValue("lp_log_level",lpLogLevel,"bonmin.");
00183     continuousSolver_->messageHandler()->setLogLevel(lpLogLevel);
00184 
00186 
00187     couenneCg -> Problem () -> setMaxCpuTime (getDoubleParameter (BabSetupBase::MaxTime));
00188 
00189     ci -> extractLinearRelaxation (*continuousSolver_, *couenneCg);
00190 
00191     // In case there are no discrete variables, we have already a
00192     // heuristic solution for which create a initialization heuristic
00193     if (!(extraStuff -> infeasibleNode ()) &&
00194         ci -> isProvenOptimal () && 
00195         ci -> haveNlpSolution ()) {
00196 
00198       InitHeuristic* initHeuristic = new InitHeuristic 
00199         (ci -> getObjValue (), ci -> getColSolution (), *couenneProb);
00200       HeuristicMethod h;
00201       h.id = "Init Rounding NLP";
00202       h.heuristic = initHeuristic;
00203       heuristics_.push_back(h);
00204     }
00205 
00206     if (extraStuff -> infeasibleNode ()){
00207       std::cout<<"Initial linear relaxation constructed by Couenne is infeasible, exiting..."
00208                <<std::endl;
00209       return false;
00210     }
00211 
00212     //continuousSolver_ -> findIntegersAndSOS (false);
00213     //addSos (); // only adds embedded SOS objects
00214 
00215     // Add Couenne SOS ///////////////////////////////////////////////////////////////
00216 
00217     std::string s;
00218 
00219     int 
00220       nSOS  = 0,
00221       nVars = couenneProb -> nVars ();
00222 
00223     OsiObject ** objects = NULL;
00224 
00225     options () -> GetStringValue ("enable_sos", s, "couenne.");
00226     if (s == "yes") {
00227 
00228       // allocate sufficient space for both nonlinear variables and SOS's
00229       objects = new OsiObject* [couenneProb -> nCons () + nVars];
00230 
00231       nSOS = couenneProb -> findSOS (nonlinearSolver (), objects);
00232 
00233       nonlinearSolver () -> addObjects (nSOS, objects);
00234 
00235       //printf ("==================== found %d SOS\n", nSOS);
00236       //nonlinearSolver () -> addObjects (nSOS, objects);
00237       //continuousSolver () -> addObjects (nSOS, objects);
00238 
00239       //printf ("found %d SOS!\n", nSOS);
00240 
00241       /*for (int i=0; i<nSOS; i++)
00242         delete objects [i];
00243         delete [] objects;*/
00244 
00245       if (!nSOS) {
00246         delete [] objects;
00247         objects = NULL;
00248       } 
00249     }
00250 
00251     //model -> assignSolver (continuousSolver_, true);
00252     //continuousSolver_ = model -> solver();
00253 
00254     // Add Couenne objects for branching /////////////////////////////////////////////
00255 
00256     options () -> GetStringValue ("display_stats", s, "couenne.");
00257     displayStats_ = (s == "yes");
00258 
00259     options () -> GetStringValue ("branching_object", s, "couenne.");
00260 
00261     enum CouenneObject::branch_obj objType = CouenneObject::VAR_OBJ;
00262 
00263     if      (s ==   "vt_obj") objType = CouenneObject::VT_OBJ;
00264     else if (s ==  "var_obj") objType = CouenneObject::VAR_OBJ;
00265     else if (s == "expr_obj") objType = CouenneObject::EXPR_OBJ;
00266     else {
00267       printf ("CouenneSetup: Unknown branching object type\n");
00268       exit (-1);
00269     }
00270 
00271     int 
00272       nobj = nSOS; // if no SOS then objects is empty
00273 
00274     if (!objects)
00275       objects = new OsiObject* [nVars];
00276 
00277     int contObjPriority = 2000; // default object priority -- it is 1000 for integers and 10 for SOS
00278 
00279     options () -> GetIntegerValue ("cont_var_priority", contObjPriority, "bonmin.");
00280 
00281     for (int i = 0; i < nVars; i++) { // for each variable
00282 
00283       exprVar *var = couenneProb -> Var (i);
00284 
00285       // we only want enabled variables
00286       if (var -> Multiplicity () <= 0) 
00287         continue;
00288 
00289       switch (objType) {
00290 
00291       case CouenneObject::EXPR_OBJ:
00292 
00293         // if this variable is associated with a nonlinear function
00294         if (var -> isInteger () || 
00295             (var -> Type  () == AUX) && 
00296             (var -> Image () -> Linearity () > LINEAR)) {
00297 
00298           /*if ((var -> Image () -> code () == COU_EXPRMUL) &&
00299               (var -> Image () -> ArgList () [0] -> Index () >= 0) &&
00300               (var -> Image () -> ArgList () [1] -> Index () >= 0) &&
00301               (fabs (var -> lb ()) < COUENNE_EPS) &&
00302               (fabs (var -> ub ()) < COUENNE_EPS))
00303 
00304             // it's a complementarity constraint object!
00305             objects    [nobj] = new CouenneComplObject (couenneProb, var, this, journalist ());
00306             else*/
00307           objects [nobj] = new CouenneObject      (couenneProb, var, this, journalist ());
00308 
00309           objects [nobj++] -> setPriority (contObjPriority);
00310           //objects [nobj++] -> setPriority (contObjPriority + var -> rank ());
00311         }
00312 
00313         break;
00314 
00315       case CouenneObject::VAR_OBJ:
00316 
00317         // branching objects on variables
00318         if // comment three lines below for linear variables too
00319           (var -> isInteger () || 
00320            (couenneProb -> Dependence () [var -> Index ()] . size () > 0)) {  // has indep
00321            //|| ((var -> Type () == AUX) &&                                  // or, aux 
00322            //    (var -> Image () -> Linearity () > LINEAR))) {              // of nonlinear
00323 
00324           objects [nobj] = new CouenneVarObject (couenneProb, var, this, journalist ());
00325           objects [nobj++] -> setPriority (contObjPriority);
00326           //objects [nobj++] -> setPriority (contObjPriority + var -> rank ());
00327         }
00328 
00329         break;
00330 
00331       default:
00332       case CouenneObject::VT_OBJ:
00333 
00334         // branching objects on variables
00335         if // comment three lines below for linear variables too
00336           (var -> isInteger () || 
00337            (couenneProb -> Dependence () [var -> Index ()] . size () > 0)) { // has indep
00338           //|| ((var -> Type () == AUX) &&                      // or, aux 
00339           //(var -> Image () -> Linearity () > LINEAR))) { // of nonlinear
00340 
00341           objects [nobj] = new CouenneVTObject (couenneProb, var, this, journalist ());
00342           objects [nobj++] -> setPriority (contObjPriority);
00343           //objects [nobj++] -> setPriority (contObjPriority + var -> rank ());
00344         }
00345 
00346         break;
00347       }
00348     }
00349 
00350     // Add objects /////////////////////////////////
00351 
00352     continuousSolver_ -> addObjects (nobj, objects);
00353 
00354     for (int i = 0 ; i < nobj ; i++)
00355       delete objects [i];
00356 
00357     delete [] objects;
00358 
00359     // Setup Convexifier generators ////////////////////////////////////////////////
00360 
00361     int freq;
00362 
00363     options()->GetIntegerValue("convexification_cuts",freq,"couenne.");
00364 
00365     if (freq != 0) {
00366 
00367       CuttingMethod cg;
00368       cg.frequency = freq;
00369       cg.cgl = couenneCg;
00370       cg.id = "Couenne convexifier cuts";
00371       cutGenerators().push_back(cg);
00372 
00373       // set cut gen pointer
00374       dynamic_cast <CouenneSolverInterface *> 
00375         (continuousSolver_) -> setCutGenPtr (couenneCg);
00376     }
00377 
00378     // disjunctive cuts generator added AFTER 
00379 
00380     // add other cut generators -- test for integer variables first
00381     if (couenneCg -> Problem () -> nIntVars () > 0)
00382       addMilpCutGenerators ();
00383 
00384     CouennePtr_ = couenneCg;
00385 
00386     // Setup heuristic to solve nlp problems. /////////////////////////////////
00387 
00388     int doNlpHeurisitic = 0;
00389     options()->GetEnumValue("local_optimization_heuristic", doNlpHeurisitic, "couenne.");
00390     if(doNlpHeurisitic)
00391     {
00392       int numSolve;
00393       options()->GetIntegerValue("log_num_local_optimization_per_level",numSolve,"couenne.");
00394       NlpSolveHeuristic * nlpHeuristic = new NlpSolveHeuristic;
00395       nlpHeuristic->setNlp(*ci,false);
00396       nlpHeuristic->setCouenneProblem(couenneProb);
00397       //nlpHeuristic->setMaxNlpInf(1e-4);
00398       nlpHeuristic->setMaxNlpInf(maxNlpInf_0);
00399       nlpHeuristic->setNumberSolvePerLevel(numSolve);
00400       HeuristicMethod h;
00401       h.id = "Couenne Rounding NLP";
00402       h.heuristic = nlpHeuristic;
00403       heuristics_.push_back(h);
00404     }
00405 
00406 #if 0
00407     {
00408       CbcCompareEstimate compare;
00409       model -> setNodeComparison(compare);
00410       GuessHeuristic * guessHeu = new GuessHeuristic (*model);
00411       HeuristicMethod h;
00412       h.id = "Bonmin Guessing";
00413       h.heuristic = guessHeu;
00414       heuristics_.push_back (h);
00415       //model_.addHeuristic(guessHeu);
00416       //delete guessHeu;
00417     }
00418 #endif
00419 
00420     // Add Branching rules ///////////////////////////////////////////////////////
00421 
00422     int varSelection;
00423     if (!options_->GetEnumValue("variable_selection",varSelection,"bonmin.")) {
00424       // change the default for Couenne
00425       varSelection = OSI_SIMPLE;
00426     }
00427 
00428     switch (varSelection) {
00429 
00430     case OSI_STRONG: { // strong branching
00431       CouenneChooseStrong * chooseVariable = new CouenneChooseStrong
00432         (*this, couenneProb, journalist ());
00433       chooseVariable->setTrustStrongForSolution(false);
00434       chooseVariable->setTrustStrongForBound(false);
00435       chooseVariable->setOnlyPseudoWhenTrusted(true);
00436       branchingMethod_ = chooseVariable;
00437       break;
00438     }
00439 
00440     case OSI_SIMPLE: // default choice
00441       branchingMethod_ = new CouenneChooseVariable 
00442         (continuousSolver_, couenneProb, journalist ());
00443       break;
00444 
00445     default:
00446       std::cerr << "Unknown variable_selection for Couenne\n" << std::endl;
00447       throw;
00448       break;
00449     }
00450 
00451     // Add disjunctive cuts ///////////////////////////////////////////////////////
00452 
00453     options () -> GetIntegerValue ("minlp_disj_cuts", freq, "couenne.");
00454 
00455     if (freq != 0) {
00456 
00457       CouenneDisjCuts * couenneDisj = 
00458         new CouenneDisjCuts (ci, this, 
00459                              couenneCg, 
00460                              branchingMethod_, 
00461                              varSelection == OSI_STRONG, // if true, use strong branching candidates
00462                              journalist (),
00463                              options ());
00464 
00465       CuttingMethod cg;
00466       cg.frequency = freq;
00467       cg.cgl = couenneDisj;
00468       cg.id = "Couenne disjunctive cuts";
00469       cutGenerators (). push_back(cg);
00470     }
00471 
00472     int ival;
00473     if (!options_->GetEnumValue("node_comparison",ival,"bonmin.")) {
00474       // change default for Couenne
00475       nodeComparisonMethod_ = bestBound;
00476     }
00477     else {
00478       nodeComparisonMethod_ = NodeComparison(ival);
00479     }
00480 
00481     if(intParam_[NumCutPasses] < 2)
00482     intParam_[NumCutPasses] = 2;
00483 
00484     // Tell Cbc not to check again if a solution returned from
00485     // heuristic is indeed feasible
00486     intParam_[BabSetupBase::SpecialOption] = 16 | 4;
00487 
00488     return true;
00489   }
00490  
00491   void CouenneSetup::registerOptions(){
00492     registerAllOptions(roptions());
00493   }
00494 
00495 
00496   void
00497   CouenneSetup::registerAllOptions(Ipopt::SmartPtr<Bonmin::RegisteredOptions> roptions){
00498     BabSetupBase::registerAllOptions(roptions);
00499     BonCbcFullNodeInfo::registerOptions(roptions);
00500     CouenneCutGenerator::registerOptions (roptions);
00501     CouenneDisjCuts::registerOptions (roptions);
00502 
00503     roptions -> AddNumberOption
00504       ("couenne_check",
00505        "known value of a global optimum",
00506        COIN_DBL_MAX,
00507        "Default value is +infinity.");
00508 
00509     roptions -> AddStringOption2 (
00510       "display_stats",
00511       "display statistics at the end of the run",
00512       "no",
00513       "yes", "",
00514       "no", "");
00515 
00516     roptions -> AddStringOption2 (
00517       "test_mode",
00518       "set to true if this is Couenne unit test",
00519       "no",
00520       "yes", "",
00521       "no", "");
00522 
00523     roptions->AddBoundedIntegerOption(
00524       "branching_print_level", "Output level for braching code in Couenne",
00525       -2, J_LAST_LEVEL-1, J_NONE, "");
00526 
00527     roptions->AddBoundedIntegerOption(
00528       "boundtightening_print_level", "Output level for bound tightening code in Couenne",
00529       -2, J_LAST_LEVEL-1, J_NONE, "");
00530 
00531     roptions->AddBoundedIntegerOption(
00532       "convexifying_print_level", "Output level for convexifying code in Couenne",
00533       -2, J_LAST_LEVEL-1, J_NONE, "");
00534 
00535     roptions->AddBoundedIntegerOption(
00536       "problem_print_level", "Output level for problem manipulation code in Couenne",
00537       -2, J_LAST_LEVEL-1, J_WARNING, "");
00538 
00539     roptions->AddBoundedIntegerOption(
00540       "nlpheur_print_level", "Output level for NLP heuristic in Couenne",
00541       -2, J_LAST_LEVEL-1, J_WARNING, "");
00542 
00543     roptions->AddBoundedIntegerOption(
00544     "disjcuts_print_level", "Output level for disjunctive cuts in Couenne",
00545     -2, J_LAST_LEVEL-1, J_WARNING, "");
00546 
00547     roptions->AddBoundedIntegerOption(
00548     "reformulate_print_level", "Output level for reformulating problems in Couenne",
00549     -2, J_LAST_LEVEL-1, J_WARNING, "");
00550 
00551 
00552     // copied from BonminSetup::registerMilpCutGenerators(), in
00553     // BonBonminSetup.cpp
00554 
00555     struct cutOption_ {
00556 
00557       const char *cgname;
00558       int         defaultFreq;
00559 
00560     } cutOption [] = {
00561       {(const char *) "Gomory_cuts",             0},
00562       {(const char *) "probing_cuts",            0},
00563       {(const char *) "cover_cuts",              0},
00564       {(const char *) "mir_cuts",                0},
00565       {(const char *) "2mir_cuts",               0},
00566       {(const char *) "flow_covers_cuts",        0},
00567       {(const char *) "lift_and_project_cuts",   0},
00568       {(const char *) "reduce_split_cuts",       0},
00569       {(const char *) "clique_cuts",             0},
00570       {NULL, 0}};
00571 
00572     for (int i=0; cutOption [i].cgname; i++) {
00573 
00574       char descr [150];
00575 
00576       sprintf (descr, "Frequency k (in terms of nodes) for generating %s cuts in branch-and-cut.",
00577                cutOption [i].cgname);
00578 
00579       roptions -> AddLowerBoundedIntegerOption 
00580         (cutOption [i].cgname,
00581          descr,
00582          -100, cutOption [i].defaultFreq,
00583          "If k > 0, cuts are generated every k nodes, "
00584          "if -99 < k < 0 cuts are generated every -k nodes but "
00585          "Cbc may decide to stop generating cuts, if not enough are generated at the root node, "
00586          "if k=-99 generate cuts only at the root node, if k=0 or 100 do not generate cuts.");
00587 
00588       roptions->setOptionExtraInfo (cutOption [i].cgname, 5);
00589     }
00590   }
00591 
00592 
00593 
00595   void CouenneSetup::addMilpCutGenerators () {
00596 
00597     enum extraInfo_ {CUTINFO_NONE, CUTINFO_MIG, CUTINFO_PROBING, CUTINFO_CLIQUE};
00598 
00599     struct cutInfo {
00600 
00601       const char      *optname;
00602       CglCutGenerator *cglptr;
00603       const char      *cglId;
00604       enum extraInfo_  extraInfo;
00605 
00606     } cutList [] = {
00607       {(const char*)"Gomory_cuts",new CglGomory,      (const char*)"Mixed Integer Gomory",CUTINFO_MIG},
00608       {(const char*)"probing_cuts",new CglProbing,        (const char*) "Probing", CUTINFO_PROBING},
00609       {(const char*)"mir_cuts",new CglMixedIntegerRounding2, (const char*) "Mixed Integer Rounding", 
00610                                                                                         CUTINFO_NONE},
00611       {(const char*)"2mir_cuts",    new CglTwomir,         (const char*) "2-MIR",    CUTINFO_NONE},
00612       {(const char*)"cover_cuts",   new CglKnapsackCover,  (const char*) "Cover",    CUTINFO_NONE},
00613       {(const char*)"clique_cuts",  new CglClique,         (const char*) "Clique",   CUTINFO_CLIQUE},
00614       {(const char*)"lift_and_project_cuts",new CglLandP,(const char*)"Lift and Project",CUTINFO_NONE},
00615       {(const char*)"reduce_split_cuts",new CglRedSplit,(const char*) "Reduce and Split",CUTINFO_NONE},
00616       {(const char*)"flow_covers_cuts",new CglFlowCover,(const char*) "Flow cover cuts", CUTINFO_NONE},
00617       {NULL, NULL, NULL, CUTINFO_NONE}};
00618 
00619     int freq;
00620 
00621     for (int i=0; cutList [i]. optname; i++) {
00622 
00623       options_ -> GetIntegerValue (std::string (cutList [i]. optname), freq, "bonmin.");
00624 
00625       if (!freq) {
00626         delete cutList [i].cglptr;
00627         continue;
00628       }
00629 
00630       CuttingMethod cg;
00631       cg.frequency = freq;
00632       cg.cgl       = cutList [i].cglptr;
00633       cg.id        = std::string (cutList [i]. cglId);
00634       cutGenerators_.push_back (cg);
00635 
00636       // options for particular cases
00637       switch (cutList [i].extraInfo) {
00638 
00639       case CUTINFO_MIG: {
00640         CglGomory *gc = dynamic_cast <CglGomory *> (cutList [i].cglptr);
00641 
00642         if (!gc) break;
00643 
00644         gc -> setLimitAtRoot(512);
00645         gc -> setLimit(50);
00646       }
00647         break;
00648 
00649       case CUTINFO_PROBING: {
00650         CglProbing *pc = dynamic_cast <CglProbing *> (cutList [i].cglptr);
00651 
00652         if (!pc) break;
00653 
00654         pc->setUsingObjective(1);
00655         pc->setMaxPass(3);
00656         pc->setMaxPassRoot(3);
00657         // Number of unsatisfied variables to look at
00658         pc->setMaxProbe(10);
00659         pc->setMaxProbeRoot(50);
00660         // How far to follow the consequences
00661         pc->setMaxLook(10);
00662         pc->setMaxLookRoot(50);
00663         pc->setMaxLookRoot(10);
00664         // Only look at rows with fewer than this number of elements
00665         pc->setMaxElements(200);
00666         pc->setRowCuts(3);
00667       }
00668         break;
00669 
00670       case CUTINFO_CLIQUE: {
00671         CglClique *clique = dynamic_cast <CglClique *> (cutList [i].cglptr);
00672 
00673         if (!clique) break;
00674 
00675         clique -> setStarCliqueReport(false);
00676         clique -> setRowCliqueReport(false);
00677         clique -> setMinViolation(0.1);
00678       }
00679         break;
00680 
00681         //case CUTINFO_NONE:
00682       default:
00683         break;
00684       }
00685     }
00686   }
00687 }

Generated on Mon Aug 3 03:02:16 2009 by  doxygen 1.4.7