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

ClpNonLinearCost Class Reference

#include <ClpNonLinearCost.hpp>

List of all members.

Public Member Functions

Constructors, destructor
 ClpNonLinearCost ()
 Default constructor.

 ClpNonLinearCost (ClpSimplex *model)
 ClpNonLinearCost (ClpSimplex *model, const int *starts, const double *lower, const double *cost)
 ~ClpNonLinearCost ()
 Destructor.

 ClpNonLinearCost (const ClpNonLinearCost &)
ClpNonLinearCostoperator= (const ClpNonLinearCost &)
Actual work in primal
void checkInfeasibilities (double oldTolerance=0.0)
void checkInfeasibilities (int numberInArray, const int *index)
void checkChanged (int numberInArray, CoinIndexedVector *update)
void goThru (int numberInArray, double multiplier, const int *index, const double *work, double *rhs)
void goBack (int numberInArray, const int *index, double *rhs)
void goBackAll (const CoinIndexedVector *update)
void zapCosts ()
 Temporary zeroing of feasible costs.

double setOne (int sequence, double solutionValue)
int setOneOutgoing (int sequence, double &solutionValue)
double nearest (int sequence, double solutionValue)
 Returns nearest bound.

double changeInCost (int sequence, double alpha) const
double changeUpInCost (int sequence) const
double changeDownInCost (int sequence) const
double changeInCost (int sequence, double alpha, double &rhs)
 This also updates next bound.

double lower (int sequence) const
 Returns current lower bound.

double upper (int sequence) const
 Returns current upper bound.

double cost (int sequence) const
 Returns current cost.

Gets and sets
int numberInfeasibilities () const
 Number of infeasibilities.

double changeInCost () const
 Change in cost.

double feasibleCost () const
 Feasible cost.

double feasibleReportCost () const
 Feasible cost with offset and direction (i.e. for reporting).

double sumInfeasibilities () const
 Sum of infeasibilities.

double largestInfeasibility () const
 Largest infeasibility.

double averageTheta () const
 Average theta.

void setAverageTheta (double value)
void setChangeInCost (double value)
bool lookBothWays () const
 See if may want to look both ways.

Private functions to deal with infeasible regions
bool infeasible (int i) const
void setInfeasible (int i, bool trueFalse)

Private Attributes

Data members
double changeCost_
 Change in cost because of infeasibilities.

double feasibleCost_
 Feasible cost.

double largestInfeasibility_
 Largest infeasibility.

double sumInfeasibilities_
 Sum of infeasibilities.

double averageTheta_
 Average theta - kept here as only for primal.

int numberRows_
 Number of rows (mainly for checking and copy).

int numberColumns_
 Number of columns (mainly for checking and copy).

int * start_
 Starts for each entry (columns then rows).

int * whichRange_
 Range for each entry (columns then rows).

int * offset_
 Temporary range offset for each entry (columns then rows).

double * lower_
double * cost_
 Cost for each range.

ClpSimplexmodel_
 Model.

unsigned int * infeasible_
int numberInfeasibilities_
 Number of infeasibilities found.

bool convex_
 If all non-linear costs convex.

bool bothWays_
 If we should look both ways for djs.


Detailed Description

Trivial class to deal with non linear costs

I don't make any explicit assumptions about convexity but I am sure I do make implicit ones.

One interesting idea for normal LP's will be to allow non-basic variables to come into basis as infeasible i.e. if variable at lower bound has very large positive reduced cost (when problem is infeasible) could it reduce overall problem infeasibility more by bringing it into basis below its lower bound.

Another feature would be to automatically discover when problems are convex piecewise linear and re-formulate to use non-linear. I did some work on this many years ago on "grade" problems, but while it improved primal interior point algorithms were much better for that particular problem.

Definition at line 30 of file ClpNonLinearCost.hpp.


Constructor & Destructor Documentation

ClpNonLinearCost::ClpNonLinearCost ClpSimplex model  ) 
 

Constructor from simplex. This will just set up wasteful arrays for linear, but later may do dual analysis and even finding duplicate columns .

Definition at line 45 of file ClpNonLinearCost.cpp.

References averageTheta_, bothWays_, changeCost_, convex_, cost(), cost_, ClpSimplex::costRegion(), feasibleCost_, ClpSimplex::infeasibilityCost(), largestInfeasibility_, lower(), lower_, ClpSimplex::lowerRegion(), model_, ClpModel::numberColumns(), numberColumns_, numberInfeasibilities_, ClpModel::numberRows(), numberRows_, offset_, start_, sumInfeasibilities_, upper(), ClpSimplex::upperRegion(), and whichRange_.

00046 {
00047   model_ = model;
00048   numberRows_ = model_->numberRows();
00049   numberColumns_ = model_->numberColumns();
00050   int numberTotal = numberRows_+numberColumns_;
00051   convex_ = true;
00052   bothWays_ = false;
00053   start_ = new int [numberTotal+1];
00054   whichRange_ = new int [numberTotal];
00055   offset_ = new int [numberTotal];
00056   memset(offset_,0,numberTotal*sizeof(int));
00057 
00058   numberInfeasibilities_=0;
00059   changeCost_=0.0;
00060   feasibleCost_=0.0;
00061   double infeasibilityCost = model_->infeasibilityCost();
00062   sumInfeasibilities_=0.0;
00063   averageTheta_=0.0;
00064   largestInfeasibility_=0.0;
00065 
00066   // First see how much space we need
00067   int put=0;
00068 
00069   int iSequence;
00070   double * upper = model_->upperRegion();
00071   double * lower = model_->lowerRegion();
00072   double * cost = model_->costRegion();
00073 
00074   // For quadratic we need -inf,0,0,+inf
00075   for (iSequence=0;iSequence<numberTotal;iSequence++) {
00076     if (lower[iSequence]>-1.0e20)
00077       put++;
00078     if (upper[iSequence]<1.0e20)
00079       put++;
00080     put += 2;
00081   }
00082 
00083   lower_ = new double [put];
00084   cost_ = new double [put];
00085   infeasible_ = new unsigned int[(put+31)>>5];
00086   memset(infeasible_,0,((put+31)>>5)*sizeof(unsigned int));
00087 
00088   put=0;
00089 
00090   start_[0]=0;
00091 
00092   for (iSequence=0;iSequence<numberTotal;iSequence++) {
00093 
00094     if (lower[iSequence]>-COIN_DBL_MAX) {
00095       lower_[put] = -COIN_DBL_MAX;
00096       setInfeasible(put,true);
00097       cost_[put++] = cost[iSequence]-infeasibilityCost;
00098     }
00099     whichRange_[iSequence]=put;
00100     lower_[put] = lower[iSequence];
00101     cost_[put++] = cost[iSequence];
00102     lower_[put] = upper[iSequence];
00103     cost_[put++] = cost[iSequence]+infeasibilityCost;
00104     if (upper[iSequence]<1.0e20) {
00105       lower_[put] = COIN_DBL_MAX;
00106       setInfeasible(put-1,true);
00107       cost_[put++] = 1.0e50;
00108     }
00109     start_[iSequence+1]=put;
00110   }
00111 }

ClpNonLinearCost::ClpNonLinearCost ClpSimplex model,
const int *  starts,
const double *  lower,
const double *  cost
 

Constructor from simplex and list of non-linearities (columns only) First lower of each column has to match real lower Last lower has to be <= upper (if == then cost ignored) This could obviously be changed to make more user friendly

Definition at line 112 of file ClpNonLinearCost.cpp.

References bothWays_, changeCost_, ClpModel::columnLower(), ClpModel::columnUpper(), convex_, cost(), cost_, feasibleCost_, ClpSimplex::infeasibilityCost(), largestInfeasibility_, lower_, model_, ClpModel::numberColumns(), numberColumns_, numberInfeasibilities_, ClpModel::numberRows(), numberRows_, ClpModel::objective(), offset_, ClpModel::optimizationDirection(), ClpModel::rowLower(), ClpModel::rowObjective(), ClpModel::rowUpper(), ClpSimplex::scalingFlag(), start_, sumInfeasibilities_, and whichRange_.

00114 {
00115 
00116   // what about scaling? - only try without it initially
00117   assert(!model->scalingFlag());
00118   model_ = model;
00119   numberRows_ = model_->numberRows();
00120   numberColumns_ = model_->numberColumns();
00121   int numberTotal = numberRows_+numberColumns_;
00122   convex_ = true;
00123   bothWays_ = true;
00124   start_ = new int [numberTotal+1];
00125   whichRange_ = new int [numberTotal];
00126   offset_ = new int [numberTotal];
00127   memset(offset_,0,numberTotal*sizeof(int));
00128   
00129   double whichWay = model_->optimizationDirection();
00130   printf("Direction %g\n",whichWay);
00131 
00132   numberInfeasibilities_=0;
00133   changeCost_=0.0;
00134   feasibleCost_=0.0;
00135   double infeasibilityCost = model_->infeasibilityCost();
00136   largestInfeasibility_=0.0;
00137   sumInfeasibilities_=0.0;
00138 
00139   int iSequence;
00140   assert (!model_->rowObjective());
00141   double * cost = model_->objective();
00142 
00143   // First see how much space we need 
00144   // Also set up feasible bounds
00145   int put=starts[numberColumns_];
00146 
00147   double * columnUpper = model_->columnUpper();
00148   double * columnLower = model_->columnLower();
00149   for (iSequence=0;iSequence<numberColumns_;iSequence++) {
00150     if (columnLower[iSequence]>-1.0e20)
00151       put++;
00152     if (columnUpper[iSequence]<1.0e20)
00153       put++;
00154   }
00155 
00156   double * rowUpper = model_->rowUpper();
00157   double * rowLower = model_->rowLower();
00158   for (iSequence=0;iSequence<numberRows_;iSequence++) {
00159     if (rowLower[iSequence]>-1.0e20)
00160       put++;
00161     if (rowUpper[iSequence]<1.0e20)
00162       put++;
00163     put +=2;
00164   }
00165   lower_ = new double [put];
00166   cost_ = new double [put];
00167   infeasible_ = new unsigned int[(put+31)>>5];
00168   memset(infeasible_,0,((put+31)>>5)*sizeof(unsigned int));
00169 
00170   // now fill in 
00171   put=0;
00172 
00173   start_[0]=0;
00174   for (iSequence=0;iSequence<numberTotal;iSequence++) {
00175     lower_[put] = -COIN_DBL_MAX;
00176     whichRange_[iSequence]=put+1;
00177     double thisCost;
00178     double lowerValue;
00179     double upperValue;
00180     if (iSequence>=numberColumns_) {
00181       // rows
00182       lowerValue = rowLower[iSequence-numberColumns_];
00183       upperValue = rowUpper[iSequence-numberColumns_];
00184       if (lowerValue>-1.0e30) {
00185         setInfeasible(put,true);
00186         cost_[put++] = -infeasibilityCost;
00187         lower_[put] = lowerValue;
00188       }
00189       cost_[put++] = 0.0;
00190       thisCost = 0.0;
00191     } else {
00192       // columns - move costs and see if convex
00193       lowerValue = columnLower[iSequence];
00194       upperValue = columnUpper[iSequence];
00195       if (lowerValue>-1.0e30) {
00196         setInfeasible(put,true);
00197         cost_[put++] = whichWay*cost[iSequence]-infeasibilityCost;
00198         lower_[put] = lowerValue;
00199       }
00200       int iIndex = starts[iSequence];
00201       int end = starts[iSequence+1];
00202       assert (fabs(columnLower[iSequence]-lowerNon[iIndex])<1.0e-8);
00203       thisCost = -COIN_DBL_MAX;
00204       for (;iIndex<end;iIndex++) {
00205         if (lowerNon[iIndex]<columnUpper[iSequence]-1.0e-8) {
00206           lower_[put] = lowerNon[iIndex];
00207           cost_[put++] = whichWay*costNon[iIndex];
00208           // check convexity
00209           if (whichWay*costNon[iIndex]<thisCost-1.0e-12)
00210             convex_ = false;
00211           thisCost = whichWay*costNon[iIndex];
00212         } else {
00213           break;
00214         }
00215       }
00216     }
00217     lower_[put] = upperValue;
00218     setInfeasible(put,true);
00219     cost_[put++] = thisCost+infeasibilityCost;
00220     if (upperValue<1.0e20) {
00221       lower_[put] = COIN_DBL_MAX;
00222       cost_[put++] = 1.0e50;
00223     }
00224     int iFirst = start_[iSequence];
00225     if (lower_[iFirst] != -COIN_DBL_MAX) {
00226       setInfeasible(iFirst,true);
00227       whichRange_[iSequence]=iFirst+1;
00228     } else {
00229       whichRange_[iSequence]=iFirst;
00230     }
00231     start_[iSequence+1]=put;
00232   }
00233   // can't handle non-convex at present
00234   assert(convex_);
00235 }


Member Function Documentation

double ClpNonLinearCost::changeInCost int  sequence,
double  alpha
const [inline]
 

Returns change in cost - one down if alpha >0.0, up if <0.0 Value is current - new

Definition at line 113 of file ClpNonLinearCost.hpp.

References cost_, offset_, and whichRange_.

Referenced by ClpSimplex::gutsOfSolution(), ClpSimplexPrimalQuadratic::primalRow(), ClpSimplexPrimal::primalRow(), and ClpSimplexPrimal::updatePrimalsInPrimal().

00114   {
00115     int iRange = whichRange_[sequence]+offset_[sequence];
00116     if (alpha>0.0)
00117       return cost_[iRange]-cost_[iRange-1];
00118     else
00119       return cost_[iRange]-cost_[iRange+1];
00120   }

void ClpNonLinearCost::checkChanged int  numberInArray,
CoinIndexedVector update
 

Puts back correct infeasible costs for each variable The input indices are row indices and need converting to sequences for costs. On input array is empty (but indices exist). On exit just changed costs will be stored as normal CoinIndexedVector

Definition at line 676 of file ClpNonLinearCost.cpp.

References cost(), cost_, ClpSimplex::costAddress(), ClpSimplex::currentPrimalTolerance(), CoinIndexedVector::denseVector(), CoinIndexedVector::getIndices(), ClpSimplex::getStatus(), lower(), lower_, ClpSimplex::lowerAddress(), model_, numberInfeasibilities_, ClpSimplex::pivotVariable(), CoinIndexedVector::setNumElements(), ClpSimplex::solution(), start_, upper(), ClpSimplex::upperAddress(), and whichRange_.

00677 {
00678   assert (model_!=NULL);
00679   double primalTolerance = model_->currentPrimalTolerance();
00680   const int * pivotVariable = model_->pivotVariable();
00681   int number=0;
00682   int * index = update->getIndices();
00683   double * work = update->denseVector();
00684   int i;
00685   for (i=0;i<numberInArray;i++) {
00686     int iRow = index[i];
00687     int iPivot = pivotVariable[iRow];
00688     // get where in bound sequence
00689     int iRange;
00690     double value = model_->solution(iPivot);
00691     int start = start_[iPivot];
00692     int end = start_[iPivot+1]-1;
00693     for (iRange=start; iRange<end;iRange++) {
00694       if (value<lower_[iRange+1]+primalTolerance) {
00695         // put in better range
00696         if (value>=lower_[iRange+1]-primalTolerance&&infeasible(iRange)&&iRange==start) 
00697           iRange++;
00698         break;
00699       }
00700     }
00701     assert(iRange<end);
00702     assert(model_->getStatus(iPivot)==ClpSimplex::basic);
00703     int jRange = whichRange_[iPivot];
00704     if (iRange!=jRange) {
00705       // changed
00706       work[iRow] = cost_[jRange]-cost_[iRange];
00707       index[number++]=iRow;
00708       double & lower = model_->lowerAddress(iPivot);
00709       double & upper = model_->upperAddress(iPivot);
00710       double & cost = model_->costAddress(iPivot);
00711       whichRange_[iPivot]=iRange;
00712       if (infeasible(iRange))
00713         numberInfeasibilities_++;
00714       if (infeasible(jRange))
00715         numberInfeasibilities_--;
00716       lower = lower_[iRange];
00717       upper = lower_[iRange+1];
00718       cost = cost_[iRange];
00719     }
00720   }
00721   update->setNumElements(number);
00722 }

void ClpNonLinearCost::checkInfeasibilities int  numberInArray,
const int *  index
 

Changes infeasible costs for each variable The indices are row indices and need converting to sequences

Definition at line 629 of file ClpNonLinearCost.cpp.

References cost(), cost_, ClpSimplex::costAddress(), ClpSimplex::currentPrimalTolerance(), ClpSimplex::getStatus(), lower(), lower_, ClpSimplex::lowerAddress(), model_, numberInfeasibilities_, ClpSimplex::pivotVariable(), ClpSimplex::solution(), start_, upper(), ClpSimplex::upperAddress(), and whichRange_.

00630 {
00631   assert (model_!=NULL);
00632   double primalTolerance = model_->currentPrimalTolerance();
00633   const int * pivotVariable = model_->pivotVariable();
00634   int i;
00635   for (i=0;i<numberInArray;i++) {
00636     int iRow = index[i];
00637     int iPivot = pivotVariable[iRow];
00638     // get where in bound sequence
00639     int iRange;
00640     int currentRange = whichRange_[iPivot];
00641     double value = model_->solution(iPivot);
00642     int start = start_[iPivot];
00643     int end = start_[iPivot+1]-1;
00644     for (iRange=start; iRange<end;iRange++) {
00645       if (value<lower_[iRange+1]+primalTolerance) {
00646         // put in better range
00647         if (value>=lower_[iRange+1]-primalTolerance&&infeasible(iRange)&&iRange==start) 
00648           iRange++;
00649         break;
00650       }
00651     }
00652     assert(iRange<end);
00653     assert(model_->getStatus(iPivot)==ClpSimplex::basic);
00654     double & lower = model_->lowerAddress(iPivot);
00655     double & upper = model_->upperAddress(iPivot);
00656     double & cost = model_->costAddress(iPivot);
00657     whichRange_[iPivot]=iRange;
00658     if (iRange!=currentRange) {
00659       if (infeasible(iRange))
00660         numberInfeasibilities_++;
00661       if (infeasible(currentRange))
00662         numberInfeasibilities_--;
00663     }
00664     lower = lower_[iRange];
00665     upper = lower_[iRange+1];
00666     cost = cost_[iRange];
00667   }
00668 }

void ClpNonLinearCost::checkInfeasibilities double  oldTolerance = 0.0  ) 
 

Changes infeasible costs and computes number and cost of infeas Puts all non-basic (non free) variables to bounds and all free variables to zero if oldTolerance is non-zero

  • but does not move those <= oldTolerance away

Definition at line 353 of file ClpNonLinearCost.cpp.

References changeCost_, cost(), cost_, ClpSimplex::costRegion(), ClpSimplex::currentPrimalTolerance(), feasibleCost_, ClpSimplex::getStatus(), ClpSimplex::infeasibilityCost(), largestInfeasibility_, lower(), lower_, ClpSimplex::lowerRegion(), model_, nearest(), numberColumns_, numberInfeasibilities_, numberRows_, ClpSimplex::setStatus(), ClpSimplex::solutionRegion(), start_, sumInfeasibilities_, upper(), ClpSimplex::upperRegion(), and whichRange_.

Referenced by ClpSimplex::ClpSimplex(), ClpSimplex::gutsOfSolution(), ClpSimplex::originalModel(), ClpSimplexPrimal::pivotResult(), ClpSimplexPrimal::primal(), ClpSimplexPrimalQuadratic::statusOfProblemInPrimal(), ClpSimplexPrimal::statusOfProblemInPrimal(), and ClpSimplexPrimal::unPerturb().

00354 {
00355   numberInfeasibilities_=0;
00356   double infeasibilityCost = model_->infeasibilityCost();
00357   changeCost_=0.0;
00358   largestInfeasibility_ = 0.0;
00359   sumInfeasibilities_ = 0.0;
00360   double primalTolerance = model_->currentPrimalTolerance();
00361   int iSequence;
00362   double * solution = model_->solutionRegion();
00363   double * upper = model_->upperRegion();
00364   double * lower = model_->lowerRegion();
00365   double * cost = model_->costRegion();
00366   bool toNearest = oldTolerance<=0.0;
00367   feasibleCost_=0.0;
00368     
00369   // nonbasic should be at a valid bound
00370   for (iSequence=0;iSequence<numberColumns_+numberRows_;iSequence++) {
00371     double lowerValue;
00372     double upperValue;
00373     double value=solution[iSequence];
00374     int iRange;
00375     // get correct place
00376     int start = start_[iSequence];
00377     int end = start_[iSequence+1]-1;
00378     // correct costs for this infeasibility weight
00379     // If free then true cost will be first
00380     double thisFeasibleCost=cost_[start];
00381     if (infeasible(start)) {
00382       thisFeasibleCost = cost_[start+1];
00383       cost_[start] = thisFeasibleCost-infeasibilityCost;
00384     }
00385     if (infeasible(end-1)) {
00386       thisFeasibleCost = cost_[end-2];
00387       cost_[end-1] = thisFeasibleCost+infeasibilityCost;
00388     }
00389     for (iRange=start; iRange<end;iRange++) {
00390       if (value<lower_[iRange+1]+primalTolerance) {
00391         // put in better range if infeasible
00392         if (value>=lower_[iRange+1]-primalTolerance&&infeasible(iRange)&&iRange==start) 
00393           iRange++;
00394         whichRange_[iSequence]=iRange;
00395         break;
00396       }
00397     }
00398     assert(iRange<end);
00399     lowerValue = lower_[iRange];
00400     upperValue = lower_[iRange+1];
00401     ClpSimplex::Status status = model_->getStatus(iSequence);
00402     if (upperValue==lowerValue) {
00403       if (status != ClpSimplex::basic) 
00404         model_->setStatus(iSequence,ClpSimplex::isFixed);
00405     }
00406     switch(status) {
00407       
00408     case ClpSimplex::basic:
00409     case ClpSimplex::superBasic:
00410       // iRange is in correct place
00411       // slot in here
00412       if (infeasible(iRange)) {
00413         if (lower_[iRange]<-1.0e50) {
00414           //cost_[iRange] = cost_[iRange+1]-infeasibilityCost;
00415           // possibly below
00416           lowerValue = lower_[iRange+1];
00417           if (value<lowerValue-primalTolerance) {
00418             value = lowerValue-value;
00419             sumInfeasibilities_ += value;
00420             largestInfeasibility_ = max(largestInfeasibility_,value);
00421             changeCost_ -= lowerValue*
00422               (cost_[iRange]-cost[iSequence]);
00423             numberInfeasibilities_++;
00424           }
00425         } else {
00426           //cost_[iRange] = cost_[iRange-1]+infeasibilityCost;
00427           // possibly above
00428           upperValue = lower_[iRange];
00429           if (value>upperValue+primalTolerance) {
00430             value = value-upperValue;
00431             sumInfeasibilities_ += value;
00432             largestInfeasibility_ = max(largestInfeasibility_,value);
00433             changeCost_ -= upperValue*
00434               (cost_[iRange]-cost[iSequence]);
00435             numberInfeasibilities_++;
00436           }
00437         }
00438       }
00439       //lower[iSequence] = lower_[iRange];
00440       //upper[iSequence] = lower_[iRange+1];
00441       //cost[iSequence] = cost_[iRange];
00442       break;
00443     case ClpSimplex::isFree:
00444       if (toNearest)
00445         solution[iSequence] = 0.0;
00446       break;
00447     case ClpSimplex::atUpperBound:
00448       if (!toNearest) {
00449         // With increasing tolerances - we may be at wrong place
00450         if (fabs(value-upperValue)>oldTolerance*1.0001) {
00451           if (fabs(value-lowerValue)<=oldTolerance*1.0001) {
00452             if  (fabs(value-lowerValue)>primalTolerance)
00453               solution[iSequence]=lowerValue;
00454             model_->setStatus(iSequence,ClpSimplex::atLowerBound);
00455           } else {
00456             model_->setStatus(iSequence,ClpSimplex::superBasic);
00457           }
00458         } else if  (fabs(value-upperValue)>primalTolerance) {
00459           solution[iSequence]=upperValue;
00460         }
00461       } else {
00462         // Set to nearest and make at upper bound
00463         int kRange;
00464         iRange=-1;
00465         double nearest = COIN_DBL_MAX;
00466         for (kRange=start; kRange<end;kRange++) {
00467           if (fabs(lower_[kRange]-value)<nearest) {
00468             nearest = fabs(lower_[kRange]-value);
00469             iRange=kRange;
00470           }
00471         }
00472         assert (iRange>=0);
00473         iRange--;
00474         solution[iSequence]=lower_[iRange+1];
00475       }
00476       break;
00477     case ClpSimplex::atLowerBound:
00478       if (!toNearest) {
00479         // With increasing tolerances - we may be at wrong place
00480         if (fabs(value-lowerValue)>oldTolerance*1.0001) {
00481           if (fabs(value-upperValue)<=oldTolerance*1.0001) {
00482             if  (fabs(value-upperValue)>primalTolerance)
00483               solution[iSequence]=upperValue;
00484             model_->setStatus(iSequence,ClpSimplex::atLowerBound);
00485           } else {
00486             model_->setStatus(iSequence,ClpSimplex::superBasic);
00487           }
00488         } else if  (fabs(value-lowerValue)>primalTolerance) {
00489           solution[iSequence]=lowerValue;
00490         }
00491       } else {
00492         // Set to nearest and make at lower bound
00493         int kRange;
00494         iRange=-1;
00495         double nearest = COIN_DBL_MAX;
00496         for (kRange=start; kRange<end;kRange++) {
00497           if (fabs(lower_[kRange]-value)<nearest) {
00498             nearest = fabs(lower_[kRange]-value);
00499             iRange=kRange;
00500           }
00501         }
00502         assert (iRange>=0);
00503         solution[iSequence]=lower_[iRange];
00504       }
00505       break;
00506     case ClpSimplex::isFixed:
00507       if (toNearest) {
00508         // Set to true fixed
00509         for (iRange=start; iRange<end;iRange++) {
00510           if (lower_[iRange]==lower_[iRange+1])
00511             break;
00512         }
00513         if (iRange==end) {
00514           // Odd - but make sensible
00515           // Set to nearest and make at lower bound
00516           int kRange;
00517           iRange=-1;
00518           double nearest = COIN_DBL_MAX;
00519           for (kRange=start; kRange<end;kRange++) {
00520             if (fabs(lower_[kRange]-value)<nearest) {
00521               nearest = fabs(lower_[kRange]-value);
00522               iRange=kRange;
00523             }
00524           }
00525           assert (iRange>=0);
00526           model_->setStatus(iSequence,ClpSimplex::atLowerBound);
00527         }
00528         solution[iSequence]=lower_[iRange];
00529       }
00530       break;
00531     }
00532     lower[iSequence] = lower_[iRange];
00533     upper[iSequence] = lower_[iRange+1];
00534     cost[iSequence] = cost_[iRange];
00535     feasibleCost_ += thisFeasibleCost*solution[iSequence];
00536   }
00537 }

void ClpNonLinearCost::goBack int  numberInArray,
const int *  index,
double *  rhs
 

Takes off last iteration (i.e. offsets closer to 0)

Definition at line 575 of file ClpNonLinearCost.cpp.

References lower_, model_, offset_, ClpSimplex::pivotVariable(), ClpSimplex::solution(), start_, and whichRange_.

Referenced by ClpSimplexPrimalQuadratic::primalRow().

00577 {
00578   assert (model_!=NULL);
00579   const int * pivotVariable = model_->pivotVariable();
00580   int i;
00581   for (i=0;i<numberInArray;i++) {
00582     int iRow = index[i];
00583     int iPivot = pivotVariable[iRow];
00584     // get where in bound sequence
00585     int iRange = whichRange_[iPivot];
00586     bool down;
00587     // get closer to original
00588     if (offset_[iPivot]>0) {
00589       offset_[iPivot]--;
00590       assert (offset_[iPivot]>=0);
00591       down = false;
00592     } else {
00593       offset_[iPivot]++;
00594       assert (offset_[iPivot]<=0);
00595       down = true;
00596     }
00597     iRange += offset_[iPivot]; //add temporary bias
00598     double value = model_->solution(iPivot);
00599     if (down) {
00600       // down one
00601       assert(iRange>=start_[iPivot]);
00602       rhs[iRow] = value - lower_[iRange];
00603     } else {
00604       // up one
00605       assert(iRange<start_[iPivot+1]-1);
00606       rhs[iRow] = lower_[iRange+1] - value;
00607     }
00608   }
00609 }

void ClpNonLinearCost::goBackAll const CoinIndexedVector update  ) 
 

Puts back correct infeasible costs for each variable The input indices are row indices and need converting to sequences for costs. At the end of this all temporary offsets are zero

Definition at line 611 of file ClpNonLinearCost.cpp.

References CoinIndexedVector::getIndices(), CoinIndexedVector::getNumElements(), model_, numberColumns_, numberRows_, offset_, and ClpSimplex::pivotVariable().

Referenced by ClpSimplexPrimalQuadratic::primalRow(), and ClpSimplexPrimal::primalRow().

00612 {
00613   assert (model_!=NULL);
00614   const int * pivotVariable = model_->pivotVariable();
00615   int i;
00616   int number = update->getNumElements();
00617   const int * index = update->getIndices();
00618   for (i=0;i<number;i++) {
00619     int iRow = index[i];
00620     int iPivot = pivotVariable[iRow];
00621     offset_[iPivot]=0;
00622   }
00623 #ifdef CLP_DEBUG
00624   for (i=0;i<numberRows_+numberColumns_;i++) 
00625     assert(!offset_[i]);
00626 #endif
00627 }

void ClpNonLinearCost::goThru int  numberInArray,
double  multiplier,
const int *  index,
const double *  work,
double *  rhs
 

Goes through one bound for each variable. If multiplier*work[iRow]>0 goes down, otherwise up. The indices are row indices and need converting to sequences Temporary offsets may be set Rhs entries are increased

Definition at line 543 of file ClpNonLinearCost.cpp.

References lower_, model_, offset_, ClpSimplex::pivotVariable(), ClpSimplex::solution(), start_, and whichRange_.

Referenced by ClpSimplexPrimalQuadratic::primalRow().

00546 {
00547   assert (model_!=NULL);
00548   const int * pivotVariable = model_->pivotVariable();
00549   int i;
00550   for (i=0;i<numberInArray;i++) {
00551     int iRow = index[i];
00552     int iPivot = pivotVariable[iRow];
00553     double alpha = multiplier*array[iRow];
00554     // get where in bound sequence
00555     int iRange = whichRange_[iPivot];
00556     iRange += offset_[iPivot]; //add temporary bias
00557     double value = model_->solution(iPivot);
00558     if (alpha>0.0) {
00559       // down one
00560       iRange--;
00561       assert(iRange>=start_[iPivot]);
00562       rhs[iRow] = value - lower_[iRange];
00563     } else {
00564       // up one
00565       iRange++;
00566       assert(iRange<start_[iPivot+1]-1);
00567       rhs[iRow] = lower_[iRange+1] - value;
00568     }
00569     offset_[iPivot] = iRange - whichRange_[iPivot];
00570   }
00571 }

double ClpNonLinearCost::setOne int  sequence,
double  solutionValue
 

Sets bounds and cost for one variable Returns change in cost May need to be inline for speed

Definition at line 725 of file ClpNonLinearCost.cpp.

References bothWays_, changeCost_, cost(), cost_, ClpSimplex::costAddress(), ClpSimplex::currentPrimalTolerance(), ClpSimplex::getStatus(), lower(), lower_, ClpSimplex::lowerAddress(), model_, numberInfeasibilities_, ClpSimplex::setStatus(), start_, upper(), ClpSimplex::upperAddress(), and whichRange_.

Referenced by ClpSimplexPrimal::pivotResult(), ClpSimplexPrimal::primalColumn(), ClpSimplexPrimal::updatePrimalsInPrimal(), and ClpSimplexPrimalQuadratic::whileIterating().

00726 {
00727   assert (model_!=NULL);
00728   double primalTolerance = model_->currentPrimalTolerance();
00729   // get where in bound sequence
00730   int iRange;
00731   int currentRange = whichRange_[iPivot];
00732   int start = start_[iPivot];
00733   int end = start_[iPivot+1]-1;
00734   if (!bothWays_) {
00735     // If fixed try and get feasible
00736     if (lower_[start+1]==lower_[start+2]&&fabs(value-lower_[start+1])<1.001*primalTolerance) {
00737       iRange =start+1;
00738     } else {
00739       for (iRange=start; iRange<end;iRange++) {
00740         if (value<=lower_[iRange+1]+primalTolerance) {
00741           // put in better range
00742           if (value>=lower_[iRange+1]-primalTolerance&&infeasible(iRange)&&iRange==start) 
00743             iRange++;
00744           break;
00745         }
00746       }
00747     }
00748   } else {
00749     // leave in current if possible
00750     iRange = whichRange_[iPivot];
00751     if (value<lower_[iRange]-primalTolerance||value>lower_[iRange+1]+primalTolerance) {
00752       for (iRange=start; iRange<end;iRange++) {
00753         if (value<lower_[iRange+1]+primalTolerance) {
00754           // put in better range
00755           if (value>=lower_[iRange+1]-primalTolerance&&infeasible(iRange)&&iRange==start) 
00756             iRange++;
00757           break;
00758         }
00759       }
00760     }
00761   }
00762   assert(iRange<end);
00763   whichRange_[iPivot]=iRange;
00764   if (iRange!=currentRange) {
00765     if (infeasible(iRange))
00766       numberInfeasibilities_++;
00767     if (infeasible(currentRange))
00768       numberInfeasibilities_--;
00769   }
00770   double & lower = model_->lowerAddress(iPivot);
00771   double & upper = model_->upperAddress(iPivot);
00772   double & cost = model_->costAddress(iPivot);
00773   lower = lower_[iRange];
00774   upper = lower_[iRange+1];
00775   ClpSimplex::Status status = model_->getStatus(iPivot);
00776   if (upper==lower) {
00777     if (status != ClpSimplex::basic) {
00778       model_->setStatus(iPivot,ClpSimplex::isFixed);
00779       status = ClpSimplex::basic; // so will skip
00780     }
00781   }
00782   switch(status) {
00783       
00784   case ClpSimplex::basic:
00785   case ClpSimplex::superBasic:
00786   case ClpSimplex::isFree:
00787     break;
00788   case ClpSimplex::atUpperBound:
00789   case ClpSimplex::atLowerBound:
00790   case ClpSimplex::isFixed:
00791     // set correctly
00792     if (fabs(value-lower)<=primalTolerance*1.001){
00793       model_->setStatus(iPivot,ClpSimplex::atLowerBound);
00794     } else if (fabs(value-upper)<=primalTolerance*1.001){
00795       model_->setStatus(iPivot,ClpSimplex::atUpperBound);
00796     } else {
00797       // set superBasic
00798       model_->setStatus(iPivot,ClpSimplex::superBasic);
00799     }
00800     break;
00801   }
00802   double difference = cost-cost_[iRange]; 
00803   cost = cost_[iRange];
00804   changeCost_ += value*difference;
00805   return difference;
00806 }

int ClpNonLinearCost::setOneOutgoing int  sequence,
double &  solutionValue
 

Sets bounds and cost for outgoing variable may change value Returns direction

Definition at line 811 of file ClpNonLinearCost.cpp.

References changeCost_, cost(), cost_, ClpSimplex::costAddress(), ClpSimplex::currentPrimalTolerance(), lower(), lower_, ClpSimplex::lowerAddress(), model_, numberInfeasibilities_, start_, upper(), ClpSimplex::upperAddress(), and whichRange_.

Referenced by ClpSimplexPrimal::pivotResult(), and ClpSimplexPrimalQuadratic::whileIterating().

00812 {
00813   assert (model_!=NULL);
00814   double primalTolerance = model_->currentPrimalTolerance();
00815   // get where in bound sequence
00816   int iRange;
00817   int currentRange = whichRange_[iPivot];
00818   int start = start_[iPivot];
00819   int end = start_[iPivot+1]-1;
00820   // Set perceived direction out
00821   int direction;
00822   if (value<=lower_[currentRange]+1.001*primalTolerance) {
00823     direction=1;
00824   } else if (value>=lower_[currentRange+1]-1.001*primalTolerance) {
00825     direction=-1;
00826   } else {
00827     // odd
00828     direction=0;
00829   }
00830   // If fixed try and get feasible
00831   if (lower_[start+1]==lower_[start+2]&&fabs(value-lower_[start+1])<1.001*primalTolerance) {
00832     iRange =start+1;
00833   } else {
00834     // See if exact
00835     for (iRange=start; iRange<end;iRange++) {
00836       if (value==lower_[iRange+1]) {
00837         // put in better range
00838         if (infeasible(iRange)&&iRange==start) 
00839           iRange++;
00840         break;
00841       }
00842     }
00843     if (iRange==end) {
00844       // not exact
00845       for (iRange=start; iRange<end;iRange++) {
00846         if (value<=lower_[iRange+1]+primalTolerance) {
00847           // put in better range
00848           if (value>=lower_[iRange+1]-primalTolerance&&infeasible(iRange)&&iRange==start) 
00849             iRange++;
00850           break;
00851         }
00852       }
00853     }
00854   }
00855   assert(iRange<end);
00856   whichRange_[iPivot]=iRange;
00857   if (iRange!=currentRange) {
00858     if (infeasible(iRange))
00859       numberInfeasibilities_++;
00860     if (infeasible(currentRange))
00861       numberInfeasibilities_--;
00862   }
00863   double & lower = model_->lowerAddress(iPivot);
00864   double & upper = model_->upperAddress(iPivot);
00865   double & cost = model_->costAddress(iPivot);
00866   lower = lower_[iRange];
00867   upper = lower_[iRange+1];
00868   if (upper==lower) {
00869     value=upper;
00870   } else {
00871     // set correctly
00872     if (fabs(value-lower)<=primalTolerance*1.001){
00873       value = min(value,lower+primalTolerance);
00874     } else if (fabs(value-upper)<=primalTolerance*1.001){
00875       value = max(value,upper-primalTolerance);
00876     } else {
00877       //printf("*** variable wandered off bound %g %g %g!\n",
00878       //     lower,value,upper);
00879       if (value-lower<=upper-value) 
00880         value = lower+primalTolerance;
00881       else 
00882         value = upper-primalTolerance;
00883     }
00884   }
00885   double difference = cost-cost_[iRange]; 
00886   cost = cost_[iRange];
00887   changeCost_ += value*difference;
00888   return direction;
00889 }


Member Data Documentation

double* ClpNonLinearCost::lower_ [private]
 

Lower bound for each range (upper bound is next lower). For various reasons there is always an infeasible range at bottom - even if lower bound is - infinity

Definition at line 235 of file ClpNonLinearCost.hpp.

Referenced by changeInCost(), checkChanged(), checkInfeasibilities(), ClpNonLinearCost(), goBack(), goThru(), lower(), nearest(), setOne(), setOneOutgoing(), upper(), and ~ClpNonLinearCost().


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