- Timestamp:
- May 31, 2011 4:10:30 AM (10 years ago)
- Location:
- trunk/Cbc/src
- Files:
-
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Cbc/src/CbcCutGenerator.cpp
r1643 r1656 276 276 if (fullScan < 0) 277 277 info.options |= 128; 278 if (whetherInMustCallAgainMode()) 279 info.options |= 1024; 278 280 // See if we want alternate set of cuts 279 281 if ((model_->moreSpecialOptions()&16384) != 0) … … 539 541 } 540 542 //if (!solver->basisIsAvailable()) 541 //returnCode=true; 543 //returnCode=true; 544 if (!returnCode) { 545 // bounds changed but still optimal 546 #ifdef COIN_HAS_CLP 547 OsiClpSolverInterface * clpSolver 548 = dynamic_cast<OsiClpSolverInterface *> (solver); 549 if (clpSolver) { 550 clpSolver->setLastAlgorithm(2); 551 } 552 #endif 553 } 542 554 #ifdef JJF_ZERO 543 555 // Pass across info to pseudocosts -
trunk/Cbc/src/CbcCutGenerator.hpp
r1573 r1656 167 167 } 168 168 169 /// Get switches (for debug) 170 inline int switches() const { 171 return switches_; 172 } 169 173 /// Get whether the cut generator should be called in the normal place 170 174 inline bool normal() const { … … 319 323 switches_ &= ~1024; 320 324 switches_ |= yesNo ? 1024 : 0; 325 } 326 /// Whether in must call again mode (or after others) 327 inline bool whetherInMustCallAgainMode() const { 328 return (switches_&2048) != 0; 329 } 330 /// Set whether in must call again mode (or after others) 331 inline void setWhetherInMustCallAgainMode(bool yesNo) { 332 switches_ &= ~2048; 333 switches_ |= yesNo ? 2048 : 0; 334 } 335 /// Whether to call at end 336 inline bool whetherCallAtEnd() const { 337 return (switches_&4096) != 0; 338 } 339 /// Set whether to call at end 340 inline void setWhetherCallAtEnd(bool yesNo) { 341 switches_ &= ~4096; 342 switches_ |= yesNo ? 4096 : 0; 321 343 } 322 344 /// Number of cuts generated at root -
trunk/Cbc/src/CbcHeuristicRENS.cpp
r1641 r1656 852 852 returnCode = smallBranchAndBound(newSolver, numberNodes_, betterSolution, solutionValue, 853 853 model_->getCutoff(), "CbcHeuristicRENS"); 854 if (returnCode < 0) { 855 returnCode = 0; // returned on size 854 if (returnCode < 0 || returnCode == 0) { 856 855 #ifdef RENS_FIX_CONTINUOUS 857 856 if (numberContinuous > numberIntegers && numberFixed >= numberColumns / 5) { … … 905 904 returnCode = smallBranchAndBound(newSolver, numberNodes_, betterSolution, solutionValue, 906 905 model_->getCutoff(), "CbcHeuristicRENS"); 907 #endif 908 } 906 } 907 #endif 908 if (returnCode < 0 || returnCode == 0) { 909 // Do passes fixing up those >0.9 and 910 // down those < 0.05 911 #define RENS_PASS 3 912 //#define KEEP_GOING 913 #ifdef KEEP_GOING 914 double * saveLower = CoinCopyOfArray(colLower,numberColumns); 915 double * saveUpper = CoinCopyOfArray(colUpper,numberColumns); 916 bool badPass=false; 917 int nSolved=0; 918 #endif 919 for (int iPass=0;iPass<RENS_PASS;iPass++) { 920 int nFixed=0; 921 int nFixedAlready=0; 922 int nFixedContinuous=0; 923 for (int iColumn = 0; iColumn < numberColumns; iColumn++) { 924 if (colUpper[iColumn]>colLower[iColumn]) { 925 if (newSolver->isInteger(iColumn)) { 926 double value = currentSolution[iColumn]; 927 double fixTo = floor(value+0.1); 928 if (fixTo>value || value-fixTo < 0.05) { 929 // above 0.9 or below 0.05 930 nFixed++; 931 newSolver->setColLower(iColumn, fixTo); 932 newSolver->setColUpper(iColumn, fixTo); 933 } 934 } 935 } else if (newSolver->isInteger(iColumn)) { 936 nFixedAlready++; 937 } else { 938 nFixedContinuous++; 939 } 940 } 941 #ifdef CLP_INVESTIGATE2 942 printf("%d more integers fixed (total %d) plus %d continuous\n", 943 nFixed,nFixed+nFixedAlready,nFixedContinuous); 944 #endif 945 #ifdef KEEP_GOING 946 if (nFixed) { 947 newSolver->resolve(); 948 if (!newSolver->isProvenOptimal()) { 949 badPass=true; 950 break; 951 } else { 952 nSolved++; 953 memcpy(saveLower,colLower,numberColumns*sizeof(double)); 954 memcpy(saveUpper,colUpper,numberColumns*sizeof(double)); 955 } 956 } else { 957 break; 958 } 959 #else 960 if (nFixed) { 961 newSolver->resolve(); 962 if (!newSolver->isProvenOptimal()) { 963 returnCode=0; 964 break; 965 } 966 returnCode = smallBranchAndBound(newSolver, numberNodes_, betterSolution, solutionValue, 967 model_->getCutoff(), "CbcHeuristicRENS"); 968 } else { 969 returnCode=0; 970 } 971 if (returnCode>=0) 972 break; 973 } 974 if (returnCode < 0) 975 returnCode = 0; // returned on size 976 #endif 977 } 978 #ifdef KEEP_GOING 979 if (badPass) { 980 newSolver->setColLower(saveLower); 981 newSolver->setColUpper(saveUpper); 982 newSolver->resolve(); 983 } 984 delete [] saveLower; 985 delete [] saveUpper; 986 if (nSolved) 987 returnCode = 988 smallBranchAndBound(newSolver, numberNodes_, betterSolution, solutionValue, 989 model_->getCutoff(), "CbcHeuristicRENS"); 990 else 991 returnCode=0; 992 } 993 #endif 909 994 } 910 995 //printf("return code %d",returnCode); -
trunk/Cbc/src/CbcModel.cpp
r1654 r1656 1981 1981 #endif 1982 1982 bool feasible; 1983 numberSolves_ = 0 ; 1983 1984 // If NLP then we assume already solved outside branchAndbound 1984 1985 if (!solverCharacteristics_->solverType() || solverCharacteristics_->solverType() == 4) { … … 2223 2224 if (clpSolver) 2224 2225 clpSolver->setStuff(getIntegerTolerance(), getCutoffIncrement()); 2226 #ifdef CLP_RESOLVE 2227 if ((moreSpecialOptions_&1048576)!=0&&!parentModel_&&clpSolver) { 2228 resolveClp(clpSolver,0); 2229 } 2230 #endif 2225 2231 } 2226 2232 #endif … … 2332 2338 */ 2333 2339 numberIterations_ = 0 ; 2334 numberSolves_ = 0 ;2335 2340 numberNodes_ = 0 ; 2336 2341 numberNodes2_ = 0 ; … … 2561 2566 feasible = false; 2562 2567 2568 #ifdef CLP_RESOLVE 2569 if ((moreSpecialOptions_&2097152)!=0&&!parentModel_&&feasible) { 2570 OsiClpSolverInterface * clpSolver 2571 = dynamic_cast<OsiClpSolverInterface *> (solver_); 2572 if (clpSolver) 2573 resolveClp(clpSolver,0); 2574 } 2575 #endif 2563 2576 // make cut generators less aggressive 2564 2577 for (iCutGenerator = 0; iCutGenerator < numberCutGenerators_; iCutGenerator++) { … … 6920 6933 // Whether to increase minimum drop 6921 6934 bool increaseDrop = (moreSpecialOptions_ & 8192) != 0; 6935 for (int i = 0; i < numberCutGenerators_; i++) 6936 generator_[i]->setWhetherInMustCallAgainMode(false); 6922 6937 /* 6923 6938 Begin cut generation loop. Cuts generated during each iteration are … … 6943 6958 if (!generator_[i]->mustCallAgain()) 6944 6959 generator_[i]->setSwitchedOff(true); 6960 else 6961 generator_[i]->setWhetherInMustCallAgainMode(true); 6945 6962 } 6946 6963 } … … 7530 7547 keepGoing=false; 7531 7548 } 7549 if (numberTries <=0 && feasible && !keepGoing && !parentModel_ && !numberNodes_) { 7550 for (int i = 0; i < numberCutGenerators_; i++) { 7551 if (generator_[i]->whetherCallAtEnd() 7552 &&!generator_[i]->whetherInMustCallAgainMode()) { 7553 keepGoing= true; 7554 break; 7555 } 7556 } 7557 } 7532 7558 } while (numberTries > 0 || keepGoing) ; 7533 7559 /* … … 8345 8371 int numberRowCutsAfter = numberRowCutsBefore; 8346 8372 int numberColumnCutsAfter = numberColumnCutsBefore; 8373 /*printf("GEN %d %s switches %d\n", 8374 i,generator_[i]->cutGeneratorName(), 8375 generator_[i]->switches());*/ 8347 8376 bool generate = generator_[i]->normal(); 8348 8377 // skip if not optimal and should be (maybe a cut generator has fixed variables) … … 8375 8404 } 8376 8405 if (numberRowCutsBefore < numberRowCutsAfter && 8377 generator_[i]->mustCallAgain() && status >= 0) 8406 generator_[i]->mustCallAgain() && status >= 0) 8407 /*printf("%s before %d after %d must %c atend %c off %c endmode %c\n", 8408 generator_[i]->cutGeneratorName(), 8409 numberRowCutsBefore,numberRowCutsAfter, 8410 generator_[i]->mustCallAgain() ? 'Y': 'N', 8411 generator_[i]->whetherCallAtEnd() ? 'Y': 'N', 8412 generator_[i]->switchedOff() ? 'Y': 'N', 8413 generator_[i]->whetherInMustCallAgainMode() ? 'Y': 'N');*/ 8414 if (numberRowCutsBefore < numberRowCutsAfter && 8415 generator_[i]->mustCallAgain() && status >= 0) 8378 8416 status = 1 ; // say must go round 8379 8417 // Check last cut to see if infeasible … … 12107 12145 return solver->isProvenOptimal() ? 1 : 0; 12108 12146 } 12147 #ifdef CLP_RESOLVE 12148 // Special purpose resolve 12149 int 12150 CbcModel::resolveClp(OsiClpSolverInterface * clpSolver, int type) 12151 { 12152 numberSolves_++; 12153 ClpSimplex * clpSimplex = clpSolver->getModelPtr(); 12154 int save = clpSimplex->specialOptions(); 12155 clpSimplex->setSpecialOptions(save | 0x11000000); // say is Cbc (and in branch and bound) 12156 int save2 = clpSolver->specialOptions(); 12157 clpSolver->resolve(); 12158 if (!numberNodes_) { 12159 double error = CoinMax(clpSimplex->largestDualError(), 12160 clpSimplex->largestPrimalError()); 12161 if (error > 1.0e-2 || !clpSolver->isProvenOptimal()) { 12162 #ifdef CLP_INVESTIGATE 12163 printf("Problem was %s largest dual error %g largest primal %g - safer cuts\n", 12164 clpSolver->isProvenOptimal() ? "optimal" : "!infeasible", 12165 clpSimplex->largestDualError(), 12166 clpSimplex->largestPrimalError()); 12167 #endif 12168 if (!clpSolver->isProvenOptimal()) { 12169 clpSolver->setSpecialOptions(save2 | 2048); 12170 clpSimplex->allSlackBasis(true); 12171 clpSolver->resolve(); 12172 if (!clpSolver->isProvenOptimal()) { 12173 bool takeHint; 12174 OsiHintStrength strength; 12175 clpSolver->getHintParam(OsiDoDualInResolve, takeHint, strength); 12176 clpSolver->setHintParam(OsiDoDualInResolve, false, OsiHintDo); 12177 clpSolver->resolve(); 12178 clpSolver->setHintParam(OsiDoDualInResolve, takeHint, strength); 12179 } 12180 } 12181 // make cuts safer 12182 for (int iCutGenerator = 0; iCutGenerator < numberCutGenerators_; iCutGenerator++) { 12183 CglCutGenerator * generator = generator_[iCutGenerator]->generator(); 12184 CglGomory * cgl1 = dynamic_cast<CglGomory *>(generator); 12185 if (cgl1) { 12186 cgl1->setLimitAtRoot(cgl1->getLimit()); 12187 } 12188 CglTwomir * cgl2 = dynamic_cast<CglTwomir *>(generator); 12189 if (cgl2) { 12190 generator_[iCutGenerator]->setHowOften(-100); 12191 } 12192 } 12193 } 12194 } 12195 clpSolver->setSpecialOptions(save2); 12196 #ifdef CLP_INVESTIGATE 12197 if (clpSimplex->numberIterations() > 1000) 12198 printf("node %d took %d iterations\n", numberNodes_, clpSimplex->numberIterations()); 12199 #endif 12200 if (type==0 && clpSolver->isProvenOptimal()) { 12201 ClpSimplex newModel(*clpSimplex); 12202 newModel.primal(); 12203 int numberColumns = newModel.numberColumns(); 12204 int numberRows = newModel.numberRows(); 12205 double * obj = new double [numberColumns]; 12206 int * which = new int [numberColumns]; 12207 const double * solution = clpSimplex->primalColumnSolution(); 12208 double rhs=1.0e-8; 12209 int numberObj=0; 12210 double integerTolerance = getDblParam(CbcIntegerTolerance) ; 12211 double * objective = newModel.objective(); 12212 for (int i=0;i<numberColumns;i++) { 12213 if (objective[i]) { 12214 rhs += objective[i]*solution[i]; 12215 obj[numberObj]=objective[i]; 12216 which[numberObj++]=i; 12217 objective[i]=0.0; 12218 } 12219 } 12220 if (numberObj) { 12221 newModel.addRow(numberObj,which,obj,-COIN_DBL_MAX,rhs); 12222 } 12223 delete [] obj; 12224 delete [] which; 12225 double * lower = newModel.columnLower(); 12226 double * upper = newModel.columnUpper(); 12227 int numberInf = 0; 12228 int numberLb = 0; 12229 int numberUb = 0; 12230 int numberInt = 0; 12231 double sumInf=0.0; 12232 for (int i=0;i<numberIntegers_;i++) { 12233 int iSequence = integerVariable_[i]; 12234 double value = solution[iSequence]; 12235 value = CoinMax(value, lower[iSequence]); 12236 value = CoinMin(value, upper[iSequence]); 12237 double nearest = floor(value + 0.5); 12238 if (value<lower[iSequence]+integerTolerance) { 12239 objective[iSequence]=1.0; 12240 numberLb++; 12241 } else if (value>upper[iSequence]-integerTolerance) { 12242 objective[iSequence]=-1.0; 12243 numberUb++; 12244 } else if (fabs(value - nearest) <= integerTolerance) { 12245 // fix?? 12246 lower[iSequence]=nearest; 12247 upper[iSequence]=nearest; 12248 numberInt++; 12249 } else { 12250 lower[iSequence]=floor(value); 12251 upper[iSequence]=ceil(value); 12252 if (value>nearest) { 12253 objective[iSequence]=1.0; 12254 sumInf += value-nearest; 12255 } else { 12256 objective[iSequence]=-1.0; 12257 sumInf -= value-nearest; 12258 } 12259 numberInf++; 12260 } 12261 } 12262 printf("XX %d inf (sum %g), %d at lb %d at ub %d other integer\n", 12263 numberInf,sumInf,numberLb,numberUb,numberInt); 12264 if (numberInf) { 12265 newModel.primal(1); 12266 if (!newModel.isProvenOptimal()) { 12267 printf("not optimal - scaling issue - switch off\n"); 12268 clpSimplex->setSpecialOptions(save); 12269 if (clpSimplex->status()==4) 12270 clpSimplex->setProblemStatus(1); 12271 return clpSolver->isProvenOptimal() ? 1 : 0; 12272 } 12273 //newModel.writeMps("bad.mps"); 12274 //assert (newModel.isProvenOptimal()); 12275 printf("%d iterations\n",newModel.numberIterations()); 12276 int numberInf2 = 0; 12277 int numberLb2 = 0; 12278 int numberUb2 = 0; 12279 int numberInt2 = 0; 12280 double sumInf2=0.0; 12281 const double * solution = newModel.primalColumnSolution(); 12282 const double * lower = clpSimplex->columnLower(); 12283 const double * upper = clpSimplex->columnUpper(); 12284 for (int i=0;i<numberIntegers_;i++) { 12285 int iSequence = integerVariable_[i]; 12286 double value = solution[iSequence]; 12287 value = CoinMax(value, lower[iSequence]); 12288 value = CoinMin(value, upper[iSequence]); 12289 double nearest = floor(value + 0.5); 12290 if (value<lower[iSequence]+integerTolerance) { 12291 numberLb2++; 12292 } else if (value>upper[iSequence]-integerTolerance) { 12293 numberUb2++; 12294 } else if (fabs(value - nearest) <= integerTolerance) { 12295 numberInt2++; 12296 } else { 12297 if (value>nearest) { 12298 sumInf2 += value-nearest; 12299 } else { 12300 sumInf2 -= value-nearest; 12301 } 12302 numberInf2++; 12303 } 12304 } 12305 printf("XXX %d inf (sum %g), %d at lb %d at ub %d other integer\n", 12306 numberInf2,sumInf2,numberLb2,numberUb2,numberInt2); 12307 if (sumInf2<sumInf*0.95) { 12308 printf("XXXX suminf reduced from %g (%d) to %g (%d)\n", 12309 sumInf,numberInf,sumInf2,numberInf2); 12310 if (numberObj) { 12311 newModel.deleteRows(1,&numberRows); 12312 } 12313 memcpy(newModel.objective(), 12314 clpSimplex->objective(), 12315 numberColumns*sizeof(double)); 12316 memcpy(newModel.columnLower(), 12317 clpSimplex->columnLower(), 12318 numberColumns*sizeof(double)); 12319 memcpy(newModel.columnUpper(), 12320 clpSimplex->columnUpper(), 12321 numberColumns*sizeof(double)); 12322 newModel.setClpScaledMatrix(NULL); 12323 newModel.primal(1); 12324 printf("%d iterations\n",newModel.numberIterations()); 12325 int numberInf3 = 0; 12326 int numberLb3 = 0; 12327 int numberUb3 = 0; 12328 int numberInt3 = 0; 12329 double sumInf3=0.0; 12330 const double * solution = newModel.primalColumnSolution(); 12331 const double * lower = clpSimplex->columnLower(); 12332 const double * upper = clpSimplex->columnUpper(); 12333 for (int i=0;i<numberIntegers_;i++) { 12334 int iSequence = integerVariable_[i]; 12335 double value = solution[iSequence]; 12336 value = CoinMax(value, lower[iSequence]); 12337 value = CoinMin(value, upper[iSequence]); 12338 double nearest = floor(value + 0.5); 12339 if (value<lower[iSequence]+integerTolerance) { 12340 numberLb3++; 12341 } else if (value>upper[iSequence]-integerTolerance) { 12342 numberUb3++; 12343 } else if (fabs(value - nearest) <= integerTolerance) { 12344 numberInt3++; 12345 } else { 12346 if (value>nearest) { 12347 sumInf3 += value-nearest; 12348 } else { 12349 sumInf3 -= value-nearest; 12350 } 12351 numberInf3++; 12352 } 12353 } 12354 printf("XXXXX %d inf (sum %g), %d at lb %d at ub %d other integer\n", 12355 numberInf3,sumInf3,numberLb3,numberUb3,numberInt3); 12356 if (sumInf3<sumInf*0.95) { 12357 memcpy(clpSimplex->primalColumnSolution(), 12358 newModel.primalColumnSolution(), 12359 numberColumns*sizeof(double)); 12360 memcpy(clpSimplex->dualColumnSolution(), 12361 newModel.dualColumnSolution(), 12362 numberColumns*sizeof(double)); 12363 memcpy(clpSimplex->primalRowSolution(), 12364 newModel.primalRowSolution(), 12365 numberRows*sizeof(double)); 12366 memcpy(clpSimplex->dualRowSolution(), 12367 newModel.dualRowSolution(), 12368 numberRows*sizeof(double)); 12369 memcpy(clpSimplex->statusArray(), 12370 newModel.statusArray(), 12371 (numberColumns+numberRows)*sizeof(unsigned char)); 12372 clpSolver->setWarmStart(NULL); 12373 } 12374 } 12375 } 12376 } 12377 clpSimplex->setSpecialOptions(save); 12378 if (clpSimplex->status()==4) 12379 clpSimplex->setProblemStatus(1); 12380 return clpSolver->isProvenOptimal() ? 1 : 0; 12381 } 12382 #endif 12109 12383 /*! 12110 12384 \todo It'd be really nice if there were an overload for this method that -
trunk/Cbc/src/CbcModel.hpp
r1650 r1656 18 18 #include "ClpDualRowPivot.hpp" 19 19 20 //class OsiSolverInterface;21 20 22 21 class CbcCutGenerator; … … 39 38 class CglPreProcess; 40 39 # ifdef COIN_HAS_CLP 40 class OsiClpSolverInterface; 41 41 class ClpNodeStuff; 42 42 #endif … … 1716 1716 16 bit (65536) - Original model had integer bounds 1717 1717 17 bit (131072) - Perturbation switched off 1718 18 bit (262144) - donor CbcModel 1719 19 bit (524288) - recipient CbcModel 1718 1720 */ 1719 1721 inline void setSpecialOptions(int value) { … … 1737 1739 65536 no cuts in preprocessing 1738 1740 131072 Time limits elapsed 1741 18 bit (262144) - Perturb fathom nodes 1742 19 bit (524288) - No limit on fathom nodes 1743 20 bit (1048576) - Reduce sum of infeasibilities before cuts 1744 21 bit (2097152) - Reduce sum of infeasibilities after cuts 1739 1745 */ 1740 1746 inline void setMoreSpecialOptions(int value) { … … 2004 2010 /// Encapsulates solver resolve 2005 2011 int resolve(OsiSolverInterface * solver); 2012 #ifdef CLP_RESOLVE 2013 /// Special purpose resolve 2014 int resolveClp(OsiClpSolverInterface * solver, int type); 2015 #endif 2006 2016 2007 2017 /** Encapsulates choosing a variable - … … 2457 2467 18 bit (262144) - Perturb fathom nodes 2458 2468 19 bit (524288) - No limit on fathom nodes 2469 20 bit (1048576) - Reduce sum of infeasibilities before cuts 2470 21 bit (2097152) - Reduce sum of infeasibilities after cuts 2459 2471 */ 2460 2472 int moreSpecialOptions_; -
trunk/Cbc/src/CbcSolver.cpp
r1650 r1656 1130 1130 int numberParameters_ = numberParameters; 1131 1131 CbcModel & model_ = model; 1132 #ifdef CBC_USE_INITIAL_TIME 1133 if (model_.useElapsedTime()) 1134 model_.setDblParam(CbcModel::CbcStartSeconds, CoinGetTimeOfDay()); 1135 else 1136 model_.setDblParam(CbcModel::CbcStartSeconds, CoinCpuTime()); 1137 #endif 1132 1138 CbcModel * babModel_ = NULL; 1133 1139 int returnMode = 1; … … 1753 1759 numberGoodCommands++; 1754 1760 if (type == CBC_PARAM_ACTION_BAB && goodModel) { 1761 #ifndef CBC_USE_INITIAL_TIME 1755 1762 if (model_.useElapsedTime()) 1756 1763 model_.setDblParam(CbcModel::CbcStartSeconds, CoinGetTimeOfDay()); 1757 1764 else 1758 1765 model_.setDblParam(CbcModel::CbcStartSeconds, CoinCpuTime()); 1766 #endif 1759 1767 // check if any integers 1760 1768 #ifndef CBC_OTHER_SOLVER … … 2044 2052 pumpChanged = true; 2045 2053 else if (parameters_[iParam].type() == CBC_PARAM_INT_EXPERIMENT) { 2054 int addFlags=0; 2055 if (value>=10) { 2056 addFlags = 1048576*(value/10); 2057 value = value % 10; 2058 parameters[whichParam(CBC_PARAM_INT_EXPERIMENT, numberParameters, parameters)].setIntValue(value); 2059 } 2046 2060 if (value >= 1) { 2047 2061 int values[]={24003,280003,792003,24003,24003}; … … 2053 2067 parameters_[iParam].setCurrentOption("on"); 2054 2068 } 2055 int extra4 = values[value-1] ;2069 int extra4 = values[value-1]+addFlags; 2056 2070 parameters[whichParam(CBC_PARAM_INT_EXTRA4, numberParameters, parameters)].setIntValue(extra4); 2057 2071 if (!noPrinting_) { … … 4002 4016 int bothFlags = CoinMax(CoinMin(experimentFlag, 1), strategyFlag); 4003 4017 // add cut generators if wanted 4004 int switches[20]; 4005 int accuracyFlag[20]; 4018 int switches[30]; 4019 int accuracyFlag[30]; 4020 char doAtEnd[30]; 4021 memset(doAtEnd,0,30); 4006 4022 int numberGenerators = 0; 4007 4023 int translate[] = { -100, -1, -99, -98, 1, -1098, -999, 1, 1, 1, -1}; … … 4078 4094 } 4079 4095 } 4080 int extra3 = parameters_[whichParam(CBC_PARAM_INT_EXTRA3, numberParameters_, parameters_)].intValue(); 4081 if (extra3>=100) { 4082 // replace 4083 gomoryGen.passInOriginalSolver(babModel_->solver()); 4084 gomoryGen.setGomoryType(2); 4085 extra3 = -1; 4086 parameters_[whichParam(CBC_PARAM_INT_EXTRA3, numberParameters_, parameters_)].setIntValue(extra3); 4087 babModel_->addCutGenerator(&gomoryGen, translate[gomoryAction], "GomoryL"); 4088 } else { 4096 int laGomory = parameters_[whichParam(CBC_PARAM_STR_LAGOMORYCUTS, numberParameters_, parameters_)].currentOptionAsInteger(); 4097 int gType = translate[gomoryAction]; 4098 if (!laGomory) { 4099 // Normal 4089 4100 babModel_->addCutGenerator(&gomoryGen, translate[gomoryAction], "Gomory"); 4090 }4091 accuracyFlag[numberGenerators] = 3;4092 switches[numberGenerators++] = 0;4093 if (extra3>=10) {4094 // just root if 104095 int itype=-99;4096 if (extra3>=20) {4097 extra3-=10;4098 itype = translate[gomoryAction];4099 }4100 gomoryGen.passInOriginalSolver(babModel_->solver());4101 babModel_->addCutGenerator(&gomoryGen, itype, "GomoryL2");4102 4101 accuracyFlag[numberGenerators] = 3; 4103 4102 switches[numberGenerators++] = 0; 4104 extra3 -= 10; 4105 parameters_[whichParam(CBC_PARAM_INT_EXTRA3, numberParameters_, parameters_)].setIntValue(extra3); 4103 } else { 4104 laGomory--; 4105 int type = (laGomory % 3)+1; 4106 int when = laGomory/3; 4107 char atEnd = (when<2) ? 1 : 0; 4108 int gomoryTypeMajor = 0; 4109 if (when<3) { 4110 // normal as well 4111 babModel_->addCutGenerator(&gomoryGen, gType, "Gomory"); 4112 accuracyFlag[numberGenerators] = 3; 4113 switches[numberGenerators++] = 0; 4114 if (when==2) 4115 gomoryTypeMajor=10; 4116 } else { 4117 when--; // so on 4118 gomoryTypeMajor=20; 4119 } 4120 if (!when) 4121 gType=-99; // root 4122 gomoryGen.passInOriginalSolver(babModel_->solver()); 4123 if ((type&1) !=0) { 4124 // clean 4125 gomoryGen.setGomoryType(gomoryTypeMajor+1); 4126 babModel_->addCutGenerator(&gomoryGen, gType, "GomoryL1"); 4127 accuracyFlag[numberGenerators] = 3; 4128 doAtEnd[numberGenerators]=atEnd; 4129 switches[numberGenerators++] = 0; 4130 } 4131 if ((type&2) !=0) { 4132 // simple 4133 gomoryGen.setGomoryType(gomoryTypeMajor+2); 4134 babModel_->addCutGenerator(&gomoryGen, gType, "GomoryL2"); 4135 accuracyFlag[numberGenerators] = 3; 4136 doAtEnd[numberGenerators]=atEnd; 4137 switches[numberGenerators++] = 0; 4138 } 4106 4139 } 4107 4140 } … … 4190 4223 //generator->setWhetherToUse(true); 4191 4224 generator->setInaccuracy(accuracyFlag[iGenerator]); 4225 if (doAtEnd[iGenerator]) { 4226 generator->setWhetherCallAtEnd(true); 4227 generator->setMustCallAgain(true); 4228 } 4192 4229 generator->setTiming(true); 4193 4230 if (cutDepth >= 0)
Note: See TracChangeset
for help on using the changeset viewer.