#include <ClpSimplexPrimal.hpp>
Inheritance diagram for ClpSimplexPrimal:
Public Member Functions | |
Description of algorithm | |
int | primal (int ifValuesPass=0) |
For advanced users | |
void | alwaysOptimal (bool onOff) |
Do not change infeasibility cost and always say optimal. | |
bool | alwaysOptimal () const |
void | exactOutgoing (bool onOff) |
bool | exactOutgoing () const |
Functions used in primal | |
int | whileIterating (int valuesOption) |
int | pivotResult (int ifValuesPass=0) |
int | updatePrimalsInPrimal (CoinIndexedVector *rowArray, double theta, double &objectiveChange, int valuesPass) |
void | primalRow (CoinIndexedVector *rowArray, CoinIndexedVector *rhsArray, CoinIndexedVector *spareArray, CoinIndexedVector *spareArray2, int valuesPass) |
void | primalColumn (CoinIndexedVector *updateArray, CoinIndexedVector *spareRow1, CoinIndexedVector *spareRow2, CoinIndexedVector *spareColumn1, CoinIndexedVector *spareColumn2) |
int | checkUnbounded (CoinIndexedVector *ray, CoinIndexedVector *spare, double changeCost) |
void | statusOfProblemInPrimal (int &lastCleaned, int type, ClpSimplexProgress *progress, bool doFactorization, ClpSimplex *saveModel=NULL) |
void | perturb (int type) |
Perturbs problem (method depends on perturbation()). | |
bool | unPerturb () |
Take off effect of perturbation and say whether to try dual. | |
int | unflag () |
Unflag all variables and return number unflagged. | |
int | nextSuperBasic (int superBasicType, CoinIndexedVector *columnArray) |
void | primalRay (CoinIndexedVector *rowArray) |
Create primal ray. | |
void | clearAll () |
Clears all bits and clears rowArray[1] etc. |
It inherits from ClpSimplex. It has no data of its own and is never created - only cast from a ClpSimplex object at algorithm time.
Definition at line 22 of file ClpSimplexPrimal.hpp.
|
Checks if tentative optimal actually means unbounded in primal Returns -3 if not, 2 if is unbounded |
|
Normally outgoing variables can go out to slightly negative values (but within tolerance) - this is to help stability and and degeneracy. This can be switched off Definition at line 1907 of file ClpSimplexPrimal.cpp.
01908 { 01909 if (onOff) 01910 specialOptions_ |= 4; 01911 else 01912 specialOptions_ &= ~4; 01913 } |
|
Get next superbasic -1 if none, Normal type is 1 If type is 3 then initializes sorted list if 2 uses list. Definition at line 2333 of file ClpSimplexPrimal.cpp. References CoinIndexedVector::denseVector(), CoinIndexedVector::getIndices(), CoinIndexedVector::getNumElements(), and CoinIndexedVector::setNumElements(). Referenced by whileIterating().
02334 { 02335 if (firstFree_>=0&&superBasicType) { 02336 int returnValue=firstFree_; 02337 int iColumn=firstFree_+1; 02338 if (superBasicType>1) { 02339 if (superBasicType>2) { 02340 // Initialize list 02341 // Wild guess that lower bound more natural than upper 02342 int number=0; 02343 double * work=columnArray->denseVector(); 02344 int * which=columnArray->getIndices(); 02345 for (iColumn=0;iColumn<numberRows_+numberColumns_;iColumn++) { 02346 if (getStatus(iColumn)==superBasic) { 02347 if (fabs(solution_[iColumn]-lower_[iColumn])<=primalTolerance_) { 02348 solution_[iColumn]=lower_[iColumn]; 02349 setStatus(iColumn,atLowerBound); 02350 } else if (fabs(solution_[iColumn]-upper_[iColumn]) 02351 <=primalTolerance_) { 02352 solution_[iColumn]=upper_[iColumn]; 02353 setStatus(iColumn,atUpperBound); 02354 } else if (lower_[iColumn]<-1.0e20&&upper_[iColumn]>1.0e20) { 02355 setStatus(iColumn,isFree); 02356 break; 02357 } else if (!flagged(iColumn)) { 02358 // put ones near bounds at end after sorting 02359 work[number]= - min(0.1*(solution_[iColumn]-lower_[iColumn]), 02360 upper_[iColumn]-solution_[iColumn]); 02361 which[number++] = iColumn; 02362 } 02363 } 02364 } 02365 CoinSort_2(work,work+number,which); 02366 columnArray->setNumElements(number); 02367 memset(work,0,number*sizeof(double)); 02368 } 02369 int * which=columnArray->getIndices(); 02370 int number = columnArray->getNumElements(); 02371 if (!number) { 02372 // finished 02373 iColumn = numberRows_+numberColumns_; 02374 returnValue=-1; 02375 } else { 02376 number--; 02377 returnValue=which[number]; 02378 iColumn=returnValue; 02379 columnArray->setNumElements(number); 02380 } 02381 } else { 02382 for (;iColumn<numberRows_+numberColumns_;iColumn++) { 02383 if (getStatus(iColumn)==superBasic) { 02384 if (fabs(solution_[iColumn]-lower_[iColumn])<=primalTolerance_) { 02385 solution_[iColumn]=lower_[iColumn]; 02386 setStatus(iColumn,atLowerBound); 02387 } else if (fabs(solution_[iColumn]-upper_[iColumn]) 02388 <=primalTolerance_) { 02389 solution_[iColumn]=upper_[iColumn]; 02390 setStatus(iColumn,atUpperBound); 02391 } else if (lower_[iColumn]<-1.0e20&&upper_[iColumn]>1.0e20) { 02392 setStatus(iColumn,isFree); 02393 break; 02394 } else { 02395 break; 02396 } 02397 } 02398 } 02399 } 02400 firstFree_ = iColumn; 02401 if (firstFree_==numberRows_+numberColumns_) 02402 firstFree_=-1; 02403 return returnValue; 02404 } else { 02405 return -1; 02406 } 02407 } |
|
Do last half of an iteration. This is split out so people can force incoming variable. If solveType_ is 2 then this may re-factorize while normally it would exit to re-factorize. Return codes Reasons to come out (normal mode/user mode): -1 normal -2 factorize now - good iteration/ NA -3 slight inaccuracy - refactorize - iteration done/ same but factor done -4 inaccuracy - refactorize - no iteration/ NA -5 something flagged - go round again/ pivot not possible +2 looks unbounded +3 max iterations (iteration done) With solveType_ ==2 this should Pivot in a variable and choose an outgoing one. Assumes primal feasible - will not go through a bound. Returns step length in theta Returns ray in ray_ Definition at line 1930 of file ClpSimplexPrimal.cpp. References CoinIndexedVector::checkClear(), ClpNonLinearCost::checkInfeasibilities(), CoinIndexedVector::clear(), clearAll(), ClpSimplexProgress::clearBadTimes(), CoinIndexedVector::denseVector(), CoinIndexedVector::getIndices(), ClpSimplex::housekeeping(), CoinIndexedVector::insert(), ClpSimplex::isColumn(), CoinMessageHandler::message(), primalRay(), primalRow(), ClpSimplex::sequenceWithin(), ClpSimplex::setFlagged(), ClpNonLinearCost::setOne(), ClpNonLinearCost::setOneOutgoing(), statusOfProblemInPrimal(), ClpMatrixBase::transposeTimes(), ClpSimplex::unpack(), ClpSimplex::unpackPacked(), updatePrimalsInPrimal(), and ClpPrimalColumnPivot::updateWeights(). Referenced by whileIterating().
01931 { 01932 01933 bool roundAgain=true; 01934 int returnCode=-1; 01935 01936 // loop round if user setting and doing refactorization 01937 while (roundAgain) { 01938 roundAgain=false; 01939 returnCode=-1; 01940 pivotRow_=-1; 01941 sequenceOut_=-1; 01942 rowArray_[1]->clear(); 01943 #if 0 01944 { 01945 int seq[]={612,643}; 01946 int k; 01947 for (k=0;k<sizeof(seq)/sizeof(int);k++) { 01948 int iSeq=seq[k]; 01949 if (getColumnStatus(iSeq)!=basic) { 01950 double djval; 01951 double * work; 01952 int number; 01953 int * which; 01954 01955 int iIndex; 01956 unpack(rowArray_[1],iSeq); 01957 factorization_->updateColumn(rowArray_[2],rowArray_[1]); 01958 djval = cost_[iSeq]; 01959 work=rowArray_[1]->denseVector(); 01960 number=rowArray_[1]->getNumElements(); 01961 which=rowArray_[1]->getIndices(); 01962 01963 for (iIndex=0;iIndex<number;iIndex++) { 01964 01965 int iRow = which[iIndex]; 01966 double alpha = work[iRow]; 01967 int iPivot=pivotVariable_[iRow]; 01968 djval -= alpha*cost_[iPivot]; 01969 } 01970 double comp = 1.0e-8 + 1.0e-7*(max(fabs(dj_[iSeq]),fabs(djval))); 01971 if (fabs(djval-dj_[iSeq])>comp) 01972 printf("Bad dj %g for %d - true is %g\n", 01973 dj_[iSeq],iSeq,djval); 01974 assert (fabs(djval)<1.0e-3||djval*dj_[iSeq]>0.0); 01975 rowArray_[1]->clear(); 01976 } 01977 } 01978 } 01979 #endif 01980 01981 // we found a pivot column 01982 // update the incoming column 01983 unpackPacked(rowArray_[1]); 01984 // save reduced cost 01985 double saveDj = dualIn_; 01986 factorization_->updateColumnFT(rowArray_[2],rowArray_[1]); 01987 // do ratio test and re-compute dj 01988 primalRow(rowArray_[1],rowArray_[3],rowArray_[2],rowArray_[0], 01989 ifValuesPass); 01990 if (ifValuesPass) { 01991 saveDj=dualIn_; 01992 if (pivotRow_==-1||(pivotRow_>=0&&fabs(alpha_)<1.0e-5)) { 01993 if(fabs(dualIn_)<1.0e2*dualTolerance_) { 01994 // try other way 01995 directionIn_=-directionIn_; 01996 primalRow(rowArray_[1],rowArray_[3],rowArray_[2],rowArray_[0], 01997 0); 01998 } 01999 if (pivotRow_==-1||(pivotRow_>=0&&fabs(alpha_)<1.0e-5)) { 02000 if (solveType_==1) { 02001 // reject it 02002 char x = isColumn(sequenceIn_) ? 'C' :'R'; 02003 handler_->message(CLP_SIMPLEX_FLAG,messages_) 02004 <<x<<sequenceWithin(sequenceIn_) 02005 <<CoinMessageEol; 02006 setFlagged(sequenceIn_); 02007 progress_->clearBadTimes(); 02008 lastBadIteration_ = numberIterations_; // say be more cautious 02009 clearAll(); 02010 pivotRow_=-1; 02011 } 02012 returnCode=-5; 02013 break; 02014 } 02015 } 02016 } 02017 double checkValue=1.0e-2; 02018 if (largestDualError_>1.0e-5) 02019 checkValue=1.0e-1; 02020 if (solveType_==1&&((saveDj*dualIn_<1.0e-20&&!ifValuesPass)|| 02021 fabs(saveDj-dualIn_)>checkValue*(1.0+fabs(saveDj)))) { 02022 handler_->message(CLP_PRIMAL_DJ,messages_) 02023 <<saveDj<<dualIn_ 02024 <<CoinMessageEol; 02025 if(lastGoodIteration_ != numberIterations_) { 02026 clearAll(); 02027 pivotRow_=-1; // say no weights update 02028 returnCode=-4; 02029 if(lastGoodIteration_+1 == numberIterations_) { 02030 // not looking wonderful - try cleaning bounds 02031 // put non-basics to bounds in case tolerance moved 02032 nonLinearCost_->checkInfeasibilities(0.0); 02033 } 02034 sequenceOut_=-1; 02035 break; 02036 } else { 02037 // take on more relaxed criterion 02038 if (saveDj*dualIn_<1.0e-20|| 02039 fabs(saveDj-dualIn_)>2.0e-1*(1.0+fabs(dualIn_))) { 02040 // need to reject something 02041 char x = isColumn(sequenceIn_) ? 'C' :'R'; 02042 handler_->message(CLP_SIMPLEX_FLAG,messages_) 02043 <<x<<sequenceWithin(sequenceIn_) 02044 <<CoinMessageEol; 02045 setFlagged(sequenceIn_); 02046 progress_->clearBadTimes(); 02047 lastBadIteration_ = numberIterations_; // say be more cautious 02048 clearAll(); 02049 pivotRow_=-1; 02050 returnCode=-5; 02051 sequenceOut_=-1; 02052 break; 02053 } 02054 } 02055 } 02056 if (pivotRow_>=0) { 02057 if (solveType_==2) { 02058 // **** Coding for user interface 02059 // do ray 02060 primalRay(rowArray_[1]); 02061 // update duals 02062 if (pivotRow_>=0) { 02063 // as packed need to find pivot row 02064 //assert (rowArray_[1]->packedMode()); 02065 //int i; 02066 02067 //alpha_ = rowArray_[1]->denseVector()[pivotRow_]; 02068 assert (fabs(alpha_)>1.0e-8); 02069 double multiplier = dualIn_/alpha_; 02070 rowArray_[0]->insert(pivotRow_,multiplier); 02071 factorization_->updateColumnTranspose(rowArray_[2],rowArray_[0]); 02072 // put row of tableau in rowArray[0] and columnArray[0] 02073 matrix_->transposeTimes(this,-1.0, 02074 rowArray_[0],columnArray_[1],columnArray_[0]); 02075 // update column djs 02076 int i; 02077 int * index = columnArray_[0]->getIndices(); 02078 int number = columnArray_[0]->getNumElements(); 02079 double * element = columnArray_[0]->denseVector(); 02080 for (i=0;i<number;i++) { 02081 int ii = index[i]; 02082 dj_[ii] += element[ii]; 02083 element[ii]=0.0; 02084 } 02085 columnArray_[0]->setNumElements(0); 02086 // and row djs 02087 index = rowArray_[0]->getIndices(); 02088 number = rowArray_[0]->getNumElements(); 02089 element = rowArray_[0]->denseVector(); 02090 for (i=0;i<number;i++) { 02091 int ii = index[i]; 02092 dj_[ii+numberColumns_] += element[ii]; 02093 dual_[ii] = dj_[ii+numberColumns_]; 02094 element[ii]=0.0; 02095 } 02096 rowArray_[0]->setNumElements(0); 02097 // check incoming 02098 assert (fabs(dj_[sequenceIn_])<1.0e-6); 02099 } 02100 } 02101 // if stable replace in basis 02102 int updateStatus = factorization_->replaceColumn(rowArray_[2], 02103 pivotRow_, 02104 alpha_); 02105 // if no pivots, bad update but reasonable alpha - take and invert 02106 if (updateStatus==2&& 02107 lastGoodIteration_==numberIterations_&&fabs(alpha_)>1.0e-5) 02108 updateStatus=4; 02109 if (updateStatus==1||updateStatus==4) { 02110 // slight error 02111 if (factorization_->pivots()>5||updateStatus==4) { 02112 returnCode=-3; 02113 } 02114 } else if (updateStatus==2) { 02115 // major error 02116 // better to have small tolerance even if slower 02117 factorization_->zeroTolerance(1.0e-15); 02118 int maxFactor = factorization_->maximumPivots(); 02119 if (maxFactor>10) { 02120 if (forceFactorization_<0) 02121 forceFactorization_= maxFactor; 02122 forceFactorization_ = max (1,(forceFactorization_>>1)); 02123 } 02124 // later we may need to unwind more e.g. fake bounds 02125 if(lastGoodIteration_ != numberIterations_) { 02126 clearAll(); 02127 pivotRow_=-1; 02128 if (solveType_==1) { 02129 returnCode=-4; 02130 break; 02131 } else { 02132 // user in charge - re-factorize 02133 int lastCleaned; 02134 ClpSimplexProgress dummyProgress; 02135 if (saveStatus_) 02136 statusOfProblemInPrimal(lastCleaned,1,&dummyProgress,true); 02137 else 02138 statusOfProblemInPrimal(lastCleaned,0,&dummyProgress,true); 02139 roundAgain=true; 02140 continue; 02141 } 02142 } else { 02143 // need to reject something 02144 if (solveType_==1) { 02145 char x = isColumn(sequenceIn_) ? 'C' :'R'; 02146 handler_->message(CLP_SIMPLEX_FLAG,messages_) 02147 <<x<<sequenceWithin(sequenceIn_) 02148 <<CoinMessageEol; 02149 setFlagged(sequenceIn_); 02150 progress_->clearBadTimes(); 02151 } 02152 lastBadIteration_ = numberIterations_; // say be more cautious 02153 clearAll(); 02154 pivotRow_=-1; 02155 sequenceOut_=-1; 02156 returnCode = -5; 02157 break; 02158 02159 } 02160 } else if (updateStatus==3) { 02161 // out of memory 02162 // increase space if not many iterations 02163 if (factorization_->pivots()< 02164 0.5*factorization_->maximumPivots()&& 02165 factorization_->pivots()<200) 02166 factorization_->areaFactor( 02167 factorization_->areaFactor() * 1.1); 02168 returnCode =-2; // factorize now 02169 } else if (updateStatus==5) { 02170 problemStatus_=-2; // factorize now 02171 } 02172 // here do part of steepest - ready for next iteration 02173 if (!ifValuesPass) 02174 primalColumnPivot_->updateWeights(rowArray_[1]); 02175 } else { 02176 if (pivotRow_==-1) { 02177 // no outgoing row is valid 02178 rowArray_[0]->clear(); 02179 if (!factorization_->pivots()) { 02180 returnCode = 2; //say looks unbounded 02181 // do ray 02182 primalRay(rowArray_[1]); 02183 } else if (solveType_==2) { 02184 // refactorize 02185 int lastCleaned; 02186 ClpSimplexProgress dummyProgress; 02187 if (saveStatus_) 02188 statusOfProblemInPrimal(lastCleaned,1,&dummyProgress,true); 02189 else 02190 statusOfProblemInPrimal(lastCleaned,0,&dummyProgress,true); 02191 roundAgain=true; 02192 continue; 02193 } else { 02194 returnCode = 4; //say looks unbounded but has iterated 02195 } 02196 break; 02197 } else { 02198 // flipping from bound to bound 02199 } 02200 } 02201 02202 02203 // update primal solution 02204 02205 double objectiveChange=0.0; 02206 // after this rowArray_[1] is not empty - used to update djs 02207 updatePrimalsInPrimal(rowArray_[1],theta_, objectiveChange,ifValuesPass); 02208 02209 double oldValue = valueIn_; 02210 if (directionIn_==-1) { 02211 // as if from upper bound 02212 if (sequenceIn_!=sequenceOut_) { 02213 // variable becoming basic 02214 valueIn_ -= fabs(theta_); 02215 } else { 02216 valueIn_=lowerIn_; 02217 } 02218 } else { 02219 // as if from lower bound 02220 if (sequenceIn_!=sequenceOut_) { 02221 // variable becoming basic 02222 valueIn_ += fabs(theta_); 02223 } else { 02224 valueIn_=upperIn_; 02225 } 02226 } 02227 objectiveChange += dualIn_*(valueIn_-oldValue); 02228 // outgoing 02229 if (sequenceIn_!=sequenceOut_) { 02230 if (directionOut_>0) { 02231 valueOut_ = lowerOut_; 02232 } else { 02233 valueOut_ = upperOut_; 02234 } 02235 if(valueOut_<lower_[sequenceOut_]-primalTolerance_) 02236 valueOut_=lower_[sequenceOut_]-0.9*primalTolerance_; 02237 else if (valueOut_>upper_[sequenceOut_]+primalTolerance_) 02238 valueOut_=upper_[sequenceOut_]+0.9*primalTolerance_; 02239 // may not be exactly at bound and bounds may have changed 02240 // Make sure outgoing looks feasible 02241 directionOut_=nonLinearCost_->setOneOutgoing(sequenceOut_,valueOut_); 02242 solution_[sequenceOut_]=valueOut_; 02243 } 02244 // change cost and bounds on incoming if primal 02245 nonLinearCost_->setOne(sequenceIn_,valueIn_); 02246 int whatNext=housekeeping(objectiveChange); 02247 02248 #if 0 02249 if (numberIterations_==1148) 02250 whatNext=1; 02251 if (numberIterations_>1200) 02252 exit(0); 02253 #endif 02254 if (whatNext==1) { 02255 returnCode =-2; // refactorize 02256 } else if (whatNext==2) { 02257 // maximum iterations or equivalent 02258 returnCode=3; 02259 } else if(numberIterations_ == lastGoodIteration_ 02260 + 2 * factorization_->maximumPivots()) { 02261 // done a lot of flips - be safe 02262 returnCode =-2; // refactorize 02263 } 02264 } 02265 if (solveType_==2&&(returnCode == -2||returnCode==-3)) { 02266 // refactorize here 02267 int lastCleaned; 02268 ClpSimplexProgress dummyProgress; 02269 if (saveStatus_) 02270 statusOfProblemInPrimal(lastCleaned,1,&dummyProgress,true); 02271 else 02272 statusOfProblemInPrimal(lastCleaned,0,&dummyProgress,true); 02273 if (problemStatus_==5) { 02274 printf("Singular basis\n"); 02275 problemStatus_=-1; 02276 returnCode=5; 02277 } 02278 } 02279 #ifdef CLP_DEBUG 02280 { 02281 int i; 02282 // not [1] as may have information 02283 for (i=0;i<4;i++) { 02284 if (i!=1) 02285 rowArray_[i]->checkClear(); 02286 } 02287 for (i=0;i<2;i++) { 02288 columnArray_[i]->checkClear(); 02289 } 02290 } 02291 #endif 02292 return returnCode; 02293 } |
|
Primal algorithm Method It tries to be a single phase approach with a weight of 1.0 being given to getting optimal and a weight of infeasibilityCost_ being given to getting primal feasible. In this version I have tried to be clever in a stupid way. The idea of fake bounds in dual seems to work so the primal analogue would be that of getting bounds on reduced costs (by a presolve approach) and using these for being above or below feasible region. I decided to waste memory and keep these explicitly. This allows for non-linear costs! I have not tested non-linear costs but will be glad to do something if a reasonable example is provided. The code is designed to take advantage of sparsity so arrays are seldom zeroed out from scratch or gone over in their entirety. The only exception is a full scan to find incoming variable for Dantzig row choice. For steepest edge we keep an updated list of dual infeasibilities (actually squares). On easy problems we don't need full scan - just pick first reasonable. This method has not been coded. One problem is how to tackle degeneracy and accuracy. At present I am using the modification of costs which I put in OSL and which was extended by Gill et al. I am still not sure whether we will also need explicit perturbation. The flow of primal is three while loops as follows: while (not finished) { while (not clean solution) { Factorize and/or clean up solution by changing bounds so primal feasible. If looks finished check fake primal bounds. Repeat until status is iterating (-1) or finished (0,1,2) } while (status==-1) { Iterate until no pivot in or out or time to re-factorize. Flow is: choose pivot column (incoming variable). if none then we are primal feasible so looks as if done but we need to break and check bounds etc. Get pivot column in tableau Choose outgoing row. If we don't find one then we look primal unbounded so break and check bounds etc. (Also the pivot tolerance is larger after any iterations so that may be reason) If we do find outgoing row, we may have to adjust costs to keep going forwards (anti-degeneracy). Check pivot will be stable and if unstable throw away iteration and break to re-factorize. If minor error re-factorize after iteration. Update everything (this may involve changing bounds on variables to stay primal feasible. } } TODO's (or maybe not) At present we never check we are going forwards. I overdid that in OSL so will try and make a last resort. Needs partial scan pivot in option. May need other anti-degeneracy measures, especially if we try and use loose tolerances as a way to solve in fewer iterations. I like idea of dynamic scaling. This gives opportunity to decouple different implications of scaling for accuracy, iteration count and feasibility tolerance. Reimplemented from ClpSimplex. Definition at line 99 of file ClpSimplexPrimal.cpp. References ClpNonLinearCost::checkInfeasibilities(), CoinIndexedVector::clear(), ClpSimplex::ClpSimplex(), ClpSimplex::computeDuals(), ClpSimplex::createRim(), ClpSimplex::gutsOfSolution(), CoinMessageHandler::logLevel(), CoinMessageHandler::message(), ClpNonLinearCost::numberInfeasibilities(), ClpPrimalColumnPivot::numberSprintColumns(), ClpModel::objectiveValue(), ClpSimplex::originalModel(), perturb(), CoinMessageHandler::printing(), ClpMatrixBase::refresh(), ClpSimplex::restoreData(), ClpSimplex::saveData(), ClpNonLinearCost::setAverageTheta(), ClpSimplexProgress::startCheck(), ClpSimplex::startup(), statusOfProblemInPrimal(), ClpNonLinearCost::sumInfeasibilities(), ClpPrimalColumnPivot::switchOffSprint(), unflag(), and whileIterating(). Referenced by ClpSimplexPrimalQuadratic::makeQuadratic(), ClpSimplexPrimalQuadratic::primalQuadratic(), and ClpSimplexPrimalQuadratic::primalSLP().
00100 { 00101 00102 /* 00103 Method 00104 00105 It tries to be a single phase approach with a weight of 1.0 being 00106 given to getting optimal and a weight of infeasibilityCost_ being 00107 given to getting primal feasible. In this version I have tried to 00108 be clever in a stupid way. The idea of fake bounds in dual 00109 seems to work so the primal analogue would be that of getting 00110 bounds on reduced costs (by a presolve approach) and using 00111 these for being above or below feasible region. I decided to waste 00112 memory and keep these explicitly. This allows for non-linear 00113 costs! 00114 00115 The code is designed to take advantage of sparsity so arrays are 00116 seldom zeroed out from scratch or gone over in their entirety. 00117 The only exception is a full scan to find incoming variable for 00118 Dantzig row choice. For steepest edge we keep an updated list 00119 of dual infeasibilities (actually squares). 00120 On easy problems we don't need full scan - just 00121 pick first reasonable. 00122 00123 One problem is how to tackle degeneracy and accuracy. At present 00124 I am using the modification of costs which I put in OSL and which was 00125 extended by Gill et al. I am still not sure of the exact details. 00126 00127 The flow of primal is three while loops as follows: 00128 00129 while (not finished) { 00130 00131 while (not clean solution) { 00132 00133 Factorize and/or clean up solution by changing bounds so 00134 primal feasible. If looks finished check fake primal bounds. 00135 Repeat until status is iterating (-1) or finished (0,1,2) 00136 00137 } 00138 00139 while (status==-1) { 00140 00141 Iterate until no pivot in or out or time to re-factorize. 00142 00143 Flow is: 00144 00145 choose pivot column (incoming variable). if none then 00146 we are primal feasible so looks as if done but we need to 00147 break and check bounds etc. 00148 00149 Get pivot column in tableau 00150 00151 Choose outgoing row. If we don't find one then we look 00152 primal unbounded so break and check bounds etc. (Also the 00153 pivot tolerance is larger after any iterations so that may be 00154 reason) 00155 00156 If we do find outgoing row, we may have to adjust costs to 00157 keep going forwards (anti-degeneracy). Check pivot will be stable 00158 and if unstable throw away iteration and break to re-factorize. 00159 If minor error re-factorize after iteration. 00160 00161 Update everything (this may involve changing bounds on 00162 variables to stay primal feasible. 00163 00164 } 00165 00166 } 00167 00168 At present we never check we are going forwards. I overdid that in 00169 OSL so will try and make a last resort. 00170 00171 Needs partial scan pivot in option. 00172 00173 May need other anti-degeneracy measures, especially if we try and use 00174 loose tolerances as a way to solve in fewer iterations. 00175 00176 I like idea of dynamic scaling. This gives opportunity to decouple 00177 different implications of scaling for accuracy, iteration count and 00178 feasibility tolerance. 00179 00180 */ 00181 00182 algorithm_ = +1; 00183 //specialOptions_ |= 4; 00184 00185 // save data 00186 ClpDataSave data = saveData(); 00187 00188 // Save so can see if doing after dual 00189 int initialStatus=problemStatus_; 00190 // initialize - maybe values pass and algorithm_ is +1 00191 if (!startup(ifValuesPass)) { 00192 00193 // Set average theta 00194 nonLinearCost_->setAverageTheta(1.0e3); 00195 int lastCleaned=0; // last time objective or bounds cleaned up 00196 00197 // Say no pivot has occurred (for steepest edge and updates) 00198 pivotRow_=-2; 00199 00200 // This says whether to restore things etc 00201 int factorType=0; 00202 if (problemStatus_<0&&perturbation_<100) { 00203 perturb(0); 00204 // Can't get here if values pass 00205 assert (!ifValuesPass); 00206 gutsOfSolution(NULL,NULL); 00207 if (handler_->logLevel()>2) { 00208 handler_->message(CLP_SIMPLEX_STATUS,messages_) 00209 <<numberIterations_<<objectiveValue(); 00210 handler_->printing(sumPrimalInfeasibilities_>0.0) 00211 <<sumPrimalInfeasibilities_<<numberPrimalInfeasibilities_; 00212 handler_->printing(sumDualInfeasibilities_>0.0) 00213 <<sumDualInfeasibilities_<<numberDualInfeasibilities_; 00214 handler_->printing(numberDualInfeasibilitiesWithoutFree_ 00215 <numberDualInfeasibilities_) 00216 <<numberDualInfeasibilitiesWithoutFree_; 00217 handler_->message()<<CoinMessageEol; 00218 } 00219 } 00220 ClpSimplex * saveModel=NULL; 00221 int stopSprint=-1; 00222 int sprintPass=0; 00223 int reasonableSprintIteration=0; 00224 int lastSprintIteration=0; 00225 double lastObjectiveValue=COIN_DBL_MAX; 00226 // Start check for cycles 00227 progress_->startCheck(); 00228 /* 00229 Status of problem: 00230 0 - optimal 00231 1 - infeasible 00232 2 - unbounded 00233 -1 - iterating 00234 -2 - factorization wanted 00235 -3 - redo checking without factorization 00236 -4 - looks infeasible 00237 -5 - looks unbounded 00238 */ 00239 while (problemStatus_<0) { 00240 int iRow,iColumn; 00241 // clear 00242 for (iRow=0;iRow<4;iRow++) { 00243 rowArray_[iRow]->clear(); 00244 } 00245 00246 for (iColumn=0;iColumn<2;iColumn++) { 00247 columnArray_[iColumn]->clear(); 00248 } 00249 00250 // give matrix (and model costs and bounds a chance to be 00251 // refreshed (normally null) 00252 matrix_->refresh(this); 00253 // If getting nowhere - why not give it a kick 00254 #if 1 00255 if (perturbation_<101&&numberIterations_>2*(numberRows_+numberColumns_) 00256 &&initialStatus!=10) 00257 perturb(1); 00258 #endif 00259 // If we have done no iterations - special 00260 if (lastGoodIteration_==numberIterations_&&factorType) 00261 factorType=3; 00262 if (saveModel) { 00263 // Doing sprint 00264 if (sequenceIn_<0||numberIterations_>=stopSprint) { 00265 problemStatus_=-1; 00266 originalModel(saveModel); 00267 saveModel=NULL; 00268 if (sequenceIn_<0&&numberIterations_<reasonableSprintIteration&& 00269 sprintPass>100) 00270 primalColumnPivot_->switchOffSprint(); 00271 //lastSprintIteration=numberIterations_; 00272 printf("End small model\n"); 00273 } 00274 } 00275 00276 // may factorize, checks if problem finished 00277 statusOfProblemInPrimal(lastCleaned,factorType,progress_,true,saveModel); 00278 // See if sprint says redo beacuse of problems 00279 if (numberDualInfeasibilities_==-776) { 00280 // Need new set of variables 00281 problemStatus_=-1; 00282 originalModel(saveModel); 00283 saveModel=NULL; 00284 //lastSprintIteration=numberIterations_; 00285 printf("End small model after\n"); 00286 statusOfProblemInPrimal(lastCleaned,factorType,progress_,true,saveModel); 00287 } 00288 int numberSprintIterations=0; 00289 int numberSprintColumns = primalColumnPivot_->numberSprintColumns(numberSprintIterations); 00290 if (problemStatus_==777) { 00291 // problems so do one pass with normal 00292 problemStatus_=-1; 00293 originalModel(saveModel); 00294 saveModel=NULL; 00295 // Skip factorization 00296 //statusOfProblemInPrimal(lastCleaned,factorType,progress_,false,saveModel); 00297 statusOfProblemInPrimal(lastCleaned,factorType,progress_,true,saveModel); 00298 } else if (problemStatus_<0&&!saveModel&&numberSprintColumns&&firstFree_<0) { 00299 int numberSort=0; 00300 int numberFixed=0; 00301 int numberBasic=0; 00302 reasonableSprintIteration = numberIterations_ + 100; 00303 int * whichColumns = new int[numberColumns_]; 00304 double * weight = new double[numberColumns_]; 00305 int numberNegative=0; 00306 double sumNegative = 0.0; 00307 // now massage weight so all basic in plus good djs 00308 for (iColumn=0;iColumn<numberColumns_;iColumn++) { 00309 double dj = dj_[iColumn]; 00310 switch(getColumnStatus(iColumn)) { 00311 00312 case basic: 00313 dj = -1.0e50; 00314 numberBasic++; 00315 break; 00316 case atUpperBound: 00317 dj = -dj; 00318 break; 00319 case isFixed: 00320 dj=1.0e50; 00321 numberFixed++; 00322 break; 00323 case atLowerBound: 00324 dj = dj; 00325 break; 00326 case isFree: 00327 dj = -100.0*fabs(dj); 00328 break; 00329 case superBasic: 00330 dj = -100.0*fabs(dj); 00331 break; 00332 } 00333 if (dj<-dualTolerance_&&dj>-1.0e50) { 00334 numberNegative++; 00335 sumNegative -= dj; 00336 } 00337 weight[iColumn]=dj; 00338 whichColumns[iColumn] = iColumn; 00339 } 00340 handler_->message(CLP_SPRINT,messages_) 00341 <<sprintPass<<numberIterations_-lastSprintIteration<<objectiveValue()<<sumNegative 00342 <<numberNegative 00343 <<CoinMessageEol; 00344 sprintPass++; 00345 lastSprintIteration=numberIterations_; 00346 if (objectiveValue()*optimizationDirection_>lastObjectiveValue-1.0e-7&&sprintPass>5) { 00347 // switch off 00348 printf("Switching off sprint\n"); 00349 primalColumnPivot_->switchOffSprint(); 00350 } else { 00351 lastObjectiveValue = objectiveValue()*optimizationDirection_; 00352 // sort 00353 CoinSort_2(weight,weight+numberColumns_,whichColumns); 00354 numberSort = min(numberColumns_-numberFixed,numberBasic+numberSprintColumns); 00355 // Sort to make consistent ? 00356 std::sort(whichColumns,whichColumns+numberSort); 00357 saveModel = new ClpSimplex(this,numberSort,whichColumns); 00358 delete [] whichColumns; 00359 delete [] weight; 00360 // Skip factorization 00361 //statusOfProblemInPrimal(lastCleaned,factorType,progress_,false,saveModel); 00362 //statusOfProblemInPrimal(lastCleaned,factorType,progress_,true,saveModel); 00363 stopSprint = numberIterations_+numberSprintIterations; 00364 printf("Sprint with %d columns for %d iterations\n", 00365 numberSprintColumns,numberSprintIterations); 00366 } 00367 } 00368 00369 // Say good factorization 00370 factorType=1; 00371 00372 // Say no pivot has occurred (for steepest edge and updates) 00373 pivotRow_=-2; 00374 00375 // exit if victory declared 00376 if (problemStatus_>=0) 00377 break; 00378 00379 // Iterate 00380 whileIterating(ifValuesPass); 00381 } 00382 } 00383 // if infeasible get real values 00384 if (problemStatus_==1) { 00385 infeasibilityCost_=0.0; 00386 createRim(7); 00387 nonLinearCost_->checkInfeasibilities(0.0); 00388 sumPrimalInfeasibilities_=nonLinearCost_->sumInfeasibilities(); 00389 numberPrimalInfeasibilities_= nonLinearCost_->numberInfeasibilities(); 00390 // and get good feasible duals 00391 computeDuals(NULL); 00392 } 00393 // clean up 00394 unflag(); 00395 finish(); 00396 restoreData(data); 00397 return problemStatus_; 00398 } |
|
Chooses primal pivot column updateArray has cost updates (also use pivotRow_ from last iteration) Would be faster with separate region to scan and will have this (with square of infeasibility) when steepest For easy problems we can just choose one of the first columns we look at Definition at line 1324 of file ClpSimplexPrimal.cpp. References ClpNonLinearCost::changeDownInCost(), ClpNonLinearCost::changeUpInCost(), ClpSimplex::currentPrimalTolerance(), ClpNonLinearCost::lookBothWays(), ClpPrimalColumnPivot::pivotColumn(), and ClpNonLinearCost::setOne(). Referenced by ClpSimplexPrimalQuadratic::whileIterating(), and whileIterating().
01329 { 01330 sequenceIn_ = primalColumnPivot_->pivotColumn(updates,spareRow1, 01331 spareRow2,spareColumn1, 01332 spareColumn2); 01333 if (sequenceIn_>=0) { 01334 valueIn_=solution_[sequenceIn_]; 01335 dualIn_=dj_[sequenceIn_]; 01336 if (nonLinearCost_->lookBothWays()) { 01337 // double check 01338 ClpSimplex::Status status = getStatus(sequenceIn_); 01339 01340 switch(status) { 01341 case ClpSimplex::atUpperBound: 01342 if (dualIn_<0.0) { 01343 // move to other side 01344 printf("For %d U (%g, %g, %g) dj changed from %g", 01345 sequenceIn_,lower_[sequenceIn_],solution_[sequenceIn_], 01346 upper_[sequenceIn_],dualIn_); 01347 dualIn_ -= nonLinearCost_->changeUpInCost(sequenceIn_); 01348 printf(" to %g\n",dualIn_); 01349 nonLinearCost_->setOne(sequenceIn_,upper_[sequenceIn_]+2.0*currentPrimalTolerance()); 01350 setStatus(sequenceIn_,ClpSimplex::atLowerBound); 01351 } 01352 break; 01353 case ClpSimplex::atLowerBound: 01354 if (dualIn_>0.0) { 01355 // move to other side 01356 printf("For %d L (%g, %g, %g) dj changed from %g", 01357 sequenceIn_,lower_[sequenceIn_],solution_[sequenceIn_], 01358 upper_[sequenceIn_],dualIn_); 01359 dualIn_ -= nonLinearCost_->changeDownInCost(sequenceIn_); 01360 printf(" to %g\n",dualIn_); 01361 nonLinearCost_->setOne(sequenceIn_,lower_[sequenceIn_]-2.0*currentPrimalTolerance()); 01362 setStatus(sequenceIn_,ClpSimplex::atUpperBound); 01363 } 01364 break; 01365 default: 01366 break; 01367 } 01368 } 01369 lowerIn_=lower_[sequenceIn_]; 01370 upperIn_=upper_[sequenceIn_]; 01371 if (dualIn_>0.0) 01372 directionIn_ = -1; 01373 else 01374 directionIn_ = 1; 01375 } else { 01376 sequenceIn_ = -1; 01377 } 01378 } |
|
Row array has pivot column This chooses pivot row. Rhs array is used for distance to next bound (for speed) For speed, we may need to go to a bucket approach when many variables go through bounds If valuesPass non-zero then compute dj for direction Definition at line 949 of file ClpSimplexPrimal.cpp. References ClpNonLinearCost::averageTheta(), ClpNonLinearCost::changeInCost(), CoinIndexedVector::clear(), CoinIndexedVector::denseVector(), CoinIndexedVector::getIndices(), CoinIndexedVector::getNumElements(), ClpNonLinearCost::goBackAll(), CoinMessageHandler::logLevel(), ClpNonLinearCost::nearest(), ClpSimplex::setActive(), ClpNonLinearCost::setAverageTheta(), CoinIndexedVector::setNumElements(), CoinIndexedVector::setPacked(), and ClpSimplex::solution(). Referenced by pivotResult().
00954 { 00955 //rowArray->scanAndPack(); 00956 if (valuesPass) { 00957 dualIn_ = cost_[sequenceIn_]; 00958 00959 double * work=rowArray->denseVector(); 00960 int number=rowArray->getNumElements(); 00961 int * which=rowArray->getIndices(); 00962 00963 int iIndex; 00964 for (iIndex=0;iIndex<number;iIndex++) { 00965 00966 int iRow = which[iIndex]; 00967 double alpha = work[iIndex]; 00968 int iPivot=pivotVariable_[iRow]; 00969 dualIn_ -= alpha*cost_[iPivot]; 00970 } 00971 // determine direction here 00972 if (dualIn_<-dualTolerance_) { 00973 directionIn_=1; 00974 } else if (dualIn_>dualTolerance_) { 00975 directionIn_=-1; 00976 } else { 00977 // towards nearest bound 00978 if (valueIn_-lowerIn_<upperIn_-valueIn_) { 00979 directionIn_=-1; 00980 dualIn_=dualTolerance_; 00981 } else { 00982 directionIn_=1; 00983 dualIn_=-dualTolerance_; 00984 } 00985 } 00986 } 00987 00988 // sequence stays as row number until end 00989 pivotRow_=-1; 00990 int numberRemaining=0; 00991 00992 double totalThru=0.0; // for when variables flip 00993 double acceptablePivot=1.0e-7; 00994 if (factorization_->pivots()) 00995 acceptablePivot=1.0e-5; // if we have iterated be more strict 00996 double bestEverPivot=acceptablePivot; 00997 int lastPivotRow = -1; 00998 double lastPivot=0.0; 00999 double lastTheta=1.0e50; 01000 01001 // use spareArrays to put ones looked at in 01002 // First one is list of candidates 01003 // We could compress if we really know we won't need any more 01004 // Second array has current set of pivot candidates 01005 // with a backup list saved in double * part of indexed vector 01006 01007 // pivot elements 01008 double * spare; 01009 // indices 01010 int * index; 01011 spareArray->clear(); 01012 spare = spareArray->denseVector(); 01013 index = spareArray->getIndices(); 01014 01015 // we also need somewhere for effective rhs 01016 double * rhs=rhsArray->denseVector(); 01017 //int * indexRhs = rhsArray->getIndices(); 01018 //int numberFlip=0; // Those which may change if flips 01019 01020 /* 01021 First we get a list of possible pivots. We can also see if the 01022 problem looks unbounded. 01023 01024 At first we increase theta and see what happens. We start 01025 theta at a reasonable guess. If in right area then we do bit by bit. 01026 We save possible pivot candidates 01027 01028 */ 01029 01030 // do first pass to get possibles 01031 // We can also see if unbounded 01032 01033 double * work=rowArray->denseVector(); 01034 int number=rowArray->getNumElements(); 01035 int * which=rowArray->getIndices(); 01036 01037 // we need to swap sign if coming in from ub 01038 double way = directionIn_; 01039 double maximumMovement; 01040 if (way>0.0) 01041 maximumMovement = min(1.0e30,upperIn_-valueIn_); 01042 else 01043 maximumMovement = min(1.0e30,valueIn_-lowerIn_); 01044 01045 double averageTheta = nonLinearCost_->averageTheta(); 01046 double tentativeTheta = min(10.0*averageTheta,maximumMovement); 01047 double upperTheta = maximumMovement; 01048 if (tentativeTheta>0.5*maximumMovement) 01049 tentativeTheta=maximumMovement; 01050 01051 double dualCheck = fabs(dualIn_); 01052 // but make a bit more pessimistic 01053 dualCheck=max(dualCheck-100.0*dualTolerance_,0.99*dualCheck); 01054 01055 int iIndex; 01056 bool gotList=false; 01057 int pivotOne=-1; 01058 while (!gotList) { 01059 pivotOne=-1; 01060 totalThru=0.0; 01061 // We also re-compute reduced cost 01062 numberRemaining=0; 01063 dualIn_ = cost_[sequenceIn_]; 01064 double tolerance = primalTolerance_*1.002; 01065 for (iIndex=0;iIndex<number;iIndex++) { 01066 01067 int iRow = which[iIndex]; 01068 double alpha = work[iIndex]; 01069 int iPivot=pivotVariable_[iRow]; 01070 dualIn_ -= alpha*cost_[iPivot]; 01071 alpha *= way; 01072 double oldValue = solution_[iPivot]; 01073 // get where in bound sequence 01074 if (alpha>0.0) { 01075 // basic variable going towards lower bound 01076 double bound = lower_[iPivot]; 01077 oldValue -= bound; 01078 } else { 01079 // basic variable going towards upper bound 01080 double bound = upper_[iPivot]; 01081 oldValue = bound-oldValue; 01082 } 01083 01084 double value = oldValue-tentativeTheta*fabs(alpha); 01085 assert (oldValue>=-tolerance); 01086 if (value<=tolerance) { 01087 value=oldValue-upperTheta*fabs(alpha); 01088 if (value<-primalTolerance_&&fabs(alpha)>=acceptablePivot) { 01089 upperTheta = (oldValue+primalTolerance_)/fabs(alpha); 01090 pivotOne=numberRemaining; 01091 } 01092 // add to list 01093 spare[numberRemaining]=alpha; 01094 rhs[numberRemaining]=oldValue; 01095 index[numberRemaining++]=iRow; 01096 totalThru += fabs(alpha); 01097 setActive(iRow); 01098 //} else if (value<primalTolerance_*1.002) { 01099 // May change if is a flip 01100 //indexRhs[numberFlip++]=iRow; 01101 } 01102 } 01103 if (upperTheta<maximumMovement&&totalThru*infeasibilityCost_>=1.0001*dualCheck) { 01104 // Can pivot here 01105 gotList=true; 01106 } else if (tentativeTheta<maximumMovement) { 01107 //printf("Going round with average theta of %g\n",averageTheta); 01108 tentativeTheta=maximumMovement; 01109 } else { 01110 gotList=true; 01111 } 01112 } 01113 totalThru=0.0; 01114 // we need to keep where rhs non-zeros are 01115 int numberInRhs=numberRemaining; 01116 memcpy(rhsArray->getIndices(),index,numberInRhs*sizeof(int)); 01117 rhsArray->setNumElements(numberInRhs); 01118 rhsArray->setPacked(); 01119 01120 theta_=maximumMovement; 01121 01122 bool goBackOne = false; 01123 01124 //printf("%d remain out of %d\n",numberRemaining,number); 01125 int iTry=0; 01126 #define MAXTRY 1000 01127 if (numberRemaining&&upperTheta<maximumMovement) { 01128 // First check if previously chosen one will work 01129 if (pivotOne>=0&&0) { 01130 double thruCost = infeasibilityCost_*fabs(spare[pivotOne]); 01131 if (thruCost>=0.99*fabs(dualIn_)) 01132 printf("Could pivot on %d as change %g dj %g\n", 01133 index[pivotOne],thruCost,dualIn_); 01134 double alpha = spare[pivotOne]; 01135 double oldValue = rhs[pivotOne]; 01136 theta_ = oldValue/fabs(alpha); 01137 pivotRow_=pivotOne; 01138 // Stop loop 01139 iTry=MAXTRY; 01140 } 01141 01142 // first get ratio with tolerance 01143 for ( ;iTry<MAXTRY;iTry++) { 01144 01145 upperTheta=maximumMovement; 01146 int iBest=-1; 01147 for (iIndex=0;iIndex<numberRemaining;iIndex++) { 01148 01149 double alpha = fabs(spare[iIndex]); 01150 double oldValue = rhs[iIndex]; 01151 double value = oldValue-upperTheta*alpha; 01152 01153 if (value<-primalTolerance_ && alpha>=acceptablePivot) { 01154 upperTheta = (oldValue+primalTolerance_)/alpha; 01155 iBest=iIndex; // just in case weird numbers 01156 } 01157 } 01158 01159 // now look at best in this lot 01160 double bestPivot=acceptablePivot; 01161 pivotRow_=-1; 01162 for (iIndex=0;iIndex<numberRemaining;iIndex++) { 01163 01164 int iRow = index[iIndex]; 01165 double alpha = spare[iIndex]; 01166 double oldValue = rhs[iIndex]; 01167 double value = oldValue-upperTheta*fabs(alpha); 01168 01169 if (value<=0||iBest==iIndex) { 01170 // how much would it cost to go thru and modify bound 01171 totalThru += nonLinearCost_->changeInCost(pivotVariable_[iRow],alpha,rhs[iIndex]); 01172 setActive(iRow); 01173 if (fabs(alpha)>bestPivot) { 01174 bestPivot=fabs(alpha); 01175 theta_ = oldValue/bestPivot; 01176 pivotRow_=iIndex; 01177 } 01178 } 01179 } 01180 if (bestPivot<0.1*bestEverPivot&& 01181 bestEverPivot>1.0e-6&& bestPivot<1.0e-3) { 01182 // back to previous one 01183 goBackOne = true; 01184 break; 01185 } else if (pivotRow_==-1&&upperTheta>largeValue_) { 01186 if (lastPivot>acceptablePivot) { 01187 // back to previous one 01188 goBackOne = true; 01189 } else { 01190 // can only get here if all pivots so far too small 01191 } 01192 break; 01193 } else if (totalThru>=dualCheck) { 01194 break; // no point trying another loop 01195 } else { 01196 lastPivotRow=pivotRow_; 01197 lastTheta = theta_; 01198 if (bestPivot>bestEverPivot) 01199 bestEverPivot=bestPivot; 01200 } 01201 } 01202 // can get here without pivotRow_ set but with lastPivotRow 01203 if (goBackOne||(pivotRow_<0&&lastPivotRow>=0)) { 01204 // back to previous one 01205 pivotRow_=lastPivotRow; 01206 theta_ = lastTheta; 01207 } 01208 } else { 01209 // mark ones which may move 01210 //for (int i=0;i<numberFlip;i++) { 01211 //int iRow= indexRhs[i]; 01212 //setActive(iRow); 01213 //} 01214 } 01215 //if (iTry>50) 01216 //printf("** %d tries\n",iTry); 01217 if (pivotRow_>=0) { 01218 int position=pivotRow_; // position in list 01219 pivotRow_=index[position]; 01220 //alpha_ = work[pivotRow_]; 01221 alpha_ = way*spare[position]; 01222 // translate to sequence 01223 sequenceOut_ = pivotVariable_[pivotRow_]; 01224 valueOut_ = solution(sequenceOut_); 01225 lowerOut_=lower_[sequenceOut_]; 01226 upperOut_=upper_[sequenceOut_]; 01227 #define MINIMUMTHETA 1.0e-12 01228 // Movement should be minimum for anti-degeneracy - unless 01229 // fixed variable out 01230 double minimumTheta; 01231 if (upperOut_>lowerOut_) 01232 minimumTheta=MINIMUMTHETA; 01233 else 01234 minimumTheta=0.0; 01235 // will we need to increase tolerance 01236 //#define CLP_DEBUG 01237 #ifdef CLP_DEBUG 01238 bool found=false; 01239 #endif 01240 double largestInfeasibility = primalTolerance_; 01241 if (theta_<minimumTheta&&(specialOptions_&4)==0&&!valuesPass) { 01242 theta_=minimumTheta; 01243 for (iIndex=0;iIndex<numberRemaining-numberRemaining;iIndex++) { 01244 largestInfeasibility = max (largestInfeasibility, 01245 -(rhs[iIndex]-fabs(spare[iIndex])*theta_)); 01246 } 01247 #define CLP_DEBUG 01248 #ifdef CLP_DEBUG 01249 if (largestInfeasibility>primalTolerance_&&(handler_->logLevel()&32)>-1) 01250 printf("Primal tolerance increased from %g to %g\n", 01251 primalTolerance_,largestInfeasibility); 01252 #endif 01253 #undef CLP_DEBUG 01254 primalTolerance_ = max(primalTolerance_,largestInfeasibility); 01255 } 01256 // Need to look at all in some cases 01257 if (theta_>tentativeTheta) { 01258 for (iIndex=0;iIndex<number;iIndex++) 01259 setActive(which[iIndex]); 01260 } 01261 if (way<0.0) 01262 theta_ = - theta_; 01263 double newValue = valueOut_ - theta_*alpha_; 01264 // If 4 bit set - Force outgoing variables to exact bound (primal) 01265 if (alpha_*way<0.0) { 01266 directionOut_=-1; // to upper bound 01267 if (fabs(theta_)>1.0e-6||(specialOptions_&4)!=0) { 01268 upperOut_ = nonLinearCost_->nearest(sequenceOut_,newValue); 01269 } else { 01270 upperOut_ = newValue; 01271 } 01272 } else { 01273 directionOut_=1; // to lower bound 01274 if (fabs(theta_)>1.0e-6||(specialOptions_&4)!=0) { 01275 lowerOut_ = nonLinearCost_->nearest(sequenceOut_,newValue); 01276 } else { 01277 lowerOut_ = newValue; 01278 } 01279 } 01280 dualOut_ = reducedCost(sequenceOut_); 01281 } else if (maximumMovement<1.0e20) { 01282 // flip 01283 pivotRow_ = -2; // so we can tell its a flip 01284 sequenceOut_ = sequenceIn_; 01285 valueOut_ = valueIn_; 01286 dualOut_ = dualIn_; 01287 lowerOut_ = lowerIn_; 01288 upperOut_ = upperIn_; 01289 alpha_ = 0.0; 01290 if (way<0.0) { 01291 directionOut_=1; // to lower bound 01292 theta_ = lowerOut_ - valueOut_; 01293 } else { 01294 directionOut_=-1; // to upper bound 01295 theta_ = upperOut_ - valueOut_; 01296 } 01297 } 01298 01299 double theta1 = max(theta_,1.0e-12); 01300 double theta2 = numberIterations_*nonLinearCost_->averageTheta(); 01301 // Set average theta 01302 nonLinearCost_->setAverageTheta((theta1+theta2)/((double) (numberIterations_+1))); 01303 //if (numberIterations_%1000==0) 01304 //printf("average theta is %g\n",nonLinearCost_->averageTheta()); 01305 01306 // clear arrays 01307 01308 memset(spare,0,numberRemaining*sizeof(double)); 01309 01310 // put back original bounds etc 01311 nonLinearCost_->goBackAll(rhsArray); 01312 01313 rhsArray->clear(); 01314 01315 } |
|
Refactorizes if necessary Checks if finished. Updates status. lastCleaned refers to iteration at which some objective/feasibility cleaning too place. type - 0 initial so set up save arrays etc
Definition at line 548 of file ClpSimplexPrimal.cpp. References alwaysOptimal(), ClpSimplexProgress::badTimes(), ClpNonLinearCost::checkInfeasibilities(), ClpSimplex::createRim(), ClpSimplex::dualFeasible(), ClpSimplexProgress::endOddState(), ClpNonLinearCost::feasibleReportCost(), ClpSimplex::gutsOfSolution(), ClpSimplexProgress::lastIterationNumber(), ClpSimplexProgress::lastObjective(), ClpPrimalColumnPivot::looksOptimal(), ClpSimplexProgress::looping(), CoinMessageHandler::message(), ClpSimplexProgress::newOddState(), ClpNonLinearCost::numberInfeasibilities(), ClpSimplexProgress::oddState(), ClpSimplex::primalFeasible(), CoinMessageHandler::printing(), ClpPrimalColumnPivot::saveWeights(), ClpNonLinearCost::sumInfeasibilities(), unflag(), unPerturb(), and ClpNonLinearCost::zapCosts(). Referenced by pivotResult(), and primal().
00552 { 00553 if (type==2) { 00554 // trouble - restore solution 00555 memcpy(status_ ,saveStatus_,(numberColumns_+numberRows_)*sizeof(char)); 00556 memcpy(rowActivityWork_,savedSolution_+numberColumns_ , 00557 numberRows_*sizeof(double)); 00558 memcpy(columnActivityWork_,savedSolution_ , 00559 numberColumns_*sizeof(double)); 00560 forceFactorization_=1; // a bit drastic but .. 00561 pivotRow_=-1; // say no weights update 00562 changeMade_++; // say change made 00563 } 00564 int saveThreshold = factorization_->sparseThreshold(); 00565 int tentativeStatus = problemStatus_; 00566 if (problemStatus_>-3||problemStatus_==-4) { 00567 // factorize 00568 // later on we will need to recover from singularities 00569 // also we could skip if first time 00570 // do weights 00571 // This may save pivotRow_ for use 00572 if (doFactorization) 00573 primalColumnPivot_->saveWeights(this,1); 00574 00575 if (type&&doFactorization) { 00576 // is factorization okay? 00577 if (internalFactorize(1)) { 00578 if (solveType_==2) { 00579 // say odd 00580 problemStatus_=5; 00581 return; 00582 } 00583 #if 1 00584 // switch off dense 00585 int saveDense = factorization_->denseThreshold(); 00586 factorization_->setDenseThreshold(0); 00587 internalFactorize(2); 00588 factorization_->setDenseThreshold(saveDense); 00589 #else 00590 00591 // no - restore previous basis 00592 assert (type==1); 00593 memcpy(status_ ,saveStatus_,(numberColumns_+numberRows_)*sizeof(char)); 00594 memcpy(rowActivityWork_,savedSolution_+numberColumns_ , 00595 numberRows_*sizeof(double)); 00596 memcpy(columnActivityWork_,savedSolution_ , 00597 numberColumns_*sizeof(double)); 00598 forceFactorization_=1; // a bit drastic but .. 00599 type = 2; 00600 assert (internalFactorize(1)==0); 00601 #endif 00602 changeMade_++; // say change made 00603 } 00604 } 00605 if (problemStatus_!=-4) 00606 problemStatus_=-3; 00607 } 00608 // at this stage status is -3 or -5 if looks unbounded 00609 // get primal and dual solutions 00610 // put back original costs and then check 00611 createRim(4); 00612 gutsOfSolution(NULL,NULL,(firstFree_>=0)); 00613 // Double check reduced costs if no action 00614 if (progress->lastIterationNumber(0)==numberIterations_) { 00615 if (primalColumnPivot_->looksOptimal()) { 00616 numberDualInfeasibilities_ = 0; 00617 sumDualInfeasibilities_ = 0.0; 00618 } 00619 } 00620 // Check if looping 00621 int loop; 00622 if (type!=2) 00623 loop = progress->looping(); 00624 else 00625 loop=-1; 00626 if (loop>=0) { 00627 if (!problemStatus_) { 00628 // declaring victory 00629 numberPrimalInfeasibilities_ = 0; 00630 sumPrimalInfeasibilities_ = 0.0; 00631 } else { 00632 problemStatus_ = loop; //exit if in loop 00633 problemStatus_ = 10; // instead - try other algorithm 00634 } 00635 problemStatus_ = 10; // instead - try other algorithm 00636 return ; 00637 } else if (loop<-1) { 00638 // Is it time for drastic measures 00639 if (nonLinearCost_->numberInfeasibilities()&&progress->badTimes()>5&& 00640 progress->oddState()<10&&progress->oddState()>=0) { 00641 progress->newOddState(); 00642 nonLinearCost_->zapCosts(); 00643 } 00644 // something may have changed 00645 gutsOfSolution(NULL,NULL); 00646 } 00647 // If progress then reset costs 00648 if (loop==-1&&!nonLinearCost_->numberInfeasibilities()&&progress->oddState()<0) { 00649 createRim(4,false); // costs back 00650 delete nonLinearCost_; 00651 nonLinearCost_ = new ClpNonLinearCost(this); 00652 progress->endOddState(); 00653 gutsOfSolution(NULL,NULL); 00654 } 00655 // Flag to say whether to go to dual to clean up 00656 bool goToDual=false; 00657 // really for free variables in 00658 //if((progressFlag_&2)!=0) 00659 //problemStatus_=-1;; 00660 progressFlag_ = 0; //reset progress flag 00661 00662 handler_->message(CLP_SIMPLEX_STATUS,messages_) 00663 <<numberIterations_<<nonLinearCost_->feasibleReportCost(); 00664 handler_->printing(nonLinearCost_->numberInfeasibilities()>0) 00665 <<nonLinearCost_->sumInfeasibilities()<<nonLinearCost_->numberInfeasibilities(); 00666 handler_->printing(sumDualInfeasibilities_>0.0) 00667 <<sumDualInfeasibilities_<<numberDualInfeasibilities_; 00668 handler_->printing(numberDualInfeasibilitiesWithoutFree_ 00669 <numberDualInfeasibilities_) 00670 <<numberDualInfeasibilitiesWithoutFree_; 00671 handler_->message()<<CoinMessageEol; 00672 if (!primalFeasible()) { 00673 nonLinearCost_->checkInfeasibilities(primalTolerance_); 00674 gutsOfSolution(NULL,NULL); 00675 } 00676 // we may wish to say it is optimal even if infeasible 00677 bool alwaysOptimal = (specialOptions_&1)!=0; 00678 // give code benefit of doubt 00679 if (sumOfRelaxedDualInfeasibilities_ == 0.0&& 00680 sumOfRelaxedPrimalInfeasibilities_ == 0.0) { 00681 // say optimal (with these bounds etc) 00682 numberDualInfeasibilities_ = 0; 00683 sumDualInfeasibilities_ = 0.0; 00684 numberPrimalInfeasibilities_ = 0; 00685 sumPrimalInfeasibilities_ = 0.0; 00686 // But check if in sprint 00687 if (originalModel) { 00688 // Carry on and re-do 00689 numberDualInfeasibilities_ = -776; 00690 } 00691 } 00692 // had ||(type==3&&problemStatus_!=-5) -- ??? why ???? 00693 if (dualFeasible()||problemStatus_==-4) { 00694 if (nonLinearCost_->numberInfeasibilities()&&!alwaysOptimal) { 00695 //may need infeasiblity cost changed 00696 // we can see if we can construct a ray 00697 // make up a new objective 00698 double saveWeight = infeasibilityCost_; 00699 // save nonlinear cost as we are going to switch off costs 00700 ClpNonLinearCost * nonLinear = nonLinearCost_; 00701 // do twice to make sure Primal solution has settled 00702 // put non-basics to bounds in case tolerance moved 00703 // put back original costs 00704 createRim(4); 00705 nonLinearCost_->checkInfeasibilities(0.0); 00706 gutsOfSolution(NULL,NULL); 00707 00708 infeasibilityCost_=1.0e100; 00709 // put back original costs 00710 createRim(4); 00711 nonLinearCost_->checkInfeasibilities(primalTolerance_); 00712 // may have fixed infeasibilities - double check 00713 if (nonLinearCost_->numberInfeasibilities()==0) { 00714 // carry on 00715 problemStatus_ = -1; 00716 infeasibilityCost_=saveWeight; 00717 nonLinearCost_->checkInfeasibilities(primalTolerance_); 00718 } else { 00719 nonLinearCost_=NULL; 00720 // scale 00721 int i; 00722 for (i=0;i<numberRows_+numberColumns_;i++) 00723 cost_[i] *= 1.0e-95; 00724 gutsOfSolution(NULL,NULL); 00725 nonLinearCost_=nonLinear; 00726 infeasibilityCost_=saveWeight; 00727 if ((infeasibilityCost_>=1.0e18|| 00728 numberDualInfeasibilities_==0)&&perturbation_==101) { 00729 goToDual=unPerturb(); // stop any further perturbation 00730 if (nonLinearCost_->sumInfeasibilities()>1.0e-1) 00731 goToDual=false; 00732 nonLinearCost_->checkInfeasibilities(primalTolerance_); 00733 numberDualInfeasibilities_=1; // carry on 00734 problemStatus_=-1; 00735 } 00736 if (infeasibilityCost_>=1.0e20|| 00737 numberDualInfeasibilities_==0) { 00738 // we are infeasible - use as ray 00739 delete [] ray_; 00740 ray_ = new double [numberRows_]; 00741 memcpy(ray_,dual_,numberRows_*sizeof(double)); 00742 // and get feasible duals 00743 infeasibilityCost_=0.0; 00744 createRim(4); 00745 nonLinearCost_->checkInfeasibilities(primalTolerance_); 00746 gutsOfSolution(NULL,NULL); 00747 // so will exit 00748 infeasibilityCost_=1.0e30; 00749 // reset infeasibilities 00750 sumPrimalInfeasibilities_=nonLinearCost_->sumInfeasibilities();; 00751 numberPrimalInfeasibilities_= 00752 nonLinearCost_->numberInfeasibilities(); 00753 } 00754 if (infeasibilityCost_<1.0e20) { 00755 infeasibilityCost_ *= 5.0; 00756 changeMade_++; // say change made 00757 handler_->message(CLP_PRIMAL_WEIGHT,messages_) 00758 <<infeasibilityCost_ 00759 <<CoinMessageEol; 00760 // put back original costs and then check 00761 createRim(4); 00762 nonLinearCost_->checkInfeasibilities(0.0); 00763 gutsOfSolution(NULL,NULL); 00764 problemStatus_=-1; //continue 00765 goToDual=false; 00766 } else { 00767 // say infeasible 00768 problemStatus_ = 1; 00769 } 00770 } 00771 } else { 00772 // may be optimal 00773 if (perturbation_==101) { 00774 goToDual=unPerturb(); // stop any further perturbation 00775 lastCleaned=-1; // carry on 00776 } 00777 bool unflagged = unflag(); 00778 if ( lastCleaned!=numberIterations_||unflagged) { 00779 handler_->message(CLP_PRIMAL_OPTIMAL,messages_) 00780 <<primalTolerance_ 00781 <<CoinMessageEol; 00782 if (numberTimesOptimal_<4) { 00783 numberTimesOptimal_++; 00784 changeMade_++; // say change made 00785 if (numberTimesOptimal_==1) { 00786 // better to have small tolerance even if slower 00787 factorization_->zeroTolerance(1.0e-15); 00788 } 00789 lastCleaned=numberIterations_; 00790 if (primalTolerance_!=dblParam_[ClpPrimalTolerance]) 00791 handler_->message(CLP_PRIMAL_ORIGINAL,messages_) 00792 <<CoinMessageEol; 00793 double oldTolerance = primalTolerance_; 00794 primalTolerance_=dblParam_[ClpPrimalTolerance]; 00795 #if 0 00796 double * xcost = new double[numberRows_+numberColumns_]; 00797 double * xlower = new double[numberRows_+numberColumns_]; 00798 double * xupper = new double[numberRows_+numberColumns_]; 00799 double * xdj = new double[numberRows_+numberColumns_]; 00800 double * xsolution = new double[numberRows_+numberColumns_]; 00801 memcpy(xcost,cost_,(numberRows_+numberColumns_)*sizeof(double)); 00802 memcpy(xlower,lower_,(numberRows_+numberColumns_)*sizeof(double)); 00803 memcpy(xupper,upper_,(numberRows_+numberColumns_)*sizeof(double)); 00804 memcpy(xdj,dj_,(numberRows_+numberColumns_)*sizeof(double)); 00805 memcpy(xsolution,solution_,(numberRows_+numberColumns_)*sizeof(double)); 00806 #endif 00807 // put back original costs and then check 00808 createRim(4); 00809 nonLinearCost_->checkInfeasibilities(oldTolerance); 00810 #if 0 00811 int i; 00812 for (i=0;i<numberRows_+numberColumns_;i++) { 00813 if (cost_[i]!=xcost[i]) 00814 printf("** %d old cost %g new %g sol %g\n", 00815 i,xcost[i],cost_[i],solution_[i]); 00816 if (lower_[i]!=xlower[i]) 00817 printf("** %d old lower %g new %g sol %g\n", 00818 i,xlower[i],lower_[i],solution_[i]); 00819 if (upper_[i]!=xupper[i]) 00820 printf("** %d old upper %g new %g sol %g\n", 00821 i,xupper[i],upper_[i],solution_[i]); 00822 if (dj_[i]!=xdj[i]) 00823 printf("** %d old dj %g new %g sol %g\n", 00824 i,xdj[i],dj_[i],solution_[i]); 00825 if (solution_[i]!=xsolution[i]) 00826 printf("** %d old solution %g new %g sol %g\n", 00827 i,xsolution[i],solution_[i],solution_[i]); 00828 } 00829 delete [] xcost; 00830 delete [] xupper; 00831 delete [] xlower; 00832 delete [] xdj; 00833 delete [] xsolution; 00834 #endif 00835 gutsOfSolution(NULL,NULL); 00836 if (sumOfRelaxedDualInfeasibilities_ == 0.0&& 00837 sumOfRelaxedPrimalInfeasibilities_ == 0.0) { 00838 // say optimal (with these bounds etc) 00839 numberDualInfeasibilities_ = 0; 00840 sumDualInfeasibilities_ = 0.0; 00841 numberPrimalInfeasibilities_ = 0; 00842 sumPrimalInfeasibilities_ = 0.0; 00843 } 00844 if (dualFeasible()&&!nonLinearCost_->numberInfeasibilities()&&lastCleaned>=0) 00845 problemStatus_=0; 00846 else 00847 problemStatus_ = -1; 00848 } else { 00849 problemStatus_=0; // optimal 00850 if (lastCleaned<numberIterations_) { 00851 handler_->message(CLP_SIMPLEX_GIVINGUP,messages_) 00852 <<CoinMessageEol; 00853 } 00854 } 00855 } else { 00856 problemStatus_=0; // optimal 00857 } 00858 } 00859 } else { 00860 // see if looks unbounded 00861 if (problemStatus_==-5) { 00862 if (nonLinearCost_->numberInfeasibilities()) { 00863 if (infeasibilityCost_>1.0e18&&perturbation_==101) { 00864 // back off weight 00865 infeasibilityCost_ = 1.0e13; 00866 goToDual=unPerturb(); // stop any further perturbation 00867 } 00868 //we need infeasiblity cost changed 00869 if (infeasibilityCost_<1.0e20) { 00870 infeasibilityCost_ *= 5.0; 00871 changeMade_++; // say change made 00872 handler_->message(CLP_PRIMAL_WEIGHT,messages_) 00873 <<infeasibilityCost_ 00874 <<CoinMessageEol; 00875 // put back original costs and then check 00876 createRim(4); 00877 gutsOfSolution(NULL,NULL); 00878 problemStatus_=-1; //continue 00879 } else { 00880 // say unbounded 00881 problemStatus_ = 2; 00882 } 00883 } else { 00884 // say unbounded 00885 problemStatus_ = 2; 00886 } 00887 } else { 00888 if(type==3&&problemStatus_!=-5) 00889 unflag(); // odd 00890 // carry on 00891 problemStatus_ = -1; 00892 } 00893 } 00894 if (type==0||type==1) { 00895 if (type!=1||!saveStatus_) { 00896 // create save arrays 00897 delete [] saveStatus_; 00898 delete [] savedSolution_; 00899 saveStatus_ = new unsigned char [numberRows_+numberColumns_]; 00900 savedSolution_ = new double [numberRows_+numberColumns_]; 00901 } 00902 // save arrays 00903 memcpy(saveStatus_,status_,(numberColumns_+numberRows_)*sizeof(char)); 00904 memcpy(savedSolution_+numberColumns_ ,rowActivityWork_, 00905 numberRows_*sizeof(double)); 00906 memcpy(savedSolution_ ,columnActivityWork_,numberColumns_*sizeof(double)); 00907 } 00908 if (doFactorization) { 00909 // restore weights (if saved) - also recompute infeasibility list 00910 if (tentativeStatus>-3) 00911 primalColumnPivot_->saveWeights(this,(type <2) ? 2 : 4); 00912 else 00913 primalColumnPivot_->saveWeights(this,3); 00914 if (saveThreshold) { 00915 // use default at present 00916 factorization_->sparseThreshold(0); 00917 factorization_->goSparse(); 00918 } 00919 } 00920 if (problemStatus_<0&&!changeMade_) { 00921 problemStatus_=4; // unknown 00922 } 00923 lastGoodIteration_ = numberIterations_; 00924 if (goToDual) 00925 problemStatus_=10; // try dual 00926 #if 0 00927 double thisObj = progress->lastObjective(0); 00928 double lastObj = progress->lastObjective(1); 00929 if (lastObj<thisObj-1.0e-7*max(fabs(thisObj),fabs(lastObj))-1.0e-8 00930 &&firstFree_<0) { 00931 int maxFactor = factorization_->maximumPivots(); 00932 if (maxFactor>10) { 00933 if (forceFactorization_<0) 00934 forceFactorization_= maxFactor; 00935 forceFactorization_ = max (1,(forceFactorization_>>1)); 00936 printf("Reducing factorization frequency\n"); 00937 } 00938 } 00939 #endif 00940 } |
|
The primals are updated by the given array. Returns number of infeasibilities. After rowArray will have cost changes for use next iteration Definition at line 1384 of file ClpSimplexPrimal.cpp. References CoinIndexedVector::add(), ClpNonLinearCost::changeInCost(), CoinIndexedVector::denseVector(), CoinIndexedVector::expand(), CoinIndexedVector::getIndices(), CoinIndexedVector::getNumElements(), CoinIndexedVector::scanAndPack(), ClpNonLinearCost::setChangeInCost(), CoinIndexedVector::setNumElements(), ClpNonLinearCost::setOne(), and CoinIndexedVector::setPacked(). Referenced by pivotResult(), and ClpSimplexPrimalQuadratic::whileIterating().
01388 { 01389 // Cost on pivot row may change - may need to change dualIn 01390 double oldCost=0.0; 01391 if (pivotRow_>=0) 01392 oldCost = cost_[sequenceOut_]; 01393 //rowArray->scanAndPack(); 01394 double * work=rowArray->denseVector(); 01395 int number=rowArray->getNumElements(); 01396 int * which=rowArray->getIndices(); 01397 01398 int newNumber = 0; 01399 int pivotPosition = -1; 01400 nonLinearCost_->setChangeInCost(0.0); 01401 int iIndex; 01402 if (!valuesPass) { 01403 for (iIndex=0;iIndex<number;iIndex++) { 01404 01405 int iRow = which[iIndex]; 01406 double alpha = work[iIndex]; 01407 work[iIndex]=0.0; 01408 int iPivot=pivotVariable_[iRow]; 01409 double change = theta*alpha; 01410 double value = solution_[iPivot] - change; 01411 solution_[iPivot]=value; 01412 #ifndef NDEBUG 01413 // check if not active then okay 01414 if (!active(iRow)) { 01415 // But make sure one going out is feasible 01416 if (change>0.0) { 01417 // going down 01418 if (value<lower_[iPivot]+primalTolerance_) { 01419 if (iPivot==sequenceOut_&&value>lower_[iPivot]-1.001*primalTolerance_) 01420 value=lower_[iPivot]; 01421 double difference = nonLinearCost_->setOne(iPivot,value); 01422 assert (!difference); 01423 } 01424 } else { 01425 // going up 01426 if (value>upper_[iPivot]-primalTolerance_) { 01427 if (iPivot==sequenceOut_&&value<upper_[iPivot]+1.001*primalTolerance_) 01428 value=upper_[iPivot]; 01429 double difference = nonLinearCost_->setOne(iPivot,value); 01430 assert (!difference); 01431 } 01432 } 01433 } 01434 #endif 01435 if (active(iRow)) { 01436 clearActive(iRow); 01437 // But make sure one going out is feasible 01438 if (change>0.0) { 01439 // going down 01440 if (value<lower_[iPivot]+primalTolerance_) { 01441 if (iPivot==sequenceOut_&&value>lower_[iPivot]-1.001*primalTolerance_) 01442 value=lower_[iPivot]; 01443 double difference = nonLinearCost_->setOne(iPivot,value); 01444 if (difference) { 01445 if (iRow==pivotRow_) 01446 pivotPosition=newNumber; 01447 work[newNumber] = difference; 01448 //change reduced cost on this 01449 dj_[iPivot] = -difference; 01450 which[newNumber++]=iRow; 01451 } 01452 } 01453 } else { 01454 // going up 01455 if (value>upper_[iPivot]-primalTolerance_) { 01456 if (iPivot==sequenceOut_&&value<upper_[iPivot]+1.001*primalTolerance_) 01457 value=upper_[iPivot]; 01458 double difference = nonLinearCost_->setOne(iPivot,value); 01459 if (difference) { 01460 if (iRow==pivotRow_) 01461 pivotPosition=newNumber; 01462 work[newNumber] = difference; 01463 //change reduced cost on this 01464 dj_[iPivot] = -difference; 01465 which[newNumber++]=iRow; 01466 } 01467 } 01468 } 01469 } 01470 } 01471 } else { 01472 // values pass so look at all 01473 for (iIndex=0;iIndex<number;iIndex++) { 01474 01475 int iRow = which[iIndex]; 01476 double alpha = work[iIndex]; 01477 work[iIndex]=0.0; 01478 int iPivot=pivotVariable_[iRow]; 01479 double change = theta*alpha; 01480 double value = solution_[iPivot] - change; 01481 solution_[iPivot]=value; 01482 clearActive(iRow); 01483 // But make sure one going out is feasible 01484 if (change>0.0) { 01485 // going down 01486 if (value<lower_[iPivot]+primalTolerance_) { 01487 if (iPivot==sequenceOut_&&value>lower_[iPivot]-1.001*primalTolerance_) 01488 value=lower_[iPivot]; 01489 double difference = nonLinearCost_->setOne(iPivot,value); 01490 if (difference) { 01491 if (iRow==pivotRow_) 01492 pivotPosition=newNumber; 01493 work[newNumber] = difference; 01494 //change reduced cost on this 01495 dj_[iPivot] = -difference; 01496 which[newNumber++]=iRow; 01497 } 01498 } 01499 } else { 01500 // going up 01501 if (value>upper_[iPivot]-primalTolerance_) { 01502 if (iPivot==sequenceOut_&&value<upper_[iPivot]+1.001*primalTolerance_) 01503 value=upper_[iPivot]; 01504 double difference = nonLinearCost_->setOne(iPivot,value); 01505 if (difference) { 01506 if (iRow==pivotRow_) 01507 pivotPosition=newNumber; 01508 work[newNumber] = difference; 01509 //change reduced cost on this 01510 dj_[iPivot] = -difference; 01511 which[newNumber++]=iRow; 01512 } 01513 } 01514 } 01515 } 01516 } 01517 objectiveChange += nonLinearCost_->changeInCost(); 01518 rowArray->setPacked(); 01519 #if 0 01520 rowArray->setNumElements(newNumber); 01521 rowArray->expand(); 01522 if (pivotRow_>=0) { 01523 dualIn_ += (oldCost-cost_[sequenceOut_]); 01524 // update change vector to include pivot 01525 rowArray->add(pivotRow_,-dualIn_); 01526 // and convert to packed 01527 rowArray->scanAndPack(); 01528 } else { 01529 // and convert to packed 01530 rowArray->scanAndPack(); 01531 } 01532 #else 01533 if (pivotRow_>=0) { 01534 dualIn_ += (oldCost-cost_[sequenceOut_]); 01535 // update change vector to include pivot 01536 if (pivotPosition>=0) { 01537 work[pivotPosition] -= dualIn_; 01538 } else { 01539 work[newNumber]=-dualIn_; 01540 which[newNumber++]=pivotRow_; 01541 } 01542 } 01543 rowArray->setNumElements(newNumber); 01544 #endif 01545 return 0; 01546 } |
|
This has the flow between re-factorizations Returns a code to say where decision to exit was made Problem status set to: -2 re-factorize -4 Looks optimal/infeasible -5 Looks unbounded +3 max iterations valuesOption has original value of valuesPass Definition at line 410 of file ClpSimplexPrimal.cpp. References CoinIndexedVector::checkClear(), CoinIndexedVector::clear(), ClpSimplex::createRim(), ClpSimplex::gutsOfSolution(), ClpSimplex::isColumn(), CoinMessageHandler::logLevel(), CoinMessageHandler::message(), nextSuperBasic(), ClpNonLinearCost::numberInfeasibilities(), pivotResult(), primalColumn(), ClpPrimalColumnPivot::saveWeights(), ClpSimplex::sequenceWithin(), CoinMessageHandler::setLogLevel(), and CoinIndexedVector::setNumElements(). Referenced by primal().
00411 { 00412 // Say if values pass 00413 int ifValuesPass=(firstFree_>=0) ? 1 : 0; 00414 int returnCode=-1; 00415 int superBasicType=1; 00416 if (valuesOption>1) 00417 superBasicType=3; 00418 // status stays at -1 while iterating, >=0 finished, -2 to invert 00419 // status -3 to go to top without an invert 00420 while (problemStatus_==-1) { 00421 //#define CLP_DEBUG 1 00422 #ifdef CLP_DEBUG 00423 { 00424 int i; 00425 // not [1] as has information 00426 for (i=0;i<4;i++) { 00427 if (i!=1) 00428 rowArray_[i]->checkClear(); 00429 } 00430 for (i=0;i<2;i++) { 00431 columnArray_[i]->checkClear(); 00432 } 00433 } 00434 #endif 00435 #if CLP_DEBUG>2 00436 // very expensive 00437 if (numberIterations_>0&&numberIterations_<-2534) { 00438 handler_->setLogLevel(63); 00439 double saveValue = objectiveValue_; 00440 double * saveRow1 = new double[numberRows_]; 00441 double * saveRow2 = new double[numberRows_]; 00442 memcpy(saveRow1,rowReducedCost_,numberRows_*sizeof(double)); 00443 memcpy(saveRow2,rowActivityWork_,numberRows_*sizeof(double)); 00444 double * saveColumn1 = new double[numberColumns_]; 00445 double * saveColumn2 = new double[numberColumns_]; 00446 memcpy(saveColumn1,reducedCostWork_,numberColumns_*sizeof(double)); 00447 memcpy(saveColumn2,columnActivityWork_,numberColumns_*sizeof(double)); 00448 createRim(7); 00449 gutsOfSolution(NULL,NULL); 00450 printf("xxx %d old obj %g, recomputed %g, sum primal inf %g\n", 00451 numberIterations_, 00452 saveValue,objectiveValue_,sumPrimalInfeasibilities_); 00453 memcpy(rowReducedCost_,saveRow1,numberRows_*sizeof(double)); 00454 memcpy(rowActivityWork_,saveRow2,numberRows_*sizeof(double)); 00455 memcpy(reducedCostWork_,saveColumn1,numberColumns_*sizeof(double)); 00456 memcpy(columnActivityWork_,saveColumn2,numberColumns_*sizeof(double)); 00457 delete [] saveRow1; 00458 delete [] saveRow2; 00459 delete [] saveColumn1; 00460 delete [] saveColumn2; 00461 objectiveValue_=saveValue; 00462 } 00463 #endif 00464 if (!ifValuesPass) { 00465 // choose column to come in 00466 // can use pivotRow_ to update weights 00467 // pass in list of cost changes so can do row updates (rowArray_[1]) 00468 // NOTE rowArray_[0] is used by computeDuals which is a 00469 // slow way of getting duals but might be used 00470 primalColumn(rowArray_[1],rowArray_[2],rowArray_[3], 00471 columnArray_[0],columnArray_[1]); 00472 } else { 00473 // in values pass 00474 int sequenceIn=nextSuperBasic(superBasicType,columnArray_[0]); 00475 if (valuesOption>1) 00476 superBasicType=2; 00477 if (sequenceIn<0) { 00478 // end of values pass - initialize weights etc 00479 handler_->message(CLP_END_VALUES_PASS,messages_) 00480 <<numberIterations_; 00481 primalColumnPivot_->saveWeights(this,5); 00482 problemStatus_=-2; // factorize now 00483 pivotRow_=-1; // say no weights update 00484 returnCode=-4; 00485 // Clean up 00486 int i; 00487 for (i=0;i<numberRows_+numberColumns_;i++) { 00488 if (getColumnStatus(i)==atLowerBound||getColumnStatus(i)==isFixed) 00489 solution_[i]=lower_[i]; 00490 else if (getColumnStatus(i)==atUpperBound) 00491 solution_[i]=upper_[i]; 00492 } 00493 break; 00494 } else { 00495 // normal 00496 sequenceIn_ = sequenceIn; 00497 valueIn_=solution_[sequenceIn_]; 00498 lowerIn_=lower_[sequenceIn_]; 00499 upperIn_=upper_[sequenceIn_]; 00500 dualIn_=dj_[sequenceIn_]; 00501 } 00502 } 00503 pivotRow_=-1; 00504 sequenceOut_=-1; 00505 rowArray_[1]->clear(); 00506 if (sequenceIn_>=0) { 00507 // we found a pivot column 00508 assert (!flagged(sequenceIn_)); 00509 #ifdef CLP_DEBUG 00510 if ((handler_->logLevel()&32)) { 00511 char x = isColumn(sequenceIn_) ? 'C' :'R'; 00512 std::cout<<"pivot column "<< 00513 x<<sequenceWithin(sequenceIn_)<<std::endl; 00514 } 00515 #endif 00516 // do second half of iteration 00517 returnCode = pivotResult(ifValuesPass); 00518 if (returnCode<-1&&returnCode>-5) { 00519 problemStatus_=-2; // 00520 } else if (returnCode==-5) { 00521 // something flagged - continue; 00522 } else if (returnCode==2) { 00523 problemStatus_=-5; // looks unbounded 00524 } else if (returnCode==4) { 00525 problemStatus_=-2; // looks unbounded but has iterated 00526 } else if (returnCode!=-1) { 00527 assert(returnCode==3); 00528 problemStatus_=3; 00529 } 00530 } else { 00531 // no pivot column 00532 #ifdef CLP_DEBUG 00533 if (handler_->logLevel()&32) 00534 printf("** no column pivot\n"); 00535 #endif 00536 if (nonLinearCost_->numberInfeasibilities()) 00537 problemStatus_=-4; // might be infeasible 00538 returnCode=0; 00539 break; 00540 } 00541 } 00542 if (valuesOption>1) 00543 columnArray_[0]->setNumElements(0); 00544 return returnCode; 00545 } |