Main Page | Class Hierarchy | Alphabetical List | Class List | File List | Class Members

ClpPredictorCorrector Class Reference

#include <ClpPredictorCorrector.hpp>

Inheritance diagram for ClpPredictorCorrector:

ClpInterior ClpModel List of all members.

Public Member Functions

Description of algorithm
int solve ()
Functions used in algorithm
double findStepLength (const int phase)
 findStepLength.

double findDirectionVector (const int phase)
 findDirectionVector.

void createSolution ()
 createSolution. Creates solution from scratch

double complementarityGap (int &numberComplementarityPairs, const int phase)
 complementarityGap. Computes gap

void setupForSolve (const int phase)
 setupForSolve.

bool checkGoodMove (const bool doCorrector)
bool checkGoodMove2 (const double move)
 : checks for one step size

int updateSolution ()
 updateSolution. Updates solution at end of iteration

double affineProduct ()
 Save info on products of affine deltaT*deltaW and deltaS*deltaZ.


Detailed Description

This solves LPs using the predictor-corrector method.

It is rather basic as Interior point is not my speciality

It inherits from ClpInterior. It has no data of its own and is never created - only cast from a ClpInterior object at algorithm time.

Definition at line 24 of file ClpPredictorCorrector.hpp.


Member Function Documentation

int ClpPredictorCorrector::solve  ) 
 

Primal Dual Predictor Corrector algorithm

Method

Big TODO

Definition at line 38 of file ClpPredictorCorrector.cpp.

References affineProduct(), ClpInterior::checkSolution(), complementarityGap(), createSolution(), ClpInterior::createWorkingData(), ClpModel::dualTolerance(), ClpCholeskyBase::factorize(), findDirectionVector(), findStepLength(), CoinMessageHandler::message(), ClpModel::objectiveValue(), ClpCholeskyBase::order(), ClpModel::primalTolerance(), ClpCholeskyBase::rank(), ClpCholeskyBase::resetRowsDropped(), setupForSolve(), ClpCholeskyBase::status(), ClpMatrixBase::times(), ClpMatrixBase::transposeTimes(), and updateSolution().

00039 {
00040   problemStatus_=-1;
00041   algorithm_=1;
00042   //create all regions
00043   if (!createWorkingData()) {
00044     problemStatus_=4;
00045     return 2;
00046   }
00047   //initializeFeasible(); - this just set fixed flag
00048   smallestInfeasibility_=COIN_DBL_MAX;
00049   int i;
00050   for (i=0;i<LENGTH_HISTORY;i++) 
00051     historyInfeasibility_[i]=COIN_DBL_MAX;
00052 
00053   //bool firstTime=true;
00054   //firstFactorization(true);
00055   cholesky_->order(this);
00056   mu_=1.0e10;
00057   //set iterations
00058   numberIterations_=-1;
00059   //initialize solution here
00060   createSolution();
00061   //firstFactorization(false);
00062   CoinZeroN(dual_,numberRows_);
00063   multiplyAdd(solution_+numberColumns_,numberRows_,-1.0,errorRegion_,0.0);
00064   matrix_->times(1.0,solution_,errorRegion_);
00065   maximumRHSError_=maximumAbsElement(errorRegion_,numberRows_);
00066   maximumBoundInfeasibility_=maximumRHSError_;
00067   //double maximumDualError_=COIN_DBL_MAX;
00068   //initialize
00069   actualDualStep_=0.0;
00070   actualPrimalStep_=0.0;
00071   gonePrimalFeasible_=false;
00072   goneDualFeasible_=false;
00073   //bool hadGoodSolution=false;
00074   diagonalScaleFactor_=1.0;
00075   diagonalNorm_=solutionNorm_;
00076   mu_=solutionNorm_;
00077   int numberFixed=updateSolution();
00078   int numberFixedTotal=numberFixed;
00079   //int numberRows_DroppedBefore=0;
00080   //double extra=eExtra;
00081   //double maximumPerturbation=COIN_DBL_MAX;
00082   //constants for infeas interior point
00083   const double beta2 = 0.99995;
00084   const double tau   = 0.00002;
00085   double lastComplementarityGap=COIN_DBL_MAX;
00086   int lastGoodIteration=0;
00087   double bestObjectiveGap=COIN_DBL_MAX;
00088   int saveIteration=-1;
00089   bool sloppyOptimal=false;
00090   double * savePi=NULL;
00091   double * savePrimal=NULL;
00092   int numberTotal = numberRows_+numberColumns_;
00093   while (problemStatus_<0) {
00094     complementarityGap_=complementarityGap(numberComplementarityPairs_,0);
00095       handler_->message(CLP_BARRIER_ITERATION,messages_)
00096     <<numberIterations_
00097     <<primalObjective_*optimizationDirection_- dblParam_[ClpObjOffset]
00098     << dualObjective_*optimizationDirection_- dblParam_[ClpObjOffset]
00099     <<complementarityGap_
00100     <<numberFixedTotal
00101     <<cholesky_->rank()
00102     <<CoinMessageEol;
00103     double goodGapChange;
00104     if (!sloppyOptimal) {
00105       goodGapChange=0.93;
00106     } else {
00107       goodGapChange=0.7;
00108     } 
00109     double gapO;
00110     double lastGood=bestObjectiveGap;
00111     if (gonePrimalFeasible_&&goneDualFeasible_) {
00112       double largestObjective;
00113       if (fabs(primalObjective_)>fabs(dualObjective_)) {
00114         largestObjective = fabs(primalObjective_);
00115       } else {
00116         largestObjective = fabs(dualObjective_);
00117       } 
00118       if (largestObjective<1.0) {
00119         largestObjective=1.0;
00120       } 
00121       gapO=fabs(primalObjective_-dualObjective_)/largestObjective;
00122       handler_->message(CLP_BARRIER_OBJECTIVE_GAP,messages_)
00123         <<gapO
00124         <<CoinMessageEol;
00125       //start saving best
00126       if (gapO<bestObjectiveGap) {
00127         saveIteration=numberIterations_;
00128         bestObjectiveGap=gapO;
00129         if (!savePi) {
00130           savePi=new double[numberRows_];
00131           savePrimal = new double [numberTotal];
00132         } 
00133         CoinMemcpyN(dual_,numberRows_,savePi);
00134         CoinMemcpyN(solution_,numberTotal,savePrimal);
00135       } else if(gapO>2.0*bestObjectiveGap) {
00136         //maybe be more sophisticated e.g. re-initialize having
00137         //fixed variables and dropped rows
00138         //std::cout <<" gap increasing "<<std::endl;
00139       } 
00140       //std::cout <<"could stop"<<std::endl;
00141       //gapO=0.0;
00142       if (fabs(primalObjective_-dualObjective_)<dualTolerance()) {
00143         gapO=0.0;
00144       } 
00145     } else {
00146       gapO=COIN_DBL_MAX;
00147       if (saveIteration>=0) {
00148         handler_->message(CLP_BARRIER_GONE_INFEASIBLE,messages_)
00149           <<CoinMessageEol;
00150       } 
00151     } 
00152     if (gapO<1.0e-7&&!sloppyOptimal) {
00153       sloppyOptimal=true;
00154       handler_->message(CLP_BARRIER_CLOSE_TO_OPTIMAL,messages_)
00155         <<numberIterations_<<complementarityGap_
00156         <<CoinMessageEol;
00157     } 
00158     if (complementarityGap_>=1.05*lastComplementarityGap) {
00159       handler_->message(CLP_BARRIER_COMPLEMENTARITY,messages_)
00160         <<complementarityGap_<<"increasing"
00161         <<CoinMessageEol;
00162       if (saveIteration>=0&&sloppyOptimal) {
00163         handler_->message(CLP_BARRIER_EXIT2,messages_)
00164           <<saveIteration
00165           <<CoinMessageEol;
00166         break;
00167       } else {
00168         //lastComplementarityGap=complementarityGap_;
00169       } 
00170     } else if (complementarityGap_<goodGapChange*lastComplementarityGap) {
00171       lastGoodIteration=numberIterations_;
00172       lastComplementarityGap=complementarityGap_;
00173     } else if (numberIterations_-lastGoodIteration>=5&&complementarityGap_<1.0e-3) {
00174       handler_->message(CLP_BARRIER_COMPLEMENTARITY,messages_)
00175         <<complementarityGap_<<"not decreasing"
00176         <<CoinMessageEol;
00177       if (gapO>0.75*lastGood) {
00178         break;
00179       } 
00180     } 
00181     if (numberIterations_>maximumBarrierIterations_) {
00182       handler_->message(CLP_BARRIER_STOPPING,messages_)
00183         <<CoinMessageEol;
00184       break;
00185     } 
00186     if (gapO<targetGap_) {
00187       problemStatus_=0;
00188       handler_->message(CLP_BARRIER_EXIT,messages_)
00189         <<" "
00190         <<CoinMessageEol;
00191         break;//finished
00192     } 
00193     if (complementarityGap_<1.0e-18) {
00194       problemStatus_=0;
00195       handler_->message(CLP_BARRIER_EXIT,messages_)
00196         <<"- small complementarity gap"
00197         <<CoinMessageEol;
00198         break;//finished
00199     } 
00200     if (complementarityGap_<1.0e-10&&gapO<1.0e-10) {
00201       problemStatus_=0;
00202       handler_->message(CLP_BARRIER_EXIT,messages_)
00203         <<"- objective gap and complementarity gap both small"
00204         <<CoinMessageEol;
00205         break;//finished
00206     } 
00207     if (gapO<1.0e-9) {
00208       double value=gapO*complementarityGap_;
00209       value*=actualPrimalStep_;
00210       value*=actualDualStep_;
00211       //std::cout<<value<<std::endl;
00212       if (value<1.0e-17&&numberIterations_>lastGoodIteration) {
00213         problemStatus_=0;
00214         handler_->message(CLP_BARRIER_EXIT,messages_)
00215           <<"- objective gap and complementarity gap both smallish and small steps"
00216           <<CoinMessageEol;
00217         break;//finished
00218       } 
00219     } 
00220     bool useAffine=false;
00221     bool goodMove=false;
00222     bool doCorrector=true;
00223     //bool retry=false;
00224     worstDirectionAccuracy_=0.0;
00225     while (!goodMove) {
00226       goodMove=true;
00227       int newDropped=0;
00228       //Predictor step
00229       //Are we going to use the affine direction?
00230       if (!useAffine) {
00231         //no - normal
00232         //prepare for cholesky.  Set up scaled diagonal in weights
00233         //  ** for efficiency may be better if scale factor known before
00234         double norm2=0.0;
00235         double maximumValue;
00236         getNorms(diagonal_,numberColumns_,maximumValue,norm2);
00237         diagonalNorm_ = sqrt(norm2/numberComplementarityPairs_);
00238         diagonalScaleFactor_=1.0;
00239         double maximumAllowable=eScale;
00240         //scale so largest is less than allowable ? could do better
00241         double factor=0.5;
00242         while (maximumValue>maximumAllowable) {
00243           diagonalScaleFactor_*=factor;
00244           maximumValue*=factor;
00245         } /* endwhile */
00246         if (diagonalScaleFactor_!=1.0) {
00247           handler_->message(CLP_BARRIER_SCALING,messages_)
00248             <<"diagonal"<<diagonalScaleFactor_
00249             <<CoinMessageEol;
00250           diagonalNorm_*=diagonalScaleFactor_;
00251         } 
00252         multiplyAdd(NULL,numberTotal,0.0,diagonal_,
00253                       diagonalScaleFactor_);
00254         int * rowsDroppedThisTime = new int [numberRows_];
00255         newDropped=cholesky_->factorize(diagonal_,rowsDroppedThisTime);
00256         if (newDropped) {
00257           //int newDropped2=cholesky_->factorize(diagonal_,rowsDroppedThisTime);
00258           //assert(!newDropped2);
00259           if (newDropped<0) {
00260             //replace dropped
00261             newDropped=-newDropped;
00262             //off 1 to allow for reset all
00263             newDropped--;
00264             //set all bits false
00265             cholesky_->resetRowsDropped();
00266           } 
00267         } 
00268         delete [] rowsDroppedThisTime;
00269         if (cholesky_->status()) {
00270           std::cout << "bad cholesky?" <<std::endl;
00271           abort();
00272         } 
00273       } 
00274       //set up for affine direction
00275       setupForSolve(0);
00276       double directionAccuracy=findDirectionVector(0);
00277       if (directionAccuracy>worstDirectionAccuracy_) {
00278         worstDirectionAccuracy_=directionAccuracy;
00279       } 
00280       int phase=0; // predictor, corrector , primal dual
00281       // 0 - normal
00282       // 1 - second time around i.e. no need for first part
00283       // 2 - affine step only
00284       // 9 - to exit from while because of error (to go round again)
00285       // (9 also used to signal end of while (but then goodMove is true))
00286       int recoveryMode=0;
00287       if (!goodMove) {
00288         recoveryMode=9;
00289       } 
00290       if (goodMove&&useAffine) {
00291         recoveryMode=2;
00292         phase=0;
00293       } 
00294       while (recoveryMode!=9) {
00295         goodMove=true;
00296         if (!recoveryMode) {
00297           findStepLength(phase);
00298           int nextNumber; //number of complementarity pairs
00299           double nextGap=complementarityGap(nextNumber,1);
00300           //if (complementarityGap_>1.0e-1&&worstDirectionAccuracy_<1.0e-5) {
00301           //wasif (complementarityGap_>1.0e-2*numberComplementarityPairs_) {
00302           if (complementarityGap_>1.0e-4*numberComplementarityPairs_) {
00303             //std::cout <<"predicted duality gap "<<nextGap<<std::endl;
00304             //double part1=nextGap/numberComplementarityPairs_;
00305             double part1=nextGap/numberComplementarityPairs_;
00306             double part2=nextGap/complementarityGap_;
00307             mu_=part1*part2*part2;
00308           } else {
00309             double phi;
00310             if (numberComplementarityPairs_<=500) {
00311               phi=pow(numberComplementarityPairs_,2);
00312             } else {
00313               phi=pow(numberComplementarityPairs_,1.5);
00314               if (phi<500.0*500.0) {
00315                 phi=500.0*500.0;
00316               } 
00317             }
00318             mu_=complementarityGap_/phi;
00319             //? could use gapO?
00320             //if small then should be stopping
00321             //if (mu_<1.0e-4/(numberComplementarityPairs_*qqqq)) {
00322             //mu_=1.0e-4/(numberComplementarityPairs_*qqqq);
00323             //? better to skip corrector?
00324             //} 
00325           } 
00326           //save information
00327           double product=affineProduct();
00328           //can we do corrector step?
00329           double xx= complementarityGap_*(beta2-tau) +product;
00330           //std::cout<<"gap part "<<
00331           //complementarityGap_*(beta2-tau)<<" after adding product = "<<xx;
00332           if (xx>0.0) {
00333             double saveMu = mu_;
00334             double mu2=numberComplementarityPairs_;
00335             mu2=xx/mu2;
00336             if (mu2>mu_) {
00337               //std::cout<<" could increase to "<<mu2<<std::endl;
00338               //was mu2=mu2*0.25;
00339               mu2=mu2*0.99;
00340               if (mu2<mu_) {
00341                 mu_=mu2;
00342                 //std::cout<<" changing mu to "<<mu_<<std::endl;
00343               } else {
00344                 //std::cout<<std::endl;
00345               } 
00346             } else {
00347               //std::cout<<" should decrease to "<<mu2<<std::endl;
00348               mu_=0.5*mu2;
00349               std::cout<<" changing mu to "<<mu_<<std::endl;
00350             } 
00351             handler_->message(CLP_BARRIER_MU,messages_)
00352               <<saveMu<<mu_
00353               <<CoinMessageEol;
00354           } else {
00355             //std::cout<<" bad by any standards"<<std::endl;
00356           } 
00357           if (complementarityGap_*(beta2-tau)+product-mu_*numberComplementarityPairs_<0.0) {
00358             doCorrector=false;
00359             double floatNumber = numberComplementarityPairs_;
00360             mu_=complementarityGap_/(floatNumber*floatNumber);
00361             //? if small we should be stopping
00362             //if (mu_<1.0e-4/(numberComplementarityPairs_*numberComplementarityPairs_)) {
00363             //mu_=1.0e-4/(totalVariables*totalVariables);
00364             //} 
00365             handler_->message(CLP_BARRIER_INFO,messages_)
00366               <<"no corrector step"
00367               <<CoinMessageEol;
00368             phase=2;
00369           } else {
00370             phase=1;
00371           } 
00372         } 
00373         //set up for next step
00374         setupForSolve(phase);
00375         double directionAccuracy2=findDirectionVector(phase);
00376         if (directionAccuracy2>worstDirectionAccuracy_) {
00377           worstDirectionAccuracy_=directionAccuracy2;
00378         } 
00379         double testValue=1.0e2*directionAccuracy;
00380         if (1.0e2*projectionTolerance_>testValue) {
00381           testValue=1.0e2*projectionTolerance_;
00382         } 
00383         if (primalTolerance()>testValue) {
00384           testValue=primalTolerance();
00385         } 
00386         if (maximumRHSError_>testValue) {
00387           testValue=maximumRHSError_;
00388         } 
00389         if (!recoveryMode) {
00390           if (directionAccuracy2>testValue&&numberIterations_>=-77) {
00391             goodMove=false;
00392             useAffine=true;//if bad accuracy
00393             doCorrector=false;
00394             recoveryMode=9;
00395           } 
00396         } 
00397         if (goodMove) {
00398           findStepLength(phase);
00399           if (numberIterations_>=-77) {
00400             goodMove=checkGoodMove(doCorrector);
00401           } else {
00402             goodMove=true;
00403           } 
00404           if (!goodMove) {
00405             if (doCorrector) {
00406               doCorrector=false;
00407               double floatNumber = numberComplementarityPairs_;
00408               mu_=complementarityGap_/(floatNumber*floatNumber);
00409               handler_->message(CLP_BARRIER_INFO,messages_)
00410                 <<" no corrector step - original move would be bad"
00411                 <<CoinMessageEol;
00412               phase=2;
00413               recoveryMode=1;
00414             } else {
00415               // if any killed then do zero step and hope for best
00416               abort();
00417             } 
00418           } 
00419         } 
00420         //force leave
00421         if (goodMove) {
00422           recoveryMode=9;
00423         } 
00424       } /* endwhile */
00425     } /* endwhile */
00426     numberFixed=updateSolution();
00427     numberFixedTotal+=numberFixed;
00428   } /* endwhile */
00429   if (savePi) {
00430     //std::cout<<"Restoring from iteration "<<saveIteration<<std::endl;
00431     CoinMemcpyN(savePi,numberRows_,dual_);
00432     CoinMemcpyN(savePrimal,numberTotal,solution_);
00433     delete [] savePi;
00434     delete [] savePrimal;
00435   } 
00436   //recompute slacks
00437   // Split out solution
00438   CoinZeroN(rowActivity_,numberRows_);
00439   CoinMemcpyN(solution_,numberColumns_,columnActivity_);
00440   matrix_->times(1.0,columnActivity_,rowActivity_);
00441   //unscale objective
00442   multiplyAdd(NULL,numberTotal,0.0,cost_,scaleFactor_);
00443   multiplyAdd(NULL,numberRows_,0,dual_,scaleFactor_);
00444   CoinMemcpyN(cost_,numberColumns_,reducedCost_);
00445   matrix_->transposeTimes(-1.0,dual_,reducedCost_);
00446   CoinMemcpyN(reducedCost_,numberColumns_,dj_);
00447   checkSolution();
00448   handler_->message(CLP_BARRIER_END,messages_)
00449     <<sumPrimalInfeasibilities_
00450     <<sumDualInfeasibilities_
00451     <<complementarityGap_
00452     <<objectiveValue()
00453     <<CoinMessageEol;
00454   //std::cout<<"Absolute primal infeasibility at end "<<sumPrimalInfeasibilities_<<std::endl;
00455   //std::cout<<"Absolute dual infeasibility at end "<<sumDualInfeasibilities_<<std::endl;
00456   //std::cout<<"Absolute complementarity at end "<<complementarityGap_<<std::endl;
00457   //std::cout<<"Primal objective "<<objectiveValue()<<std::endl;
00458   //std::cout<<"maximum complementarity "<<worstComplementarity_<<std::endl;
00459   //delete all temporary regions
00460   deleteWorkingData();
00461   return problemStatus_;
00462 }


The documentation for this class was generated from the following files:
Generated on Wed Dec 3 14:37:42 2003 for CLP by doxygen 1.3.5