diff --git a/src/ClpMessage.cpp b/src/ClpMessage.cpp index 130d78da..3ee23924 100644 --- a/src/ClpMessage.cpp +++ b/src/ClpMessage.cpp @@ -72,7 +72,7 @@ static Clp_message clp_us_english[] = { { CLP_MATRIX_CHANGE, 31, 2, "Matrix can not be converted into %s" }, { CLP_TIMING, 32, 1, "%s objective %.10g - %d iterations time %.2f2%?, Presolve %.2f%?, Idiot %.2f%?" }, { CLP_INTERVAL_TIMING, 33, 2, "%s took %.2f seconds (total %.2f)" }, - { CLP_SPRINT, 34, 1, "Pass %d took %d iterations, objective %g, dual infeasibilities %g( %d)" }, + { CLP_SPRINT, 34, 1, "Pass %d took %d iterations, objective %g, dual infeasibilities %g( %d) - sum artificials %g - %d columns" }, { CLP_BARRIER_ITERATION, 35, 1, "%d Primal %g Dual %g Complementarity %g - %d fixed, rank %d" }, { CLP_BARRIER_OBJECTIVE_GAP, 36, 3, "Feasible - objective gap %g" }, { CLP_BARRIER_GONE_INFEASIBLE, 37, 2, "Infeasible" }, diff --git a/src/ClpSimplexPrimal.cpp b/src/ClpSimplexPrimal.cpp index 077f82af..d8a20401 100644 --- a/src/ClpSimplexPrimal.cpp +++ b/src/ClpSimplexPrimal.cpp @@ -2925,8 +2925,8 @@ void ClpSimplexPrimal::perturb(int type) maximumFraction *= 0.1; } if (savePerturbation == 51) { - perturbation = std::min(0.1, perturbation); - maximumFraction *= 0.1; + perturbation = std::min(0.001, perturbation); + maximumFraction *= 0.001; } if (number != numberRows_) type = 1; diff --git a/src/ClpSolve.cpp b/src/ClpSolve.cpp index e9d250a8..d590f5a2 100644 --- a/src/ClpSolve.cpp +++ b/src/ClpSolve.cpp @@ -542,10 +542,12 @@ void instrument_print() } } #endif -#if ABC_PARALLEL == 2 +//#if ABC_PARALLEL == 2 +#if CLP_HAS_ABC > 2 #ifndef FAKE_CILK int number_cilk_workers = 0; #include +#include #endif #endif #ifdef ABC_INHERIT @@ -659,8 +661,8 @@ ClpSimplex::dealWithAbc(int solveType, int startUp, #ifndef FAKE_CILK char temp[3]; sprintf(temp, "%d", numberCpu); - __cilkrts_set_param("nworkers", temp); - printf("setting cilk workers to %d\n", numberCpu); + //__cilkrts_set_param("nworkers", temp); + printf("setting cilk workers to %d XX use env CILK_NWORKERS\n", numberCpu); number_cilk_workers = numberCpu; #endif @@ -2410,7 +2412,8 @@ int ClpSimplex::initialSolve(ClpSolve &options) } #endif #ifndef LACI_TRY - if (options.getSpecialOption(1) != 2 || options.getExtraInfo(1) < 1000000) { + if (model2->status()&& + (options.getSpecialOption(1) != 2 || options.getExtraInfo(1) < 1000000)) { if (dynamic_cast< ClpPackedMatrix * >(matrix_)) { // See if original wanted vector ClpPackedMatrix *clpMatrixO = dynamic_cast< ClpPackedMatrix * >(matrix_); @@ -2795,7 +2798,7 @@ int ClpSimplex::initialSolve(ClpSolve &options) int totalIterations = 0; double lastSumArtificials = COIN_DBL_MAX; int originalMaxSprintPass = maxSprintPass; - maxSprintPass = 20; // so we do that many if infeasible + maxSprintPass = std::max(0,maxSprintPass); // so we do that many if infeasible for (iPass = 0; iPass < maxSprintPass; iPass++) { //printf("Bug until submodel new version\n"); //CoinSort_2(sort,sort+numberSort,weight); @@ -2832,6 +2835,9 @@ int ClpSimplex::initialSolve(ClpSolve &options) } #endif small.setDblParam(ClpObjOffset, originalOffset - offset); + int smallMore = small.moreSpecialOptions(); + smallMore &= ~1048576; // make sure can't stop early + small.setMoreSpecialOptions(smallMore); model2->clpMatrix()->times(1.0, fullSolution, sumFixed); double *lower = small.rowLower(); @@ -2862,6 +2868,7 @@ int ClpSimplex::initialSolve(ClpSolve &options) if (dynamic_cast< ClpPackedMatrix * >(matrix) && clpMatrixO->wantsSpecialColumnCopy()) { ClpPackedMatrix *clpMatrix = dynamic_cast< ClpPackedMatrix * >(matrix); clpMatrix->makeSpecialColumnCopy(); + small.setMaximumIterations(std::max(small.numberRows(),1000)); small.primal(1); clpMatrix->releaseSpecialColumnCopy(); } else { @@ -2954,19 +2961,17 @@ int ClpSimplex::initialSolve(ClpSolve &options) } int smallIterations = small.numberIterations(); totalIterations += smallIterations; - if (2 * smallIterations < std::min(numberRows, 1000) && iPass) { + if ((2 * smallIterations < std::min(numberRows, 1000)||small.status()==3) && iPass) { int oldNumber = smallNumberColumns; if (smallIterations < 100) smallNumberColumns *= 1.2; else smallNumberColumns *= 1.1; smallNumberColumns = std::min(smallNumberColumns, numberColumns); - if (smallIterations < 200 && smallNumberColumns > 2 * saveSmallNumber) { + if (smallIterations < 200) { // try kicking it - emergencyMode = true; - smallNumberColumns = numberColumns; + smallNumberColumns *= 1.5; } - // smallNumberColumns = std::min(smallNumberColumns, 3*saveSmallNumber); char line[100]; sprintf(line, "sample size increased from %d to %d", oldNumber, smallNumberColumns); @@ -3020,15 +3025,13 @@ int ClpSimplex::initialSolve(ClpSolve &options) } handler_->message(CLP_SPRINT, messages_) << iPass + 1 << small.numberIterations() << small.objectiveValue() << sumNegative - << numberNegative + << numberNegative << sumArtificials << small.numberColumns() << CoinMessageEol; if (sumArtificials < 1.0e-8 && originalMaxSprintPass >= 0) { maxSprintPass = iPass + originalMaxSprintPass; originalMaxSprintPass = -1; } - if (iPass > 20) - sumArtificials = 0.0; - if ((small.objectiveValue() * optimizationDirection_ > lastObjective[1] - 1.0e-7 && iPass > 15 && sumArtificials < 1.0e-8 && maxSprintPass < 200) || (!small.numberIterations() && iPass) || iPass == maxSprintPass - 1 || small.status() == 3) { + if ((small.objectiveValue() * optimizationDirection_ > lastObjective[1] - 1.0e-7 && iPass > 15 && sumArtificials < 1.0e-8 && maxSprintPass < 200) || (!small.numberIterations() && iPass) || iPass == maxSprintPass - 1) { break; // finished } else { @@ -3045,22 +3048,21 @@ int ClpSimplex::initialSolve(ClpSolve &options) int saveN = numberSort; for (iColumn = 0; iColumn < numberColumns; iColumn++) { double dj = djs[iColumn] * optimizationDirection_; - double value = fullSolution[iColumn]; - if (model2->getColumnStatus(iColumn) != ClpSimplex::basic) { - if (dj < -dualTolerance_ && value < columnUpper[iColumn]) - /*dj = dj*/; - else if (dj > dualTolerance_ && value > columnLower[iColumn]) - dj = -dj; - else if (columnUpper[iColumn] > columnLower[iColumn]) - dj = fabs(dj); - else - dj = 1.0e50; - if (dj < tolerance) { - weight[numberSort] = dj; - sort[numberSort++] = iColumn; - } - } - } + ClpSimplex::Status colStatus = model2->getColumnStatus(iColumn); + if (colStatus == ClpSimplex::isFree || colStatus == ClpSimplex::superBasic) { + dj = - fabs(dj); + } else if (colStatus == ClpSimplex::atLowerBound) { + dj = dj; + } else if (colStatus == ClpSimplex::atUpperBound) { + dj = -dj; + } else { + continue; + } + if (dj < tolerance) { + weight[numberSort] = dj; + sort[numberSort++] = iColumn; + } + } // sort CoinSort_2(weight + saveN, weight + numberSort, sort + saveN); //if (numberSort < smallNumberColumns) diff --git a/src/Idiot.cpp b/src/Idiot.cpp index 969110aa..ae0bea13 100644 --- a/src/Idiot.cpp +++ b/src/Idiot.cpp @@ -336,6 +336,18 @@ static int countCostedSlacks(OsiSolverInterface *model) void Idiot::crash(int numberPass, CoinMessageHandler *handler, const CoinMessages *messages, bool doCrossover) { + // use last digit + if (numberPass%10) { + lightWeight_=0; + int option = numberPass%10; + numberPass -= option; + if ((option&1)!=0) + strategy_ |= 1048576; // extra bit at end + if ((option&2)!=0) + strategy_ |= 4194304; // limited presolve + else if ((option&4)!=0) + strategy_ |= 2097152; // no presolve + } // lightweight options int numberColumns = model_->getNumCols(); const double *objective = model_->getObjCoefficients(); @@ -974,6 +986,12 @@ void Idiot::solve2(CoinMessageHandler *handler, const CoinMessages *messages) numberAway = n; keepinfeas = result.infeas; lastWeighted = result.weighted; + if (iteration == majorIterations_&&(strategy_&1048576)!=0) { + // do a few more + mu = std::min(mu,1.0e-11); + majorIterations_+=10; + strategy_ &= ~1048576; // switch off + } //iterationTotal += result.iteration; if (iteration == 1) { if ((strategy_ & 1024) != 0 && mu < 1.0e-10) @@ -1305,6 +1323,8 @@ void Idiot::crossOver(int mode) return; } double fixTolerance = IDIOT_FIX_TOLERANCE; + bool wantVector = false; + bool justValuesPass = false; #ifdef COIN_DEVELOP double startTime = CoinCpuTime(); #endif @@ -1356,6 +1376,9 @@ void Idiot::crossOver(int mode) double *saveRowUpper = NULL; double *saveRowLower = NULL; bool allowInfeasible = ((strategy_ & 8192) != 0) || (majorIterations_ > 1000000); + ClpSimplex * saveModelX = NULL; + if ((strategy_&(2097152|4194304))!=0) + saveModelX = new ClpSimplex (*model_); if (addAll < 3) { saveUpper = new double[ncols]; saveLower = new double[ncols]; @@ -1447,6 +1470,7 @@ void Idiot::crossOver(int mode) // model_->setPerturbation(56); #endif model_->createStatus(); + if(!saveModelX) { /* addAll 0 - chosen,all used, all 1 - chosen, all @@ -1726,7 +1750,7 @@ void Idiot::crossOver(int mode) } else { maxmin = 1.0; } - bool justValuesPass = majorIterations_ > 1000000; + justValuesPass = majorIterations_ > 1000000; if (slackStart >= 0) { for (i = 0; i < nrows; i++) { model_->setRowStatus(i, ClpSimplex::superBasic); @@ -1814,7 +1838,6 @@ void Idiot::crossOver(int mode) } /*printf("%d in basis\n",ninbas);*/ } - bool wantVector = false; if (dynamic_cast< ClpPackedMatrix * >(model_->clpMatrix())) { // See if original wanted vector ClpPackedMatrix *clpMatrixO = dynamic_cast< ClpPackedMatrix * >(model_->clpMatrix()); @@ -1825,6 +1848,85 @@ void Idiot::crossOver(int mode) if ((strategy_ & 65536) != 0) justValuesPass = true; //double * saveBounds=NULL; + } else { + addAll = 3; + memcpy(model_->columnLower(),saveModelX->columnLower(),ncols*sizeof(double)); + memcpy(model_->columnUpper(),saveModelX->columnUpper(),ncols*sizeof(double)); + memcpy(model_->rowLower(),saveModelX->rowLower(),nrows*sizeof(double)); + memcpy(model_->rowUpper(),saveModelX->rowUpper(),nrows*sizeof(double)); + delete saveModelX; + if (strategy_&4194304) { + int nAway = 0; + double *away = new double[ncols+nrows]; + int *choose = new int[ncols+nrows]; + for (int i=0;isetColumnStatus(i,ClpSimplex::atLowerBound); + } else if (colsol[i] > upper[i] - fixTolerance) { + colsol[i] = upper[i]; + model_->setColumnStatus(i,ClpSimplex::atUpperBound); + } else if (lower[i]<-1.0e50 && upper[i]>1.0e50) { + model_->setColumnStatus(i,ClpSimplex::isFree); + away[i] = -1.0e50; + choose[nAway++] = i; + } else { + away[i] = -std::min(upper[i]-colsol[i],colsol[i]-lower[i]); + model_->setColumnStatus(i, ClpSimplex::superBasic); + choose[nAway++] = i; + } + } + for (int i=0;isetRowStatus(i,ClpSimplex::atLowerBound); + } else if (rowsol[i] > upper[i] - fixTolerance) { + rowsol[i] = upper[i]; + model_->setRowStatus(i,ClpSimplex::atUpperBound); + } else if (lower[i]<-1.0e50 && upper[i]>1.0e50) { + model_->setRowStatus(i,ClpSimplex::isFree); + away[i] = -1.0e50; + choose[nAway++] = i+ncols; + } else { + away[i] = -std::min(upper[i]-rowsol[i],rowsol[i]-lower[i]); + model_->setRowStatus(i, ClpSimplex::superBasic); + choose[nAway++] = i+ncols; + } + } + CoinSort_2(away, away + nAway, choose); + //nAway = std::min(nAway,(3*nrows/4)); + nAway = std::min(nAway,nrows); + for (int i=0;isetColumnStatus(choose[i],ClpSimplex::basic); + delete [] away; + delete [] choose; + } else { + for (int i=0;isetColumnStatus(i,ClpSimplex::atLowerBound); + } else if (colsol[i] > upper[i] - fixTolerance) { + colsol[i] = upper[i]; + model_->setColumnStatus(i,ClpSimplex::atUpperBound); + } else if (lower[i]<-1.0e50 && upper[i]>1.0e50) { + model_->setColumnStatus(i,ClpSimplex::isFree); + } else { + model_->setColumnStatus(i, ClpSimplex::superBasic); + } + } + for (int i=0;isetRowStatus(i,ClpSimplex::basic); + } + } + bool justValuesPass = false; + bool wantVector =true; + matrix = model_->clpMatrix(); + ClpPackedMatrix *clpMatrix = dynamic_cast< ClpPackedMatrix * >(matrix); + assert(clpMatrix); + clpMatrix->makeSpecialColumnCopy(); + model_->primal(1); + clpMatrix->releaseSpecialColumnCopy(); + } if (addAll < 3) { ClpPresolve pinfo; if (presolve) { @@ -1965,6 +2067,16 @@ void Idiot::crossOver(int mode) saveModel = model_; pinfo.setPresolveActions(pinfo.presolveActions() | 16384); model_ = pinfo.presolvedModel(*model_, 1.0e-8, false, 5); + if ((strategy_&4194304)!=0) { + if (!model_||model_->numberRows()>0.8*saveModel->numberRows()) { + // do not presolve + presolve=0; + delete model_; + model_=saveModel; + delete [] saveBounds; + saveBounds = NULL; + } + } if (saveBounds) { memcpy(saveModel->columnLower(), saveBounds, ncols * sizeof(double)); memcpy(saveModel->columnUpper(), saveBounds + ncols, ncols * sizeof(double)); @@ -2049,11 +2161,13 @@ void Idiot::crossOver(int mode) delete[] which; } } + if ((strategy_&(2097152|4194304))==0) { // Maybe presolve did nothing! if (pinfo.nullPresolve()) { delete model_; model_ = NULL; } + } if (model_) { // See if we want to go all way int oldSize = 2 * saveModel->numberRows() + saveModel->numberColumns(); @@ -2160,6 +2274,14 @@ void Idiot::crossOver(int mode) if (presolve) { saveModel = model_; model_ = pinfo.presolvedModel(*model_, 1.0e-8, false, 5); + if ((strategy_&(2097152|4194304))!=0) { + if (!model_||(strategy_&2097152)==0||model_->numberRows()>0.8*saveModel->numberRows()) { + // do not presolve + presolve=0; + delete model_; + model_=saveModel; + } + } } else { presolve = 0; } @@ -2212,6 +2334,14 @@ void Idiot::crossOver(int mode) if (presolve) { saveModel = model_; model_ = pinfo.presolvedModel(*model_, 1.0e-8, false, 5); + if ((strategy_&(2097152|4194304))!=0) { + if (!model_||(strategy_&2097152)==0||model_->numberRows()>0.8*saveModel->numberRows()) { + // do not presolve + presolve=0; + delete model_; + model_=saveModel; + } + } } else { presolve = 0; } @@ -2417,5 +2547,3 @@ Idiot::~Idiot() delete[] whenUsed_; } -/* vi: softtabstop=2 shiftwidth=2 expandtab tabstop=2 -*/ diff --git a/src/Idiot.hpp b/src/Idiot.hpp index 266d8d5d..9d92a148 100644 --- a/src/Idiot.hpp +++ b/src/Idiot.hpp @@ -69,7 +69,12 @@ class CLPLIB_EXPORT Idiot { //@{ /// Get an approximate solution with the idiot code void solve(); - /// Lightweight "crash" + /** Lightweight "crash" + Last digit ignored for number of passes + 1 - extra 10 with small mu + 2 - limited presolve (3 extra 10 with small mu) + 4 - no presolve on crossover (5 extra 10 with small mu) + */ void crash(int numberPass, CoinMessageHandler *handler, const CoinMessages *messages, bool doCrossover = true); /** Use simplex to get an optimal solution @@ -328,7 +333,10 @@ class CLPLIB_EXPORT Idiot { 65536 - experimental 2 131072 - experimental 3 262144 - just values pass etc - 524288 - don't treat structural slacks as slacks */ + 524288 - don't treat structural slacks as slacks + 1048576 - do extra few iterations with tiny mu + 2097152 - keep simple - no presolves or basis + 4194304 - kill presolve if doing little */ int lightWeight_; // 0 - normal, 1 lightweight };