00001
00002
00003
00004 #include "CoinPragma.hpp"
00005 #include <iostream>
00006 #include <cassert>
00007
00008 #include "CoinIndexedVector.hpp"
00009
00010 #include "ClpNonLinearCost.hpp"
00011 #include "ClpSimplex.hpp"
00012
00013
00014
00015
00016
00017
00018
00019
00020 ClpNonLinearCost::ClpNonLinearCost () :
00021 changeCost_(0.0),
00022 feasibleCost_(0.0),
00023 largestInfeasibility_(0.0),
00024 sumInfeasibilities_(0.0),
00025 averageTheta_(0.0),
00026 numberRows_(0),
00027 numberColumns_(0),
00028 start_(NULL),
00029 whichRange_(NULL),
00030 offset_(NULL),
00031 lower_(NULL),
00032 cost_(NULL),
00033 model_(NULL),
00034 infeasible_(NULL),
00035 numberInfeasibilities_(-1),
00036 convex_(true),
00037 bothWays_(false)
00038 {
00039
00040 }
00041
00042
00043
00044
00045 ClpNonLinearCost::ClpNonLinearCost ( ClpSimplex * model)
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
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
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 }
00112 ClpNonLinearCost::ClpNonLinearCost(ClpSimplex * model,const int * starts,
00113 const double * lowerNon, const double * costNon)
00114 {
00115
00116
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
00144
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
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
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
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
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
00234 assert(convex_);
00235 }
00236
00237
00238
00239
00240 ClpNonLinearCost::ClpNonLinearCost (const ClpNonLinearCost & rhs) :
00241 changeCost_(0.0),
00242 feasibleCost_(0.0),
00243 largestInfeasibility_(0.0),
00244 sumInfeasibilities_(0.0),
00245 averageTheta_(0.0),
00246 numberRows_(rhs.numberRows_),
00247 numberColumns_(rhs.numberColumns_),
00248 start_(NULL),
00249 whichRange_(NULL),
00250 offset_(NULL),
00251 lower_(NULL),
00252 cost_(NULL),
00253 model_(NULL),
00254 infeasible_(NULL),
00255 numberInfeasibilities_(-1),
00256 convex_(true),
00257 bothWays_(rhs.bothWays_)
00258 {
00259 if (numberRows_) {
00260 int numberTotal = numberRows_+numberColumns_;
00261 start_ = new int [numberTotal+1];
00262 memcpy(start_,rhs.start_,(numberTotal+1)*sizeof(int));
00263 whichRange_ = new int [numberTotal];
00264 memcpy(whichRange_,rhs.whichRange_,numberTotal*sizeof(int));
00265 offset_ = new int [numberTotal];
00266 memcpy(offset_,rhs.offset_,numberTotal*sizeof(int));
00267 int numberEntries = start_[numberTotal];
00268 lower_ = new double [numberEntries];
00269 memcpy(lower_,rhs.lower_,numberEntries*sizeof(double));
00270 cost_ = new double [numberEntries];
00271 memcpy(cost_,rhs.cost_,numberEntries*sizeof(double));
00272 model_ = rhs.model_;
00273 numberInfeasibilities_=rhs.numberInfeasibilities_;
00274 changeCost_ = rhs.changeCost_;
00275 feasibleCost_ = rhs.feasibleCost_;
00276 largestInfeasibility_ = rhs.largestInfeasibility_;
00277 sumInfeasibilities_ = rhs.sumInfeasibilities_;
00278 averageTheta_ = rhs.averageTheta_;
00279 convex_ = rhs.convex_;
00280 infeasible_ = new unsigned int[(numberEntries+31)>>5];
00281 memcpy(infeasible_,rhs.infeasible_,
00282 ((numberEntries+31)>>5)*sizeof(unsigned int));
00283 }
00284 }
00285
00286
00287
00288
00289 ClpNonLinearCost::~ClpNonLinearCost ()
00290 {
00291 delete [] start_;
00292 delete [] whichRange_;
00293 delete [] offset_;
00294 delete [] lower_;
00295 delete [] cost_;
00296 delete [] infeasible_;
00297 }
00298
00299
00300
00301
00302 ClpNonLinearCost &
00303 ClpNonLinearCost::operator=(const ClpNonLinearCost& rhs)
00304 {
00305 if (this != &rhs) {
00306 numberRows_ = rhs.numberRows_;
00307 numberColumns_ = rhs.numberColumns_;
00308 delete [] start_;
00309 delete [] whichRange_;
00310 delete [] offset_;
00311 delete [] lower_;
00312 delete []cost_;
00313 delete [] infeasible_;
00314 start_ = NULL;
00315 whichRange_ = NULL;
00316 lower_ = NULL;
00317 cost_= NULL;
00318 infeasible_=NULL;
00319 if (numberRows_) {
00320 int numberTotal = numberRows_+numberColumns_;
00321 start_ = new int [numberTotal+1];
00322 memcpy(start_,rhs.start_,(numberTotal+1)*sizeof(int));
00323 whichRange_ = new int [numberTotal];
00324 memcpy(whichRange_,rhs.whichRange_,numberTotal*sizeof(int));
00325 offset_ = new int [numberTotal];
00326 memcpy(offset_,rhs.offset_,numberTotal*sizeof(int));
00327 int numberEntries = start_[numberTotal];
00328 lower_ = new double [numberEntries];
00329 memcpy(lower_,rhs.lower_,numberEntries*sizeof(double));
00330 cost_ = new double [numberEntries];
00331 memcpy(cost_,rhs.cost_,numberEntries*sizeof(double));
00332 infeasible_ = new unsigned int[(numberEntries+31)>>5];
00333 memcpy(infeasible_,rhs.infeasible_,
00334 ((numberEntries+31)>>5)*sizeof(unsigned int));
00335 }
00336 model_ = rhs.model_;
00337 numberInfeasibilities_=rhs.numberInfeasibilities_;
00338 changeCost_ = rhs.changeCost_;
00339 feasibleCost_ = rhs.feasibleCost_;
00340 largestInfeasibility_ = rhs.largestInfeasibility_;
00341 sumInfeasibilities_ = rhs.sumInfeasibilities_;
00342 averageTheta_ = rhs.averageTheta_;
00343 convex_ = rhs.convex_;
00344 bothWays_ = rhs.bothWays_;
00345 }
00346 return *this;
00347 }
00348
00349
00350
00351
00352 void
00353 ClpNonLinearCost::checkInfeasibilities(double oldTolerance)
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
00370 for (iSequence=0;iSequence<numberColumns_+numberRows_;iSequence++) {
00371 double lowerValue;
00372 double upperValue;
00373 double value=solution[iSequence];
00374 int iRange;
00375
00376 int start = start_[iSequence];
00377 int end = start_[iSequence+1]-1;
00378
00379
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
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
00411
00412 if (infeasible(iRange)) {
00413 if (lower_[iRange]<-1.0e50) {
00414
00415
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
00427
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
00440
00441
00442 break;
00443 case ClpSimplex::isFree:
00444 if (toNearest)
00445 solution[iSequence] = 0.0;
00446 break;
00447 case ClpSimplex::atUpperBound:
00448 if (!toNearest) {
00449
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
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
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
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
00509 for (iRange=start; iRange<end;iRange++) {
00510 if (lower_[iRange]==lower_[iRange+1])
00511 break;
00512 }
00513 if (iRange==end) {
00514
00515
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 }
00538
00539
00540
00541
00542 void
00543 ClpNonLinearCost::goThru(int numberInArray, double multiplier,
00544 const int * index, const double * array,
00545 double * rhs)
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
00555 int iRange = whichRange_[iPivot];
00556 iRange += offset_[iPivot];
00557 double value = model_->solution(iPivot);
00558 if (alpha>0.0) {
00559
00560 iRange--;
00561 assert(iRange>=start_[iPivot]);
00562 rhs[iRow] = value - lower_[iRange];
00563 } else {
00564
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 }
00572
00573
00574 void
00575 ClpNonLinearCost::goBack(int numberInArray, const int * index,
00576 double * rhs)
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
00585 int iRange = whichRange_[iPivot];
00586 bool down;
00587
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];
00598 double value = model_->solution(iPivot);
00599 if (down) {
00600
00601 assert(iRange>=start_[iPivot]);
00602 rhs[iRow] = value - lower_[iRange];
00603 } else {
00604
00605 assert(iRange<start_[iPivot+1]-1);
00606 rhs[iRow] = lower_[iRange+1] - value;
00607 }
00608 }
00609 }
00610 void
00611 ClpNonLinearCost::goBackAll(const CoinIndexedVector * update)
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 }
00628 void
00629 ClpNonLinearCost::checkInfeasibilities(int numberInArray, const int * index)
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
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
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 }
00669
00670
00671
00672
00673
00674
00675 void
00676 ClpNonLinearCost::checkChanged(int numberInArray, CoinIndexedVector * update)
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
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
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
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 }
00723
00724 double
00725 ClpNonLinearCost::setOne(int iPivot, double value)
00726 {
00727 assert (model_!=NULL);
00728 double primalTolerance = model_->currentPrimalTolerance();
00729
00730 int iRange;
00731 int currentRange = whichRange_[iPivot];
00732 int start = start_[iPivot];
00733 int end = start_[iPivot+1]-1;
00734 if (!bothWays_) {
00735
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
00742 if (value>=lower_[iRange+1]-primalTolerance&&infeasible(iRange)&&iRange==start)
00743 iRange++;
00744 break;
00745 }
00746 }
00747 }
00748 } else {
00749
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
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;
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
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
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 }
00807
00808
00809
00810 int
00811 ClpNonLinearCost::setOneOutgoing(int iPivot, double & value)
00812 {
00813 assert (model_!=NULL);
00814 double primalTolerance = model_->currentPrimalTolerance();
00815
00816 int iRange;
00817 int currentRange = whichRange_[iPivot];
00818 int start = start_[iPivot];
00819 int end = start_[iPivot+1]-1;
00820
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
00828 direction=0;
00829 }
00830
00831 if (lower_[start+1]==lower_[start+2]&&fabs(value-lower_[start+1])<1.001*primalTolerance) {
00832 iRange =start+1;
00833 } else {
00834
00835 for (iRange=start; iRange<end;iRange++) {
00836 if (value==lower_[iRange+1]) {
00837
00838 if (infeasible(iRange)&&iRange==start)
00839 iRange++;
00840 break;
00841 }
00842 }
00843 if (iRange==end) {
00844
00845 for (iRange=start; iRange<end;iRange++) {
00846 if (value<=lower_[iRange+1]+primalTolerance) {
00847
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
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
00878
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 }
00890
00891 double
00892 ClpNonLinearCost::nearest(int sequence, double solutionValue)
00893 {
00894 assert (model_!=NULL);
00895
00896 int iRange;
00897 int start = start_[sequence];
00898 int end = start_[sequence+1];
00899 int jRange=-1;
00900 double nearest=COIN_DBL_MAX;
00901 for (iRange=start; iRange<end;iRange++) {
00902 if (fabs(solutionValue-lower_[iRange])<nearest) {
00903 jRange=iRange;
00904 nearest=fabs(solutionValue-lower_[iRange]);
00905 }
00906 }
00907 assert(jRange<end);
00908 return lower_[jRange];
00909 }
00911 double
00912 ClpNonLinearCost::feasibleReportCost() const
00913 {
00914 double value;
00915 model_->getDblParam(ClpObjOffset,value);
00916 return feasibleCost_*model_->optimizationDirection()-value;
00917 }
00918
00919 void
00920 ClpNonLinearCost::zapCosts()
00921 {
00922 int iSequence;
00923 double infeasibilityCost = model_->infeasibilityCost();
00924
00925 int n = start_[numberColumns_+numberRows_];
00926 memset(cost_,0,n*sizeof(double));
00927 for (iSequence=0;iSequence<numberColumns_+numberRows_;iSequence++) {
00928 int start = start_[iSequence];
00929 int end = start_[iSequence+1]-1;
00930
00931 if (infeasible(start)) {
00932 cost_[start] = -infeasibilityCost;
00933 }
00934 if (infeasible(end-1)) {
00935 cost_[end-1] = infeasibilityCost;
00936 }
00937 }
00938 }