00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #include "BonCouenneSetup.hpp"
00013 #include "BonInitHeuristic.hpp"
00014 #include "BonNlpHeuristic.hpp"
00015 #include "BonCouenneInterface.hpp"
00016
00017 #include "BonGuessHeuristic.hpp"
00018 #include "CbcCompareActual.hpp"
00019
00020 #include "CouenneObject.hpp"
00021
00022 #include "CouenneVarObject.hpp"
00023 #include "CouenneVTObject.hpp"
00024 #include "CouenneOrbitObj.hpp"
00025 #include "CouenneChooseVariable.hpp"
00026 #include "CouenneChooseStrong.hpp"
00027 #include "CouenneSolverInterface.hpp"
00028 #include "CouenneCutGenerator.hpp"
00029 #include "CouenneDisjCuts.hpp"
00030
00031 #include "BonCouenneInfo.hpp"
00032 #include "BonCbcNode.hpp"
00033
00034 #include "OsiClpSolverInterface.hpp"
00035 #ifdef COIN_HAS_CPX
00036 #include "OsiCpxSolverInterface.hpp"
00037 #endif
00038
00039
00040 #include "CglGomory.hpp"
00041 #include "CglProbing.hpp"
00042 #include "CglKnapsackCover.hpp"
00043 #include "CglOddHole.hpp"
00044 #include "CglClique.hpp"
00045 #include "CglFlowCover.hpp"
00046 #include "CglMixedIntegerRounding2.hpp"
00047 #include "CglTwomir.hpp"
00048 #include "CglPreProcess.hpp"
00049 #include "CglLandP.hpp"
00050 #include "CglRedSplit.hpp"
00051
00052
00053 #ifdef COIN_HAS_ASL
00054 #include "asl.h"
00055 #include "getstub.h"
00056 #endif
00057
00058
00059 namespace Bonmin{
00060
00061 SmartAsl::~SmartAsl(){
00062 #ifdef COIN_HAS_ASL
00063
00064 if(asl != NULL){
00065 if (X0) {
00066 delete [] X0;
00067 X0 = NULL;
00068 }
00069 if (havex0) {
00070 delete [] havex0;
00071 havex0 = NULL;
00072 }
00073 if (pi0) {
00074 delete [] pi0;
00075 pi0 = NULL;
00076 }
00077 if (havepi0) {
00078 delete [] havepi0;
00079 havepi0 = NULL;
00080 }
00081 ASL* asl_to_free = (ASL*)asl;
00082 ASL_free(&asl_to_free);
00083 asl = NULL;
00084 }
00085 ASL_free(&asl);
00086 #endif
00087 }
00088
00089 CouenneSetup::~CouenneSetup(){
00090 if (couenneProb_ && couenneProb_is_own_)
00091 delete couenneProb_;
00092 }
00093
00094 bool CouenneSetup::InitializeCouenne (char ** argv,
00095 CouenneProblem *couenneProb,
00096 Ipopt::SmartPtr<Bonmin::TMINLP> tminlp,
00097 Bonmin::CouenneInterface *ci) {
00098 std::string s;
00099
00100 if (couenneProb) {
00101
00102 couenneProb_ = couenneProb;
00103 couenneProb_is_own_ = false;
00104 }
00105
00106
00107 readOptionsFile();
00108
00109
00110 options_ -> GetStringValue ("test_mode", s, "couenne.");
00111 if (s == "yes")
00112 WindowsErrorPopupBlocker();
00113
00117 options_ -> SetStringValue ("nlp_failure_behavior", "fathom", "bonmin.");
00118
00119 gatherParametersValues (options_);
00120
00121 if (!ci) {
00122
00123 ci = new CouenneInterface;
00124
00125 if (!couenneProb_ && argv) {
00126 #ifdef COIN_HAS_ASL
00127
00128 ci -> readAmplNlFile (argv, roptions (), options (), journalist ());
00129 aslfg_ = new SmartAsl;
00130 aslfg_ -> asl = readASLfg (argv);
00131 #else
00132 std::cerr <<
00133 "Couenne was compiled without AMPL Solver Library. Cannot initialize from AMPL NL File."
00134 << std::endl;
00135 return false;
00136 #endif
00137 } else {
00138 assert(couenneProb_ != NULL);
00139 assert(IsValid(tminlp));
00140 ci -> initialize(roptions_, options_, journalist_, tminlp);
00141 }
00142 }
00143
00144 nonlinearSolver_ = ci;
00145
00149 int i;
00150
00151 options()->GetIntegerValue("boundtightening_print_level", i, "bonmin.");
00152 journalist()->GetJournal("console")-> SetPrintLevel(J_BOUNDTIGHTENING, (EJournalLevel) i);
00153
00154 options()->GetIntegerValue("branching_print_level", i, "bonmin.");
00155 journalist()->GetJournal("console")-> SetPrintLevel(J_BRANCHING, (EJournalLevel) i);
00156
00157 options()->GetIntegerValue("convexifying_print_level", i, "bonmin.");
00158 journalist()->GetJournal("console")-> SetPrintLevel(J_CONVEXIFYING, (EJournalLevel) i);
00159
00160 options()->GetIntegerValue("problem_print_level", i, "bonmin.");
00161 journalist()->GetJournal("console")-> SetPrintLevel(J_PROBLEM, (EJournalLevel) i);
00162
00163 options()->GetIntegerValue("nlpheur_print_level", i, "bonmin.");
00164 journalist()->GetJournal("console")-> SetPrintLevel(J_NLPHEURISTIC, (EJournalLevel) i);
00165
00166 options()->GetIntegerValue("disjcuts_print_level", i, "bonmin.");
00167 journalist()->GetJournal("console")-> SetPrintLevel(J_DISJCUTS, (EJournalLevel) i);
00168
00169 options()->GetIntegerValue("reformulate_print_level", i, "bonmin.");
00170 journalist()->GetJournal("console")-> SetPrintLevel(J_REFORMULATE, (EJournalLevel) i);
00171
00172
00173
00174
00175
00176
00177 if (!couenneProb_)
00178 couenneProb_ = new CouenneProblem (aslfg_ -> asl, this, journalist ());
00179
00180 CouenneCutGenerator * couenneCg =
00181 new CouenneCutGenerator (ci, this, couenneProb_, NULL);
00182
00183 options_ -> GetStringValue ("lp_solver", s, "couenne.");
00184
00185 if (s == "clp") {
00186
00187 CouenneSolverInterface <OsiClpSolverInterface> *CSI
00188 = new CouenneSolverInterface <OsiClpSolverInterface>;
00189
00190 continuousSolver_ = CSI;
00191 CSI -> setCutGenPtr (couenneCg);
00192
00193 } else if (s == "cplex") {
00194
00195 #ifdef COIN_HAS_CPX
00196 CouenneSolverInterface <OsiCpxSolverInterface> *CSI
00197 = new CouenneSolverInterface <OsiCpxSolverInterface>;
00198
00199 continuousSolver_ = CSI;
00200 CSI -> setCutGenPtr (couenneCg);
00201 #else
00202 journalist()->Printf(J_ERROR, J_INITIALIZATION, "Couenne was compiled without CPLEX interface. Please reconfigure, recompile, and try again.\n");
00203 return false;
00204 #endif
00205 }
00206 continuousSolver_ -> passInMessageHandler(ci -> messageHandler());
00207
00208 couenneProb_ -> setBase (this);
00209
00210 assert (couenneProb_);
00211
00212 couenneProb_ -> reformulate (couenneCg);
00213
00214 Bonmin::BabInfo * extraStuff = new Bonmin::CouenneInfo(0);
00215
00216
00217 extraStuff -> setExtraCharacteristics (extraStuff -> extraCharacteristics () | 2);
00218
00219 continuousSolver_ -> setAuxiliaryInfo (extraStuff);
00220 delete extraStuff;
00221
00222 extraStuff = dynamic_cast <Bonmin::BabInfo *> (continuousSolver_ -> getAuxiliaryInfo ());
00223
00224
00225 int lpLogLevel;
00226 options()->GetIntegerValue("lp_log_level",lpLogLevel,"bonmin.");
00227 continuousSolver_->messageHandler()->setLogLevel(lpLogLevel);
00228
00230
00231 couenneCg -> Problem () -> setMaxCpuTime (getDoubleParameter (BabSetupBase::MaxTime));
00232
00233 ci -> extractLinearRelaxation (*continuousSolver_, *couenneCg);
00234
00235
00236
00237 if (!(extraStuff -> infeasibleNode ()) &&
00238 ci -> isProvenOptimal () &&
00239 ci -> haveNlpSolution ()) {
00240
00242 InitHeuristic* initHeuristic = new InitHeuristic
00243 (ci -> getObjValue (), ci -> getColSolution (), *couenneProb_);
00244 HeuristicMethod h;
00245 h.id = "Init Rounding NLP";
00246 h.heuristic = initHeuristic;
00247 heuristics_.push_back(h);
00248 }
00249
00250 if (extraStuff -> infeasibleNode ()){
00251 journalist() -> Printf(J_SUMMARY, J_PROBLEM, "Initial linear relaxation constructed by Couenne is infeasible, exiting...\n");
00252 return false;
00253 }
00254
00255
00256
00257
00258
00259
00260 int
00261 nSOS = 0,
00262 nVars = couenneProb_ -> nVars ();
00263
00264 OsiObject ** objects = NULL;
00265
00266 options () -> GetStringValue ("enable_sos", s, "couenne.");
00267
00268 if (s == "yes") {
00269
00270
00271 objects = new OsiObject* [couenneProb_ -> nCons () + nVars];
00272
00273 nSOS = couenneProb_ -> findSOS (nonlinearSolver (), objects);
00274
00275 nonlinearSolver () -> addObjects (nSOS, objects);
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287 if (!nSOS) {
00288 delete [] objects;
00289 objects = NULL;
00290 }
00291 }
00292
00293
00294
00295
00296
00297
00298 options () -> GetStringValue ("display_stats", s, "couenne.");
00299 displayStats_ = (s == "yes");
00300
00301 options () -> GetStringValue ("branching_object", s, "couenne.");
00302
00303 enum CouenneObject::branch_obj objType = CouenneObject::VAR_OBJ;
00304
00305 if (s == "vt_obj") objType = CouenneObject::VT_OBJ;
00306 else if (s == "var_obj") objType = CouenneObject::VAR_OBJ;
00307 else if (s == "expr_obj") objType = CouenneObject::EXPR_OBJ;
00308 else {
00309 printf ("CouenneSetup: Unknown branching object type\n");
00310 exit (-1);
00311 }
00312
00313 int
00314 nobj = nSOS;
00315
00316 if (!objects)
00317 objects = new OsiObject* [nVars];
00318
00319 int contObjPriority = 2000;
00320
00321 options () -> GetIntegerValue ("cont_var_priority", contObjPriority, "bonmin.");
00322
00323 for (int i = 0; i < nVars; i++) {
00324
00325 exprVar *var = couenneProb_ -> Var (i);
00326
00327
00328 if (var -> Multiplicity () <= 0)
00329 continue;
00330
00331 switch (objType) {
00332
00333 case CouenneObject::EXPR_OBJ:
00334
00335
00336 if (var -> isInteger () ||
00337 (var -> Type () == AUX) &&
00338 (var -> Image () -> Linearity () > LINEAR)) {
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349 objects [nobj] = new CouenneObject (couenneCg, couenneProb_, var, this, journalist ());
00350
00351 objects [nobj++] -> setPriority (contObjPriority);
00352
00353 }
00354
00355 break;
00356
00357 case CouenneObject::VAR_OBJ:
00358
00359
00360 if
00361 (var -> isInteger () ||
00362 (couenneProb_ -> Dependence () [var -> Index ()] . size () > 0)) {
00363
00364
00365
00366 objects [nobj] = new CouenneVarObject (couenneCg, couenneProb_, var, this, journalist ());
00367 objects [nobj++] -> setPriority (contObjPriority);
00368
00369 }
00370
00371 break;
00372
00373 default:
00374 case CouenneObject::VT_OBJ:
00375
00376
00377 if
00378 (var -> isInteger () ||
00379 (couenneProb_ -> Dependence () [var -> Index ()] . size () > 0)) {
00380
00381
00382
00383 objects [nobj] = new CouenneVTObject (couenneCg, couenneProb_, var, this, journalist ());
00384 objects [nobj++] -> setPriority (contObjPriority);
00385
00386 }
00387
00388 break;
00389 }
00390 }
00391
00392
00393 options () -> GetStringValue ("orbital_branching", s, "couenne.");
00394
00395 if (s == "yes") {
00396
00397 objects [nobj] = new CouenneOrbitObj (couenneCg, couenneProb_, NULL, this, journalist ());
00398 objects [nobj++] -> setPriority (contObjPriority);
00399 }
00400
00401
00402
00403 continuousSolver_ -> addObjects (nobj, objects);
00404
00405 for (int i = 0 ; i < nobj ; i++)
00406 delete objects [i];
00407
00408 delete [] objects;
00409
00410
00411
00412 int freq;
00413
00414 options()->GetIntegerValue("convexification_cuts",freq,"couenne.");
00415
00416 if (freq != 0) {
00417
00418 CuttingMethod cg;
00419 cg.frequency = freq;
00420 cg.cgl = couenneCg;
00421 cg.id = "Couenne convexifier cuts";
00422 cutGenerators().push_back(cg);
00423
00424
00425
00426
00427
00428
00429
00430 }
00431
00432
00433
00434
00435 if (couenneCg -> Problem () -> nIntVars () > 0)
00436 addMilpCutGenerators ();
00437
00438 CouennePtr_ = couenneCg;
00439
00440
00441
00442 int doNlpHeurisitic = 0;
00443 options()->GetEnumValue("local_optimization_heuristic", doNlpHeurisitic, "couenne.");
00444 if(doNlpHeurisitic)
00445 {
00446 int numSolve;
00447 options()->GetIntegerValue("log_num_local_optimization_per_level",numSolve,"couenne.");
00448 NlpSolveHeuristic * nlpHeuristic = new NlpSolveHeuristic;
00449 nlpHeuristic->setNlp(*ci,false);
00450 nlpHeuristic->setCouenneProblem(couenneProb_);
00451
00452 nlpHeuristic->setMaxNlpInf(maxNlpInf_0);
00453 nlpHeuristic->setNumberSolvePerLevel(numSolve);
00454 HeuristicMethod h;
00455 h.id = "Couenne Rounding NLP";
00456 h.heuristic = nlpHeuristic;
00457 heuristics_.push_back(h);
00458 }
00459
00460
00461
00462 int varSelection;
00463 if (!options_->GetEnumValue("variable_selection",varSelection,"bonmin.")) {
00464
00465 varSelection = OSI_SIMPLE;
00466 }
00467
00468 switch (varSelection) {
00469
00470 case OSI_STRONG: {
00471 CouenneChooseStrong * chooseVariable = new CouenneChooseStrong
00472 (*this, couenneProb_, journalist ());
00473 chooseVariable->setTrustStrongForSolution(false);
00474 chooseVariable->setTrustStrongForBound(false);
00475 chooseVariable->setOnlyPseudoWhenTrusted(true);
00476 branchingMethod_ = chooseVariable;
00477 break;
00478 }
00479
00480 case OSI_SIMPLE:
00481 branchingMethod_ = new CouenneChooseVariable
00482 (continuousSolver_, couenneProb_, journalist ());
00483 break;
00484
00485 default:
00486 std::cerr << "Unknown variable_selection for Couenne\n" << std::endl;
00487 throw;
00488 break;
00489 }
00490
00491
00492
00493 options () -> GetIntegerValue ("minlp_disj_cuts", freq, "couenne.");
00494
00495 if (freq != 0) {
00496
00497 CouenneDisjCuts * couenneDisj =
00498 new CouenneDisjCuts (ci, this,
00499 couenneCg,
00500 branchingMethod_,
00501 varSelection == OSI_STRONG,
00502 journalist (),
00503 options ());
00504
00505 CuttingMethod cg;
00506 cg.frequency = freq;
00507 cg.cgl = couenneDisj;
00508 cg.id = "Couenne disjunctive cuts";
00509 cutGenerators (). push_back(cg);
00510 }
00511
00512 int ival;
00513 if (!options_->GetEnumValue("node_comparison",ival,"bonmin.")) {
00514
00515 nodeComparisonMethod_ = bestBound;
00516 }
00517 else {
00518 nodeComparisonMethod_ = NodeComparison(ival);
00519 }
00520
00521 if(intParam_[NumCutPasses] < 2)
00522 intParam_[NumCutPasses] = 2;
00523
00524
00525
00526 intParam_[BabSetupBase::SpecialOption] = 16 | 4;
00527
00528 return true;
00529 }
00530
00531 bool CouenneSetup::InitializeCouenne (char ** argv,
00532 CouenneProblem *couenneProb,
00533 Bonmin::CouenneInterface *ci) {
00534 return InitializeCouenne(argv, couenneProb, ci ? ci->model() : NULL, ci);
00535 }
00536
00537 void CouenneSetup::registerOptions(){
00538 registerAllOptions(roptions());
00539 }
00540
00541
00542 void
00543 CouenneSetup::registerAllOptions(Ipopt::SmartPtr<Bonmin::RegisteredOptions> roptions){
00544 BabSetupBase::registerAllOptions(roptions);
00545 BonCbcFullNodeInfo::registerOptions(roptions);
00546 CouenneCutGenerator::registerOptions (roptions);
00547 CouenneDisjCuts::registerOptions (roptions);
00548
00549 roptions -> AddNumberOption
00550 ("couenne_check",
00551 "known value of a global optimum",
00552 COIN_DBL_MAX,
00553 "Default value is +infinity.");
00554
00555 roptions -> AddStringOption2 (
00556 "display_stats",
00557 "display statistics at the end of the run",
00558 "no",
00559 "yes", "",
00560 "no", "");
00561
00562 roptions -> AddStringOption2 (
00563 "test_mode",
00564 "set to true if this is Couenne unit test",
00565 "no",
00566 "yes", "",
00567 "no", "");
00568
00569 roptions -> AddStringOption3 (
00570 "lp_solver",
00571 "Linear Programming solver for the linearization",
00572 "clp",
00573 "clp", "Use the Coin-OR Open Source solver CLP",
00574 "cplex", "Use the commercial solver Cplex (license is needed)",
00575 "soplex", "Use the freely available Soplex (not available yet)");
00576
00577 roptions->AddBoundedIntegerOption(
00578 "branching_print_level", "Output level for braching code in Couenne",
00579 -2, J_LAST_LEVEL-1, J_NONE, "");
00580
00581 roptions->AddBoundedIntegerOption(
00582 "boundtightening_print_level", "Output level for bound tightening code in Couenne",
00583 -2, J_LAST_LEVEL-1, J_NONE, "");
00584
00585 roptions->AddBoundedIntegerOption(
00586 "convexifying_print_level", "Output level for convexifying code in Couenne",
00587 -2, J_LAST_LEVEL-1, J_NONE, "");
00588
00589 roptions->AddBoundedIntegerOption(
00590 "problem_print_level", "Output level for problem manipulation code in Couenne",
00591 -2, J_LAST_LEVEL-1, J_ERROR, "");
00592
00593 roptions->AddBoundedIntegerOption(
00594 "nlpheur_print_level", "Output level for NLP heuristic in Couenne",
00595 -2, J_LAST_LEVEL-1, J_NONE, "");
00596
00597 roptions->AddBoundedIntegerOption(
00598 "disjcuts_print_level", "Output level for disjunctive cuts in Couenne",
00599 -2, J_LAST_LEVEL-1, J_NONE, "");
00600
00601 roptions->AddBoundedIntegerOption(
00602 "reformulate_print_level", "Output level for reformulating problems in Couenne",
00603 -2, J_LAST_LEVEL-1, J_NONE, "");
00604
00605
00606
00607
00608
00609 struct cutOption_ {
00610
00611 const char *cgname;
00612 int defaultFreq;
00613
00614 } cutOption [] = {
00615 {(const char *) "Gomory_cuts", 0},
00616 {(const char *) "probing_cuts", 0},
00617 {(const char *) "cover_cuts", 0},
00618 {(const char *) "mir_cuts", 0},
00619 {(const char *) "2mir_cuts", 0},
00620 {(const char *) "flow_covers_cuts", 0},
00621 {(const char *) "lift_and_project_cuts", 0},
00622 {(const char *) "reduce_split_cuts", 0},
00623 {(const char *) "clique_cuts", 0},
00624 {NULL, 0}};
00625
00626 for (int i=0; cutOption [i].cgname; i++) {
00627
00628 char descr [150];
00629
00630 sprintf (descr, "Frequency k (in terms of nodes) for generating %s cuts in branch-and-cut.",
00631 cutOption [i].cgname);
00632
00633 roptions -> AddLowerBoundedIntegerOption
00634 (cutOption [i].cgname,
00635 descr,
00636 -100, cutOption [i].defaultFreq,
00637 "If k > 0, cuts are generated every k nodes, "
00638 "if -99 < k < 0 cuts are generated every -k nodes but "
00639 "Cbc may decide to stop generating cuts, if not enough are generated at the root node, "
00640 "if k=-99 generate cuts only at the root node, if k=0 or 100 do not generate cuts.");
00641
00642 roptions->setOptionExtraInfo (cutOption [i].cgname, 5);
00643 }
00644 }
00645
00646
00647
00649 void CouenneSetup::addMilpCutGenerators () {
00650
00651 enum extraInfo_ {CUTINFO_NONE, CUTINFO_MIG, CUTINFO_PROBING, CUTINFO_CLIQUE};
00652
00653 struct cutInfo {
00654
00655 const char *optname;
00656 CglCutGenerator *cglptr;
00657 const char *cglId;
00658 enum extraInfo_ extraInfo;
00659
00660 } cutList [] = {
00661 {(const char*)"Gomory_cuts",new CglGomory, (const char*)"Mixed Integer Gomory",CUTINFO_MIG},
00662 {(const char*)"probing_cuts",new CglProbing, (const char*) "Probing", CUTINFO_PROBING},
00663 {(const char*)"mir_cuts",new CglMixedIntegerRounding2, (const char*) "Mixed Integer Rounding",
00664 CUTINFO_NONE},
00665 {(const char*)"2mir_cuts", new CglTwomir, (const char*) "2-MIR", CUTINFO_NONE},
00666 {(const char*)"cover_cuts", new CglKnapsackCover, (const char*) "Cover", CUTINFO_NONE},
00667 {(const char*)"clique_cuts", new CglClique, (const char*) "Clique", CUTINFO_CLIQUE},
00668 {(const char*)"lift_and_project_cuts",new CglLandP,(const char*)"Lift and Project",CUTINFO_NONE},
00669 {(const char*)"reduce_split_cuts",new CglRedSplit,(const char*) "Reduce and Split",CUTINFO_NONE},
00670 {(const char*)"flow_covers_cuts",new CglFlowCover,(const char*) "Flow cover cuts", CUTINFO_NONE},
00671 {NULL, NULL, NULL, CUTINFO_NONE}};
00672
00673 int freq;
00674
00675 for (int i=0; cutList [i]. optname; i++) {
00676
00677 options_ -> GetIntegerValue (std::string (cutList [i]. optname), freq, "bonmin.");
00678
00679 if (!freq) {
00680 delete cutList [i].cglptr;
00681 continue;
00682 }
00683
00684 CuttingMethod cg;
00685 cg.frequency = freq;
00686 cg.cgl = cutList [i].cglptr;
00687 cg.id = std::string (cutList [i]. cglId);
00688 cutGenerators_.push_back (cg);
00689
00690
00691 switch (cutList [i].extraInfo) {
00692
00693 case CUTINFO_MIG: {
00694 CglGomory *gc = dynamic_cast <CglGomory *> (cutList [i].cglptr);
00695
00696 if (!gc) break;
00697
00698 gc -> setLimitAtRoot(512);
00699 gc -> setLimit(50);
00700 }
00701 break;
00702
00703 case CUTINFO_PROBING: {
00704 CglProbing *pc = dynamic_cast <CglProbing *> (cutList [i].cglptr);
00705
00706 if (!pc) break;
00707
00708 pc->setUsingObjective(1);
00709 pc->setMaxPass(3);
00710 pc->setMaxPassRoot(3);
00711
00712 pc->setMaxProbe(10);
00713 pc->setMaxProbeRoot(50);
00714
00715 pc->setMaxLook(10);
00716 pc->setMaxLookRoot(50);
00717 pc->setMaxLookRoot(10);
00718
00719 pc->setMaxElements(200);
00720 pc->setRowCuts(3);
00721 }
00722 break;
00723
00724 case CUTINFO_CLIQUE: {
00725 CglClique *clique = dynamic_cast <CglClique *> (cutList [i].cglptr);
00726
00727 if (!clique) break;
00728
00729 clique -> setStarCliqueReport(false);
00730 clique -> setRowCliqueReport(false);
00731 clique -> setMinViolation(0.1);
00732 }
00733 break;
00734
00735
00736 default:
00737 break;
00738 }
00739 }
00740 }
00741 }