#include <ClpNonLinearCost.hpp>
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 &) | |
ClpNonLinearCost & | operator= (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. | |
ClpSimplex * | model_ |
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. |
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 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 } |
|
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 } |
|
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().
|
|
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 } |
|
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 } |
|
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
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 } |
|
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 } |
|
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 } |
|
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 } |
|
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 } |
|
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 } |
|
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(). |