00001
00002
00003
00004
00005
00006
00007 #include "CoinPragma.hpp"
00008
00009 #include <math.h>
00010
00011 #include "CoinHelperFunctions.hpp"
00012 #include "ClpSimplex.hpp"
00013 #include "ClpFactorization.hpp"
00014 #include "ClpPackedMatrix.hpp"
00015 #include "CoinIndexedVector.hpp"
00016 #include "ClpDualRowDantzig.hpp"
00017 #include "ClpDualRowSteepest.hpp"
00018 #include "ClpPrimalColumnDantzig.hpp"
00019 #include "ClpPrimalColumnSteepest.hpp"
00020 #include "ClpNonLinearCost.hpp"
00021 #include "ClpMessage.hpp"
00022 #include "ClpLinearObjective.hpp"
00023 #include <cfloat>
00024
00025 #include <string>
00026 #include <stdio.h>
00027 #include <iostream>
00028
00029
00030 ClpSimplex::ClpSimplex () :
00031
00032 ClpModel(),
00033 columnPrimalInfeasibility_(0.0),
00034 rowPrimalInfeasibility_(0.0),
00035 columnPrimalSequence_(-2),
00036 rowPrimalSequence_(-2),
00037 columnDualInfeasibility_(0.0),
00038 rowDualInfeasibility_(0.0),
00039 columnDualSequence_(-2),
00040 rowDualSequence_(-2),
00041 primalToleranceToGetOptimal_(-1.0),
00042 remainingDualInfeasibility_(0.0),
00043 largeValue_(1.0e15),
00044 largestPrimalError_(0.0),
00045 largestDualError_(0.0),
00046 largestSolutionError_(0.0),
00047 dualBound_(1.0e10),
00048 alpha_(0.0),
00049 theta_(0.0),
00050 lowerIn_(0.0),
00051 valueIn_(0.0),
00052 upperIn_(0.0),
00053 dualIn_(0.0),
00054 lowerOut_(-1),
00055 valueOut_(-1),
00056 upperOut_(-1),
00057 dualOut_(-1),
00058 dualTolerance_(0.0),
00059 primalTolerance_(0.0),
00060 sumDualInfeasibilities_(0.0),
00061 sumPrimalInfeasibilities_(0.0),
00062 infeasibilityCost_(1.0e10),
00063 sumOfRelaxedDualInfeasibilities_(0.0),
00064 sumOfRelaxedPrimalInfeasibilities_(0.0),
00065 lower_(NULL),
00066 rowLowerWork_(NULL),
00067 columnLowerWork_(NULL),
00068 upper_(NULL),
00069 rowUpperWork_(NULL),
00070 columnUpperWork_(NULL),
00071 cost_(NULL),
00072 rowObjectiveWork_(NULL),
00073 objectiveWork_(NULL),
00074 sequenceIn_(-1),
00075 directionIn_(-1),
00076 sequenceOut_(-1),
00077 directionOut_(-1),
00078 pivotRow_(-1),
00079 lastGoodIteration_(-100),
00080 dj_(NULL),
00081 rowReducedCost_(NULL),
00082 reducedCostWork_(NULL),
00083 solution_(NULL),
00084 rowActivityWork_(NULL),
00085 columnActivityWork_(NULL),
00086 numberDualInfeasibilities_(0),
00087 numberDualInfeasibilitiesWithoutFree_(0),
00088 numberPrimalInfeasibilities_(100),
00089 numberRefinements_(0),
00090 pivotVariable_(NULL),
00091 factorization_(NULL),
00092 rowScale_(NULL),
00093 savedSolution_(NULL),
00094 columnScale_(NULL),
00095 scalingFlag_(3),
00096 numberTimesOptimal_(0),
00097 changeMade_(1),
00098 algorithm_(0),
00099 forceFactorization_(-1),
00100 perturbation_(100),
00101 nonLinearCost_(NULL),
00102 specialOptions_(0),
00103 lastBadIteration_(-999999),
00104 numberFake_(0),
00105 progressFlag_(0),
00106 firstFree_(-1),
00107 incomingInfeasibility_(1.0),
00108 allowedInfeasibility_(10.0),
00109 progress_(NULL)
00110 {
00111 int i;
00112 for (i=0;i<6;i++) {
00113 rowArray_[i]=NULL;
00114 columnArray_[i]=NULL;
00115 }
00116 saveStatus_=NULL;
00117
00118 factorization_ = new ClpFactorization();
00119
00120 factorization_->sparseThreshold(1);
00121
00122 dualRowPivot_ = new ClpDualRowSteepest();
00123
00124 primalColumnPivot_ = new ClpPrimalColumnSteepest();
00125 solveType_=1;
00126
00127 }
00128
00129
00130 ClpSimplex::ClpSimplex ( const ClpModel * rhs,
00131 int numberRows, const int * whichRow,
00132 int numberColumns, const int * whichColumn,
00133 bool dropNames, bool dropIntegers)
00134 : ClpModel(rhs, numberRows, whichRow,
00135 numberColumns,whichColumn,dropNames,dropIntegers),
00136 columnPrimalInfeasibility_(0.0),
00137 rowPrimalInfeasibility_(0.0),
00138 columnPrimalSequence_(-2),
00139 rowPrimalSequence_(-2),
00140 columnDualInfeasibility_(0.0),
00141 rowDualInfeasibility_(0.0),
00142 columnDualSequence_(-2),
00143 rowDualSequence_(-2),
00144 primalToleranceToGetOptimal_(-1.0),
00145 remainingDualInfeasibility_(0.0),
00146 largeValue_(1.0e15),
00147 largestPrimalError_(0.0),
00148 largestDualError_(0.0),
00149 largestSolutionError_(0.0),
00150 dualBound_(1.0e10),
00151 alpha_(0.0),
00152 theta_(0.0),
00153 lowerIn_(0.0),
00154 valueIn_(0.0),
00155 upperIn_(0.0),
00156 dualIn_(0.0),
00157 lowerOut_(-1),
00158 valueOut_(-1),
00159 upperOut_(-1),
00160 dualOut_(-1),
00161 dualTolerance_(0.0),
00162 primalTolerance_(0.0),
00163 sumDualInfeasibilities_(0.0),
00164 sumPrimalInfeasibilities_(0.0),
00165 infeasibilityCost_(1.0e10),
00166 sumOfRelaxedDualInfeasibilities_(0.0),
00167 sumOfRelaxedPrimalInfeasibilities_(0.0),
00168 lower_(NULL),
00169 rowLowerWork_(NULL),
00170 columnLowerWork_(NULL),
00171 upper_(NULL),
00172 rowUpperWork_(NULL),
00173 columnUpperWork_(NULL),
00174 cost_(NULL),
00175 rowObjectiveWork_(NULL),
00176 objectiveWork_(NULL),
00177 sequenceIn_(-1),
00178 directionIn_(-1),
00179 sequenceOut_(-1),
00180 directionOut_(-1),
00181 pivotRow_(-1),
00182 lastGoodIteration_(-100),
00183 dj_(NULL),
00184 rowReducedCost_(NULL),
00185 reducedCostWork_(NULL),
00186 solution_(NULL),
00187 rowActivityWork_(NULL),
00188 columnActivityWork_(NULL),
00189 numberDualInfeasibilities_(0),
00190 numberDualInfeasibilitiesWithoutFree_(0),
00191 numberPrimalInfeasibilities_(100),
00192 numberRefinements_(0),
00193 pivotVariable_(NULL),
00194 factorization_(NULL),
00195 rowScale_(NULL),
00196 savedSolution_(NULL),
00197 columnScale_(NULL),
00198 scalingFlag_(3),
00199 numberTimesOptimal_(0),
00200 changeMade_(1),
00201 algorithm_(0),
00202 forceFactorization_(-1),
00203 perturbation_(100),
00204 nonLinearCost_(NULL),
00205 specialOptions_(0),
00206 lastBadIteration_(-999999),
00207 numberFake_(0),
00208 progressFlag_(0),
00209 firstFree_(-1),
00210 incomingInfeasibility_(1.0),
00211 allowedInfeasibility_(10.0),
00212 progress_(NULL)
00213 {
00214 int i;
00215 for (i=0;i<6;i++) {
00216 rowArray_[i]=NULL;
00217 columnArray_[i]=NULL;
00218 }
00219 saveStatus_=NULL;
00220
00221 factorization_ = new ClpFactorization();
00222
00223 dualRowPivot_ = new ClpDualRowSteepest();
00224
00225 primalColumnPivot_ = new ClpPrimalColumnSteepest();
00226 solveType_=1;
00227
00228 }
00229
00230
00231
00232 ClpSimplex::~ClpSimplex ()
00233 {
00234 gutsOfDelete(0);
00235 delete nonLinearCost_;
00236 }
00237
00238 void ClpSimplex::setLargeValue( double value)
00239 {
00240 if (value>0.0&&value<COIN_DBL_MAX)
00241 largeValue_=value;
00242 }
00243 int
00244 ClpSimplex::gutsOfSolution ( double * givenDuals,
00245 const double * givenPrimals,
00246 bool valuesPass)
00247 {
00248
00249
00250
00251 double * save = NULL;
00252 double oldValue=0.0;
00253 if (valuesPass) {
00254 assert(algorithm_>0);
00255 assert(nonLinearCost_);
00256 int iRow;
00257 checkPrimalSolution( rowActivityWork_, columnActivityWork_);
00258
00259 nonLinearCost_->checkInfeasibilities(primalTolerance_);
00260 oldValue = nonLinearCost_->largestInfeasibility();
00261 save = new double[numberRows_];
00262 for (iRow=0;iRow<numberRows_;iRow++) {
00263 int iPivot=pivotVariable_[iRow];
00264 save[iRow] = solution_[iPivot];
00265 }
00266 }
00267
00268 computePrimals(rowActivityWork_, columnActivityWork_);
00269
00270 if (givenPrimals) {
00271 memcpy(columnActivityWork_,givenPrimals,numberColumns_*sizeof(double));
00272 memset(rowActivityWork_,0,numberRows_*sizeof(double));
00273 times(-1.0,columnActivityWork_,rowActivityWork_);
00274 }
00275 double objectiveModification = 0.0;
00276 if (algorithm_>0&&nonLinearCost_!=NULL) {
00277
00278
00279
00280 if ((specialOptions_&4)==0)
00281 nonLinearCost_->checkInfeasibilities(primalTolerance_);
00282 else
00283 nonLinearCost_->checkInfeasibilities(0.0);
00284 objectiveModification += nonLinearCost_->changeInCost();
00285 if (nonLinearCost_->numberInfeasibilities())
00286 handler_->message(CLP_SIMPLEX_NONLINEAR,messages_)
00287 <<nonLinearCost_->changeInCost()
00288 <<nonLinearCost_->numberInfeasibilities()
00289 <<CoinMessageEol;
00290 }
00291 if (valuesPass) {
00292 #ifdef CLP_DEBUG
00293 std::cout<<"Largest given infeasibility "<<oldValue
00294 <<" now "<<nonLinearCost_->largestInfeasibility()<<std::endl;
00295 #endif
00296 int numberOut=0;
00297 if (oldValue<incomingInfeasibility_
00298 &&nonLinearCost_->largestInfeasibility()>
00299 max(incomingInfeasibility_,allowedInfeasibility_)||
00300 largestPrimalError_>1.0e-3) {
00301 printf("Original largest infeas %g, now %g, primalError %g\n",
00302 oldValue,nonLinearCost_->largestInfeasibility(),
00303 largestPrimalError_);
00304
00305 int iRow;
00306 int * sort = new int[numberRows_];
00307
00308 for (iRow=0;iRow<numberRows_;iRow++) {
00309 int iPivot=pivotVariable_[iRow];
00310 double difference = fabs(solution_[iPivot]-save[iRow]);
00311 solution_[iPivot]=save[iRow];
00312 save[iRow]=difference;
00313 }
00314 for (iRow=0;iRow<numberRows_;iRow++) {
00315 int iPivot=pivotVariable_[iRow];
00316
00317 if (iPivot<numberColumns_) {
00318
00319 double difference= save[iRow];
00320 if (difference>1.0e-4) {
00321 sort[numberOut]=iPivot;
00322 save[numberOut++]=difference;
00323 }
00324 }
00325 }
00326 CoinSort_2(save, save + numberOut, sort,
00327 CoinFirstGreater_2<double, int>());
00328 numberOut = min(1000,numberOut);
00329 for (iRow=0;iRow<numberOut;iRow++) {
00330 int iColumn=sort[iRow];
00331 setColumnStatus(iColumn,superBasic);
00332
00333 }
00334 delete [] sort;
00335 }
00336 delete [] save;
00337 if (numberOut)
00338 return numberOut;
00339 }
00340
00341 computeDuals(givenDuals);
00342
00343
00344 checkPrimalSolution( rowActivityWork_, columnActivityWork_);
00345 objectiveValue_ += objectiveModification;
00346 checkDualSolution();
00347 if (handler_->logLevel()>3||(largestPrimalError_>1.0e-2||
00348 largestDualError_>1.0e-2))
00349 handler_->message(CLP_SIMPLEX_ACCURACY,messages_)
00350 <<largestPrimalError_
00351 <<largestDualError_
00352 <<CoinMessageEol;
00353
00354 if (!valuesPass&&algorithm_>0)
00355 firstFree_ = -1;
00356 return 0;
00357 }
00358 void
00359 ClpSimplex::computePrimals ( const double * rowActivities,
00360 const double * columnActivities)
00361 {
00362
00363
00364 CoinIndexedVector * workSpace = rowArray_[0];
00365
00366 CoinIndexedVector arrayVector;
00367 arrayVector.reserve(numberRows_+1);
00368 CoinIndexedVector previousVector;
00369 previousVector.reserve(numberRows_+1);
00370
00371
00372
00373 int iRow;
00374
00375
00376
00377 if (columnActivities!=columnActivityWork_)
00378 ClpDisjointCopyN(columnActivities,numberColumns_,columnActivityWork_);
00379 if (rowActivities!=rowActivityWork_)
00380 ClpDisjointCopyN(rowActivities,numberRows_,rowActivityWork_);
00381 for (iRow=0;iRow<numberRows_;iRow++) {
00382 int iPivot=pivotVariable_[iRow];
00383 solution_[iPivot] = 0.0;
00384 }
00385 double * array = arrayVector.denseVector();
00386 times(-1.0,columnActivityWork_,array);
00387
00388 int * index = arrayVector.getIndices();
00389 int number=0;
00390 for (iRow=0;iRow<numberRows_;iRow++) {
00391 double value = array[iRow] + rowActivityWork_[iRow];
00392 if (value) {
00393 array[iRow]=value;
00394 index[number++]=iRow;
00395 } else {
00396 array[iRow]=0.0;
00397 }
00398 }
00399 arrayVector.setNumElements(number);
00400
00401
00402 double lastError=COIN_DBL_MAX;
00403 int iRefine;
00404 double * work = workSpace->denseVector();
00405 CoinIndexedVector * thisVector = &arrayVector;
00406 CoinIndexedVector * lastVector = &previousVector;
00407 factorization_->updateColumn(workSpace,thisVector);
00408 bool goodSolution=true;
00409 for (iRefine=0;iRefine<numberRefinements_+1;iRefine++) {
00410
00411 int numberIn = thisVector->getNumElements();
00412 int * indexIn = thisVector->getIndices();
00413 double * arrayIn = thisVector->denseVector();
00414
00415 int j;
00416 for (j=0;j<numberIn;j++) {
00417 iRow = indexIn[j];
00418 int iPivot=pivotVariable_[iRow];
00419 solution_[iPivot] = arrayIn[iRow];
00420 }
00421
00422 times(-1.0,columnActivityWork_,work);
00423 largestPrimalError_=0.0;
00424 double multiplier = 131072.0;
00425 for (iRow=0;iRow<numberRows_;iRow++) {
00426 double value = work[iRow] + rowActivityWork_[iRow];
00427 work[iRow] = value*multiplier;
00428 if (fabs(value)>largestPrimalError_) {
00429 largestPrimalError_=fabs(value);
00430 }
00431 }
00432 if (largestPrimalError_>=lastError) {
00433
00434 CoinIndexedVector * temp = thisVector;
00435 thisVector = lastVector;
00436 lastVector=temp;
00437 goodSolution=false;
00438 break;
00439 }
00440 if (iRefine<numberRefinements_&&largestPrimalError_>1.0e-10) {
00441
00442
00443 CoinIndexedVector * temp = thisVector;
00444 thisVector = lastVector;
00445 lastVector=temp;
00446 int * indexOut = thisVector->getIndices();
00447 int number=0;
00448 array = thisVector->denseVector();
00449 thisVector->clear();
00450 for (iRow=0;iRow<numberRows_;iRow++) {
00451 double value = work[iRow];
00452 if (value) {
00453 array[iRow]=value;
00454 indexOut[number++]=iRow;
00455 work[iRow]=0.0;
00456 }
00457 }
00458 thisVector->setNumElements(number);
00459 lastError=largestPrimalError_;
00460 factorization_->updateColumn(workSpace,thisVector);
00461 multiplier = 1.0/multiplier;
00462 double * previous = lastVector->denseVector();
00463 number=0;
00464 for (iRow=0;iRow<numberRows_;iRow++) {
00465 double value = previous[iRow] + multiplier*array[iRow];
00466 if (value) {
00467 array[iRow]=value;
00468 indexOut[number++]=iRow;
00469 } else {
00470 array[iRow]=0.0;
00471 }
00472 }
00473 thisVector->setNumElements(number);
00474 } else {
00475 break;
00476 }
00477 }
00478
00479
00480 ClpFillN(work,numberRows_,0.0);
00481 if (!goodSolution) {
00482 array = thisVector->denseVector();
00483
00484 for (iRow=0;iRow<numberRows_;iRow++) {
00485 int iPivot=pivotVariable_[iRow];
00486 solution_[iPivot] = array[iRow];
00487 }
00488 }
00489 }
00490
00491 void
00492 ClpSimplex::computeDuals(double * givenDjs)
00493 {
00494
00495 CoinIndexedVector * workSpace = rowArray_[0];
00496
00497 CoinIndexedVector arrayVector;
00498 arrayVector.reserve(numberRows_+1);
00499 CoinIndexedVector previousVector;
00500 previousVector.reserve(numberRows_+1);
00501
00502
00503 int iRow;
00504 #ifdef CLP_DEBUG
00505 workSpace->checkClear();
00506 #endif
00507 double * array = arrayVector.denseVector();
00508 int * index = arrayVector.getIndices();
00509 int number=0;
00510 if (!givenDjs) {
00511 for (iRow=0;iRow<numberRows_;iRow++) {
00512 int iPivot=pivotVariable_[iRow];
00513 double value = cost_[iPivot];
00514 if (value) {
00515 array[iRow]=value;
00516 index[number++]=iRow;
00517 }
00518 }
00519 } else {
00520
00521 for (iRow=0;iRow<numberRows_;iRow++) {
00522 int iPivot=pivotVariable_[iRow];
00523
00524 if (!pivoted(iPivot))
00525 givenDjs[iPivot]=0.0;
00526 double value =cost_[iPivot]-givenDjs[iPivot];
00527 if (value) {
00528 array[iRow]=value;
00529 index[number++]=iRow;
00530 }
00531 }
00532 }
00533 arrayVector.setNumElements(number);
00534
00535
00536 double lastError=COIN_DBL_MAX;
00537 int iRefine;
00538 double * work = workSpace->denseVector();
00539 CoinIndexedVector * thisVector = &arrayVector;
00540 CoinIndexedVector * lastVector = &previousVector;
00541 factorization_->updateColumnTranspose(workSpace,thisVector);
00542
00543 for (iRefine=0;iRefine<numberRefinements_+1;iRefine++) {
00544
00545 largestDualError_=0.0;
00546
00547 ClpDisjointCopyN(objectiveWork_,numberColumns_,reducedCostWork_);
00548 transposeTimes(-1.0,array,reducedCostWork_);
00549 if (!givenDjs) {
00550 for (iRow=0;iRow<numberRows_;iRow++) {
00551 int iPivot=pivotVariable_[iRow];
00552 double value;
00553 if (iPivot>=numberColumns_) {
00554
00555 value = rowObjectiveWork_[iPivot-numberColumns_]
00556 + array[iPivot-numberColumns_];
00557 } else {
00558
00559 value = reducedCostWork_[iPivot];
00560 }
00561 work[iRow]=value;
00562 if (fabs(value)>largestDualError_) {
00563 largestDualError_=fabs(value);
00564 }
00565 }
00566 } else {
00567 for (iRow=0;iRow<numberRows_;iRow++) {
00568 int iPivot=pivotVariable_[iRow];
00569 if (iPivot>=numberColumns_) {
00570
00571 work[iRow] = rowObjectiveWork_[iPivot-numberColumns_]
00572 + array[iPivot-numberColumns_]-givenDjs[iPivot];
00573 } else {
00574
00575 work[iRow] = reducedCostWork_[iPivot]- givenDjs[iPivot];
00576 }
00577 if (fabs(work[iRow])>largestDualError_) {
00578 largestDualError_=fabs(work[iRow]);
00579
00580
00581
00582 }
00583 }
00584 }
00585 if (largestDualError_>=lastError) {
00586
00587 CoinIndexedVector * temp = thisVector;
00588 thisVector = lastVector;
00589 lastVector=temp;
00590 break;
00591 }
00592 if (iRefine<numberRefinements_&&largestDualError_>1.0e-10
00593 &&!givenDjs) {
00594
00595
00596 CoinIndexedVector * temp = thisVector;
00597 thisVector = lastVector;
00598 lastVector=temp;
00599 int * indexOut = thisVector->getIndices();
00600 int number=0;
00601 array = thisVector->denseVector();
00602 thisVector->clear();
00603 double multiplier = 131072.0;
00604 for (iRow=0;iRow<numberRows_;iRow++) {
00605 double value = multiplier*work[iRow];
00606 if (value) {
00607 array[iRow]=value;
00608 indexOut[number++]=iRow;
00609 work[iRow]=0.0;
00610 }
00611 work[iRow]=0.0;
00612 }
00613 thisVector->setNumElements(number);
00614 lastError=largestDualError_;
00615 factorization_->updateColumnTranspose(workSpace,thisVector);
00616 multiplier = 1.0/multiplier;
00617 double * previous = lastVector->denseVector();
00618 number=0;
00619 for (iRow=0;iRow<numberRows_;iRow++) {
00620 double value = previous[iRow] + multiplier*array[iRow];
00621 if (value) {
00622 array[iRow]=value;
00623 indexOut[number++]=iRow;
00624 } else {
00625 array[iRow]=0.0;
00626 }
00627 }
00628 thisVector->setNumElements(number);
00629 } else {
00630 break;
00631 }
00632 }
00633 ClpFillN(work,numberRows_,0.0);
00634
00635 array = thisVector->denseVector();
00636 for (iRow=0;iRow<numberRows_;iRow++) {
00637
00638 double value = array[iRow];
00639 dual_[iRow]=value;
00640 value += rowObjectiveWork_[iRow];
00641 rowReducedCost_[iRow]=value;
00642 }
00643 ClpDisjointCopyN(objectiveWork_,numberColumns_,reducedCostWork_);
00644 transposeTimes(-1.0,dual_,reducedCostWork_);
00645
00646 if (givenDjs) {
00647
00648 memcpy(givenDjs,dj_,(numberRows_+numberColumns_)*sizeof(double));
00649 }
00650
00651 }
00652
00653
00654
00655 int ClpSimplex::getSolution ( const double * rowActivities,
00656 const double * columnActivities)
00657 {
00658 if (!factorization_->status()) {
00659
00660 createRim(7+8+16+32);
00661
00662 gutsOfSolution ( NULL,NULL);
00663
00664 deleteRim(0);
00665 }
00666 return factorization_->status();
00667 }
00668
00669
00670
00671 int ClpSimplex::getSolution ( )
00672 {
00673 double * rowActivities = new double[numberRows_];
00674 double * columnActivities = new double[numberColumns_];
00675 ClpDisjointCopyN ( rowActivityWork_, numberRows_ , rowActivities);
00676 ClpDisjointCopyN ( columnActivityWork_, numberColumns_ , columnActivities);
00677 int status = getSolution( rowActivities, columnActivities);
00678 delete [] rowActivities;
00679 delete [] columnActivities;
00680 return status;
00681 }
00682
00683
00684 int ClpSimplex::factorize ()
00685 {
00686
00687 createRim(7+8+16+32,false);
00688
00689 int status = internalFactorize(-1);
00690
00691 deleteRim(0);
00692
00693 return status;
00694 }
00695
00696 void
00697 ClpSimplex::cleanStatus()
00698 {
00699 int iRow,iColumn;
00700 int numberBasic=0;
00701
00702 memset(rowActivityWork_,0,numberRows_*sizeof(double));
00703 times(1.0,columnActivityWork_,rowActivityWork_);
00704 if (!status_)
00705 createStatus();
00706 for (iRow=0;iRow<numberRows_;iRow++) {
00707 if (getRowStatus(iRow)==basic)
00708 numberBasic++;
00709 else {
00710 setRowStatus(iRow,superBasic);
00711
00712 if (fabs(rowActivityWork_[iRow]-rowLowerWork_[iRow])
00713 <=primalTolerance_) {
00714 rowActivityWork_[iRow]=rowLowerWork_[iRow];
00715 setRowStatus(iRow,atLowerBound);
00716 } else if (fabs(rowActivityWork_[iRow]-rowUpperWork_[iRow])
00717 <=primalTolerance_) {
00718 rowActivityWork_[iRow]=rowUpperWork_[iRow];
00719 setRowStatus(iRow,atUpperBound);
00720 }
00721 }
00722 }
00723 for (iColumn=0;iColumn<numberColumns_;iColumn++) {
00724 if (getColumnStatus(iColumn)==basic) {
00725 if (numberBasic==numberRows_) {
00726
00727 setColumnStatus(iColumn,superBasic);
00728
00729 if (fabs(columnActivityWork_[iColumn]-columnLowerWork_[iColumn])
00730 <=primalTolerance_) {
00731 columnActivityWork_[iColumn]=columnLowerWork_[iColumn];
00732 setColumnStatus(iColumn,atLowerBound);
00733 } else if (fabs(columnActivityWork_[iColumn]
00734 -columnUpperWork_[iColumn])
00735 <=primalTolerance_) {
00736 columnActivityWork_[iColumn]=columnUpperWork_[iColumn];
00737 setColumnStatus(iColumn,atUpperBound);
00738 }
00739 } else
00740 numberBasic++;
00741 } else {
00742 setColumnStatus(iColumn,superBasic);
00743
00744 if (fabs(columnActivityWork_[iColumn]-columnLowerWork_[iColumn])
00745 <=primalTolerance_) {
00746 columnActivityWork_[iColumn]=columnLowerWork_[iColumn];
00747 setColumnStatus(iColumn,atLowerBound);
00748 } else if (fabs(columnActivityWork_[iColumn]
00749 -columnUpperWork_[iColumn])
00750 <=primalTolerance_) {
00751 columnActivityWork_[iColumn]=columnUpperWork_[iColumn];
00752 setColumnStatus(iColumn,atUpperBound);
00753 }
00754 }
00755 }
00756 }
00757
00758
00759
00760
00761
00762
00763
00764
00765 int ClpSimplex::internalFactorize ( int solveType)
00766 {
00767
00768 int iRow,iColumn;
00769 int totalSlacks=numberRows_;
00770 if (!status_)
00771 createStatus();
00772
00773 bool valuesPass=false;
00774 if (solveType>=10) {
00775 valuesPass=true;
00776 solveType -= 10;
00777 }
00778 #ifdef CLP_DEBUG
00779 if (solveType>0) {
00780 int numberFreeIn=0,numberFreeOut=0;
00781 double biggestDj=0.0;
00782 for (iColumn=0;iColumn<numberColumns_;iColumn++) {
00783 switch(getColumnStatus(iColumn)) {
00784
00785 case basic:
00786 if (columnLower_[iColumn]<-largeValue_
00787 &&columnUpper_[iColumn]>largeValue_)
00788 numberFreeIn++;
00789 break;
00790 default:
00791 if (columnLower_[iColumn]<-largeValue_
00792 &&columnUpper_[iColumn]>largeValue_) {
00793 numberFreeOut++;
00794 biggestDj = max(fabs(dj_[iColumn]),biggestDj);
00795 }
00796 break;
00797 }
00798 }
00799 if (numberFreeIn+numberFreeOut)
00800 printf("%d in basis, %d out - largest dj %g\n",
00801 numberFreeIn,numberFreeOut,biggestDj);
00802 }
00803 #endif
00804 if (solveType<=0) {
00805
00806 for (iRow=0;iRow<numberRows_;iRow++) {
00807 if(getRowStatus(iRow)==isFixed) {
00808
00809 if (rowUpperWork_[iRow]>rowLowerWork_[iRow])
00810 setRowStatus(iRow,atLowerBound);
00811 } else if (getRowStatus(iRow)==isFree) {
00812
00813 if (rowLowerWork_[iRow]>-largeValue_||rowUpperWork_[iRow]<largeValue_)
00814 setRowStatus(iRow,superBasic);
00815 }
00816 }
00817 for (iColumn=0;iColumn<numberColumns_;iColumn++) {
00818 if(getColumnStatus(iColumn)==isFixed) {
00819
00820 if (columnUpperWork_[iColumn]>columnLowerWork_[iColumn])
00821 setColumnStatus(iColumn,atLowerBound);
00822 } else if (getColumnStatus(iColumn)==isFree) {
00823
00824 if (columnLowerWork_[iColumn]>-largeValue_||columnUpperWork_[iColumn]<largeValue_)
00825 setColumnStatus(iColumn,superBasic);
00826 }
00827 }
00828 if (!valuesPass) {
00829
00830 bool allSlack=true;
00831 if (status_) {
00832 for (iRow=0;iRow<numberRows_;iRow++) {
00833 if (getRowStatus(iRow)!=basic) {
00834 allSlack=false;
00835 break;
00836 }
00837 }
00838 }
00839 if (!allSlack) {
00840
00841 int numberBasic=0;
00842 for (iRow=0;iRow<numberRows_;iRow++) {
00843 switch(getRowStatus(iRow)) {
00844
00845 case basic:
00846 numberBasic++;
00847 break;
00848 case atUpperBound:
00849 rowActivityWork_[iRow]=rowUpperWork_[iRow];
00850 if (rowActivityWork_[iRow]>largeValue_) {
00851 if (rowLowerWork_[iRow]>-largeValue_) {
00852 rowActivityWork_[iRow]=rowLowerWork_[iRow];
00853 setRowStatus(iRow,atLowerBound);
00854 } else {
00855
00856 setRowStatus(iRow,isFree);
00857 rowActivityWork_[iRow]=0.0;
00858 }
00859 }
00860 break;
00861 case ClpSimplex::isFixed:
00862 case atLowerBound:
00863 rowActivityWork_[iRow]=rowLowerWork_[iRow];
00864 if (rowActivityWork_[iRow]<-largeValue_) {
00865 if (rowUpperWork_[iRow]<largeValue_) {
00866 rowActivityWork_[iRow]=rowUpperWork_[iRow];
00867 setRowStatus(iRow,atUpperBound);
00868 } else {
00869
00870 setRowStatus(iRow,isFree);
00871 rowActivityWork_[iRow]=0.0;
00872 }
00873 }
00874 break;
00875 case isFree:
00876 break;
00877
00878 case superBasic:
00879 if (rowUpperWork_[iRow]>largeValue_) {
00880 if (rowLowerWork_[iRow]>-largeValue_) {
00881 rowActivityWork_[iRow]=rowLowerWork_[iRow];
00882 setRowStatus(iRow,atLowerBound);
00883 } else {
00884
00885 setRowStatus(iRow,isFree);
00886 rowActivityWork_[iRow]=0.0;
00887 }
00888 } else {
00889 if (rowLowerWork_[iRow]>-largeValue_) {
00890
00891 if (fabs(rowActivityWork_[iRow]-rowLowerWork_[iRow])
00892 <fabs(rowActivityWork_[iRow]-rowLowerWork_[iRow])) {
00893 rowActivityWork_[iRow]=rowLowerWork_[iRow];
00894 setRowStatus(iRow,atLowerBound);
00895 } else {
00896 rowActivityWork_[iRow]=rowUpperWork_[iRow];
00897 setRowStatus(iRow,atUpperBound);
00898 }
00899 } else {
00900 rowActivityWork_[iRow]=rowUpperWork_[iRow];
00901 setRowStatus(iRow,atUpperBound);
00902 }
00903 }
00904 break;
00905 }
00906 }
00907 totalSlacks=numberBasic;
00908
00909 for (iColumn=0;iColumn<numberColumns_;iColumn++) {
00910 switch(getColumnStatus(iColumn)) {
00911
00912 case basic:
00913 if (numberBasic==numberRows_) {
00914
00915 if (columnLowerWork_[iColumn]>-largeValue_) {
00916 if (columnActivityWork_[iColumn]-columnLowerWork_[iColumn]<
00917 columnUpperWork_[iColumn]-columnActivityWork_[iColumn]) {
00918 columnActivityWork_[iColumn]=columnLowerWork_[iColumn];
00919 setColumnStatus(iColumn,atLowerBound);
00920 } else {
00921 columnActivityWork_[iColumn]=columnUpperWork_[iColumn];
00922 setColumnStatus(iColumn,atUpperBound);
00923 }
00924 } else if (columnUpperWork_[iColumn]<largeValue_) {
00925 columnActivityWork_[iColumn]=columnUpperWork_[iColumn];
00926 setColumnStatus(iColumn,atUpperBound);
00927 } else {
00928 columnActivityWork_[iColumn]=0.0;
00929 setColumnStatus(iColumn,isFree);
00930 }
00931 } else {
00932 numberBasic++;
00933 }
00934 break;
00935 case atUpperBound:
00936 columnActivityWork_[iColumn]=columnUpperWork_[iColumn];
00937 if (columnActivityWork_[iColumn]>largeValue_) {
00938 if (columnLowerWork_[iColumn]<-largeValue_) {
00939 columnActivityWork_[iColumn]=0.0;
00940 setColumnStatus(iColumn,isFree);
00941 } else {
00942 columnActivityWork_[iColumn]=columnLowerWork_[iColumn];
00943 setColumnStatus(iColumn,atLowerBound);
00944 }
00945 }
00946 break;
00947 case isFixed:
00948 case atLowerBound:
00949 columnActivityWork_[iColumn]=columnLowerWork_[iColumn];
00950 if (columnActivityWork_[iColumn]<-largeValue_) {
00951 if (columnUpperWork_[iColumn]>largeValue_) {
00952 columnActivityWork_[iColumn]=0.0;
00953 setColumnStatus(iColumn,isFree);
00954 } else {
00955 columnActivityWork_[iColumn]=columnUpperWork_[iColumn];
00956 setColumnStatus(iColumn,atUpperBound);
00957 }
00958 }
00959 break;
00960 case isFree:
00961 break;
00962
00963 case superBasic:
00964 if (columnUpperWork_[iColumn]>largeValue_) {
00965 if (columnLowerWork_[iColumn]>-largeValue_) {
00966 columnActivityWork_[iColumn]=columnLowerWork_[iColumn];
00967 setColumnStatus(iColumn,atLowerBound);
00968 } else {
00969
00970 setColumnStatus(iColumn,isFree);
00971 columnActivityWork_[iColumn]=0.0;
00972 }
00973 } else {
00974 if (columnLowerWork_[iColumn]>-largeValue_) {
00975
00976 if (fabs(columnActivityWork_[iColumn]-columnLowerWork_[iColumn])
00977 <fabs(columnActivityWork_[iColumn]-columnLowerWork_[iColumn])) {
00978 columnActivityWork_[iColumn]=columnLowerWork_[iColumn];
00979 setColumnStatus(iColumn,atLowerBound);
00980 } else {
00981 columnActivityWork_[iColumn]=columnUpperWork_[iColumn];
00982 setColumnStatus(iColumn,atUpperBound);
00983 }
00984 } else {
00985 columnActivityWork_[iColumn]=columnUpperWork_[iColumn];
00986 setColumnStatus(iColumn,atUpperBound);
00987 }
00988 }
00989 break;
00990 }
00991 }
00992 } else {
00993
00994 int numberBasic=0;
00995 if (!status_) {
00996 createStatus();
00997 }
00998 for (iRow=0;iRow<numberRows_;iRow++) {
00999 double lower=rowLowerWork_[iRow];
01000 double upper=rowUpperWork_[iRow];
01001 if (lower>-largeValue_||upper<largeValue_) {
01002 if (fabs(lower)<=fabs(upper)) {
01003 rowActivityWork_[iRow]=lower;
01004 } else {
01005 rowActivityWork_[iRow]=upper;
01006 }
01007 } else {
01008 rowActivityWork_[iRow]=0.0;
01009 }
01010 setRowStatus(iRow,basic);
01011 numberBasic++;
01012 }
01013 for (iColumn=0;iColumn<numberColumns_;iColumn++) {
01014 double lower=columnLowerWork_[iColumn];
01015 double upper=columnUpperWork_[iColumn];
01016 double big_bound = largeValue_;
01017 if (lower>-big_bound||upper<big_bound) {
01018 if ((getColumnStatus(iColumn)==atLowerBound&&
01019 columnActivityWork_[iColumn]==lower)||
01020 (getColumnStatus(iColumn)==atUpperBound&&
01021 columnActivityWork_[iColumn]==upper)) {
01022
01023 } else {
01024
01025 if (fabs(lower)<=fabs(upper)) {
01026 setColumnStatus(iColumn,atLowerBound);
01027 columnActivityWork_[iColumn]=lower;
01028 } else {
01029 setColumnStatus(iColumn,atUpperBound);
01030 columnActivityWork_[iColumn]=upper;
01031 }
01032 }
01033 } else {
01034 setColumnStatus(iColumn,isFree);
01035 columnActivityWork_[iColumn]=0.0;
01036 }
01037 }
01038 }
01039 } else {
01040
01041
01042 cleanStatus();
01043 if (status_) {
01044 int numberBasic=0;
01045 for (iRow=0;iRow<numberRows_;iRow++) {
01046 if (getRowStatus(iRow)==basic)
01047 numberBasic++;
01048 }
01049 totalSlacks=numberBasic;
01050 for (iColumn=0;iColumn<numberColumns_;iColumn++) {
01051 if (getColumnStatus(iColumn)==basic)
01052 numberBasic++;
01053 }
01054 } else {
01055
01056 int numberBasic=0;
01057 if (!status_) {
01058 createStatus();
01059 }
01060 for (iRow=0;iRow<numberRows_;iRow++) {
01061 setRowStatus(iRow,basic);
01062 numberBasic++;
01063 }
01064 for (iColumn=0;iColumn<numberColumns_;iColumn++) {
01065 setColumnStatus(iColumn,superBasic);
01066
01067 if (fabs(columnActivityWork_[iColumn]-columnLowerWork_[iColumn])
01068 <=primalTolerance_) {
01069 columnActivityWork_[iColumn]=columnLowerWork_[iColumn];
01070 setColumnStatus(iColumn,atLowerBound);
01071 } else if (fabs(columnActivityWork_[iColumn]
01072 -columnUpperWork_[iColumn])
01073 <=primalTolerance_) {
01074 columnActivityWork_[iColumn]=columnUpperWork_[iColumn];
01075 setColumnStatus(iColumn,atUpperBound);
01076 }
01077 }
01078 }
01079 }
01080 numberRefinements_=1;
01081
01082 for (iRow=0;iRow<numberRows_;iRow++) {
01083 if (getRowStatus(iRow)!=basic ) {
01084 if (rowLowerWork_[iRow]==rowUpperWork_[iRow]) {
01085 rowActivityWork_[iRow]=rowLowerWork_[iRow];
01086 setRowStatus(iRow,isFixed);
01087 }
01088 }
01089 }
01090 for (iColumn=0;iColumn<numberColumns_;iColumn++) {
01091 if (getColumnStatus(iColumn)!=basic ) {
01092 if (columnLowerWork_[iColumn]==columnUpperWork_[iColumn]) {
01093 columnActivityWork_[iColumn]=columnLowerWork_[iColumn];
01094 setColumnStatus(iColumn,isFixed);
01095 }
01096 }
01097 }
01098 }
01099 if (0) {
01100 static int k=0;
01101 printf("start basis\n");
01102 int i;
01103 for (i=0;i<numberRows_;i++)
01104 printf ("xx %d %d\n",i,pivotVariable_[i]);
01105 for (i=0;i<numberRows_+numberColumns_;i++)
01106 if (getColumnStatus(i)==basic)
01107 printf ("yy %d basic\n",i);
01108 if (k>20)
01109 exit(0);
01110 k++;
01111 }
01112 int status = factorization_->factorize(this, solveType,valuesPass);
01113 if (status) {
01114 handler_->message(CLP_SIMPLEX_BADFACTOR,messages_)
01115 <<status
01116 <<CoinMessageEol;
01117 return -1;
01118 } else if (!solveType) {
01119
01120 int numberSlacks=0;
01121 for (iRow=0;iRow<numberRows_;iRow++) {
01122 if (getRowStatus(iRow) == basic)
01123 numberSlacks++;
01124 }
01125 status= max(numberSlacks-totalSlacks,0);
01126 }
01127
01128
01129
01130
01131 factorization_->sparseThreshold(0);
01132 factorization_->goSparse();
01133
01134
01135 return status;
01136 }
01137
01138
01139
01140
01141 int
01142 ClpSimplex::housekeeping(double objectiveChange)
01143 {
01144 numberIterations_++;
01145 changeMade_++;
01146
01147 handler_->message(CLP_SIMPLEX_HOUSE1,messages_)
01148 <<directionOut_
01149 <<directionIn_<<theta_
01150 <<dualOut_<<dualIn_<<alpha_
01151 <<CoinMessageEol;
01152 if (getStatus(sequenceIn_)==isFree) {
01153 handler_->message(CLP_SIMPLEX_FREEIN,messages_)
01154 <<sequenceIn_
01155 <<CoinMessageEol;
01156 }
01157
01158 char rowcol[]={'R','C'};
01159 if (pivotRow_>=0)
01160 pivotVariable_[pivotRow_]=sequenceIn();
01161 if (upper_[sequenceIn_]>1.0e20&&lower_[sequenceIn_]<-1.0e20)
01162 progressFlag_ |= 2;
01163 solution_[sequenceIn_]=valueIn_;
01164 if (upper_[sequenceOut_]-lower_[sequenceOut_]<1.0e-12)
01165 progressFlag_ |= 1;
01166 if (sequenceIn_!=sequenceOut_) {
01167
01168 setStatus(sequenceIn_,basic);
01169 if (upper_[sequenceOut_]-lower_[sequenceOut_]>0) {
01170
01171
01172 if (fabs(valueOut_-lower_[sequenceOut_])<fabs(valueOut_-upper_[sequenceOut_])) {
01173
01174 setStatus(sequenceOut_,atLowerBound);
01175 } else {
01176
01177 setStatus(sequenceOut_,atUpperBound);
01178 }
01179 } else {
01180
01181 setStatus(sequenceOut_,isFixed);
01182 }
01183 solution_[sequenceOut_]=valueOut_;
01184 } else {
01185
01186
01187
01188 if (fabs(valueIn_-lower_[sequenceIn_])<fabs(valueIn_-upper_[sequenceIn_])) {
01189
01190 setStatus(sequenceIn_, atLowerBound);
01191 } else {
01192
01193 setStatus(sequenceIn_, atUpperBound);
01194 }
01195 }
01196 objectiveValue_ += objectiveChange;
01197 handler_->message(CLP_SIMPLEX_HOUSE2,messages_)
01198 <<numberIterations_<<objectiveValue()
01199 <<rowcol[isColumn(sequenceIn_)]<<sequenceWithin(sequenceIn_)
01200 <<rowcol[isColumn(sequenceOut_)]<<sequenceWithin(sequenceOut_);
01201 handler_->printing(algorithm_<0)<<theta_<<dualOut_;
01202 handler_->printing(algorithm_>0)<<dualIn_<<theta_;
01203 handler_->message()<<CoinMessageEol;
01204 if (hitMaximumIterations())
01205 return 2;
01206 #if 0
01207
01208 int cycle=progress_->cycle(sequenceIn_,sequenceOut_,
01209 directionIn_,directionOut_);
01210 if (cycle>0) {
01211 printf("Cycle of %d\n",cycle);
01212
01213 progress_->startCheck();
01214 if (factorization_->pivots()>cycle) {
01215 forceFactorization_=cycle-1;
01216 } else {
01217
01218 int iSequence;
01219 if (algorithm_<0)
01220 iSequence = sequenceIn_;
01221 else
01222 iSequence = sequenceOut_;
01223 char x = isColumn(iSequence) ? 'C' :'R';
01224 handler_->message(CLP_SIMPLEX_FLAG,messages_)
01225 <<x<<sequenceWithin(iSequence)
01226 <<CoinMessageEol;
01227 setFlagged(iSequence);
01228 printf("flagging %d\n",iSequence);
01229 }
01230 return 1;
01231 }
01232 #endif
01233
01234
01235 if (factorization_->pivots()==factorization_->maximumPivots()) {
01236 return 1;
01237 } else {
01238 if (forceFactorization_>0&&
01239 factorization_->pivots()==forceFactorization_) {
01240
01241 forceFactorization_ = (3+5*forceFactorization_)/4;
01242 if (forceFactorization_>factorization_->maximumPivots())
01243 forceFactorization_ = -1;
01244 return 1;
01245 } else {
01246
01247 return 0;
01248 }
01249 }
01250 }
01251
01252 ClpSimplex::ClpSimplex(const ClpSimplex &rhs) :
01253 ClpModel(rhs),
01254 columnPrimalInfeasibility_(0.0),
01255 rowPrimalInfeasibility_(0.0),
01256 columnPrimalSequence_(-2),
01257 rowPrimalSequence_(-2),
01258 columnDualInfeasibility_(0.0),
01259 rowDualInfeasibility_(0.0),
01260 columnDualSequence_(-2),
01261 rowDualSequence_(-2),
01262 primalToleranceToGetOptimal_(-1.0),
01263 remainingDualInfeasibility_(0.0),
01264 largeValue_(1.0e15),
01265 largestPrimalError_(0.0),
01266 largestDualError_(0.0),
01267 largestSolutionError_(0.0),
01268 dualBound_(1.0e10),
01269 alpha_(0.0),
01270 theta_(0.0),
01271 lowerIn_(0.0),
01272 valueIn_(0.0),
01273 upperIn_(0.0),
01274 dualIn_(0.0),
01275 lowerOut_(-1),
01276 valueOut_(-1),
01277 upperOut_(-1),
01278 dualOut_(-1),
01279 dualTolerance_(0.0),
01280 primalTolerance_(0.0),
01281 sumDualInfeasibilities_(0.0),
01282 sumPrimalInfeasibilities_(0.0),
01283 infeasibilityCost_(1.0e10),
01284 sumOfRelaxedDualInfeasibilities_(0.0),
01285 sumOfRelaxedPrimalInfeasibilities_(0.0),
01286 lower_(NULL),
01287 rowLowerWork_(NULL),
01288 columnLowerWork_(NULL),
01289 upper_(NULL),
01290 rowUpperWork_(NULL),
01291 columnUpperWork_(NULL),
01292 cost_(NULL),
01293 rowObjectiveWork_(NULL),
01294 objectiveWork_(NULL),
01295 sequenceIn_(-1),
01296 directionIn_(-1),
01297 sequenceOut_(-1),
01298 directionOut_(-1),
01299 pivotRow_(-1),
01300 lastGoodIteration_(-100),
01301 dj_(NULL),
01302 rowReducedCost_(NULL),
01303 reducedCostWork_(NULL),
01304 solution_(NULL),
01305 rowActivityWork_(NULL),
01306 columnActivityWork_(NULL),
01307 numberDualInfeasibilities_(0),
01308 numberDualInfeasibilitiesWithoutFree_(0),
01309 numberPrimalInfeasibilities_(100),
01310 numberRefinements_(0),
01311 pivotVariable_(NULL),
01312 factorization_(NULL),
01313 rowScale_(NULL),
01314 savedSolution_(NULL),
01315 columnScale_(NULL),
01316 scalingFlag_(3),
01317 numberTimesOptimal_(0),
01318 changeMade_(1),
01319 algorithm_(0),
01320 forceFactorization_(-1),
01321 perturbation_(100),
01322 nonLinearCost_(NULL),
01323 specialOptions_(0),
01324 lastBadIteration_(-999999),
01325 numberFake_(0),
01326 progressFlag_(0),
01327 firstFree_(-1),
01328 incomingInfeasibility_(1.0),
01329 allowedInfeasibility_(10.0),
01330 progress_(NULL)
01331 {
01332 int i;
01333 for (i=0;i<6;i++) {
01334 rowArray_[i]=NULL;
01335 columnArray_[i]=NULL;
01336 }
01337 saveStatus_=NULL;
01338 factorization_ = NULL;
01339 dualRowPivot_ = NULL;
01340 primalColumnPivot_ = NULL;
01341 gutsOfDelete(0);
01342 specialOptions_ =0;
01343 delete nonLinearCost_;
01344 nonLinearCost_ = NULL;
01345 gutsOfCopy(rhs);
01346 solveType_=1;
01347 }
01348
01349 ClpSimplex::ClpSimplex(const ClpModel &rhs) :
01350 ClpModel(rhs),
01351 columnPrimalInfeasibility_(0.0),
01352 rowPrimalInfeasibility_(0.0),
01353 columnPrimalSequence_(-2),
01354 rowPrimalSequence_(-2),
01355 columnDualInfeasibility_(0.0),
01356 rowDualInfeasibility_(0.0),
01357 columnDualSequence_(-2),
01358 rowDualSequence_(-2),
01359 primalToleranceToGetOptimal_(-1.0),
01360 remainingDualInfeasibility_(0.0),
01361 largeValue_(1.0e15),
01362 largestPrimalError_(0.0),
01363 largestDualError_(0.0),
01364 largestSolutionError_(0.0),
01365 dualBound_(1.0e10),
01366 alpha_(0.0),
01367 theta_(0.0),
01368 lowerIn_(0.0),
01369 valueIn_(0.0),
01370 upperIn_(0.0),
01371 dualIn_(0.0),
01372 lowerOut_(-1),
01373 valueOut_(-1),
01374 upperOut_(-1),
01375 dualOut_(-1),
01376 dualTolerance_(0.0),
01377 primalTolerance_(0.0),
01378 sumDualInfeasibilities_(0.0),
01379 sumPrimalInfeasibilities_(0.0),
01380 infeasibilityCost_(1.0e10),
01381 sumOfRelaxedDualInfeasibilities_(0.0),
01382 sumOfRelaxedPrimalInfeasibilities_(0.0),
01383 lower_(NULL),
01384 rowLowerWork_(NULL),
01385 columnLowerWork_(NULL),
01386 upper_(NULL),
01387 rowUpperWork_(NULL),
01388 columnUpperWork_(NULL),
01389 cost_(NULL),
01390 rowObjectiveWork_(NULL),
01391 objectiveWork_(NULL),
01392 sequenceIn_(-1),
01393 directionIn_(-1),
01394 sequenceOut_(-1),
01395 directionOut_(-1),
01396 pivotRow_(-1),
01397 lastGoodIteration_(-100),
01398 dj_(NULL),
01399 rowReducedCost_(NULL),
01400 reducedCostWork_(NULL),
01401 solution_(NULL),
01402 rowActivityWork_(NULL),
01403 columnActivityWork_(NULL),
01404 numberDualInfeasibilities_(0),
01405 numberDualInfeasibilitiesWithoutFree_(0),
01406 numberPrimalInfeasibilities_(100),
01407 numberRefinements_(0),
01408 pivotVariable_(NULL),
01409 factorization_(NULL),
01410 rowScale_(NULL),
01411 savedSolution_(NULL),
01412 columnScale_(NULL),
01413 scalingFlag_(3),
01414 numberTimesOptimal_(0),
01415 changeMade_(1),
01416 algorithm_(0),
01417 forceFactorization_(-1),
01418 perturbation_(100),
01419 nonLinearCost_(NULL),
01420 specialOptions_(0),
01421 lastBadIteration_(-999999),
01422 numberFake_(0),
01423 progressFlag_(0),
01424 firstFree_(-1),
01425 incomingInfeasibility_(1.0),
01426 allowedInfeasibility_(10.0),
01427 progress_(NULL)
01428 {
01429 int i;
01430 for (i=0;i<6;i++) {
01431 rowArray_[i]=NULL;
01432 columnArray_[i]=NULL;
01433 }
01434 saveStatus_=NULL;
01435
01436 factorization_ = new ClpFactorization();
01437
01438 dualRowPivot_ = new ClpDualRowSteepest();
01439
01440 primalColumnPivot_ = new ClpPrimalColumnSteepest();
01441 solveType_=1;
01442
01443 }
01444
01445 ClpSimplex &
01446 ClpSimplex::operator=(const ClpSimplex & rhs)
01447 {
01448 if (this != &rhs) {
01449 gutsOfDelete(0);
01450 specialOptions_=0;
01451 delete nonLinearCost_;
01452 nonLinearCost_ = NULL;
01453 ClpModel::operator=(rhs);
01454 gutsOfCopy(rhs);
01455 }
01456 return *this;
01457 }
01458 void
01459 ClpSimplex::gutsOfCopy(const ClpSimplex & rhs)
01460 {
01461 lower_ = ClpCopyOfArray(rhs.lower_,numberColumns_+numberRows_);
01462 rowLowerWork_ = lower_+numberColumns_;
01463 columnLowerWork_ = lower_;
01464 upper_ = ClpCopyOfArray(rhs.upper_,numberColumns_+numberRows_);
01465 rowUpperWork_ = upper_+numberColumns_;
01466 columnUpperWork_ = upper_;
01467
01468 cost_ = ClpCopyOfArray(rhs.cost_,(numberColumns_+numberRows_));
01469 objectiveWork_ = cost_;
01470 rowObjectiveWork_ = cost_+numberColumns_;
01471 dj_ = ClpCopyOfArray(rhs.dj_,numberRows_+numberColumns_);
01472 if (dj_) {
01473 reducedCostWork_ = dj_;
01474 rowReducedCost_ = dj_+numberColumns_;
01475 }
01476 solution_ = ClpCopyOfArray(rhs.solution_,numberRows_+numberColumns_);
01477 if (solution_) {
01478 columnActivityWork_ = solution_;
01479 rowActivityWork_ = solution_+numberColumns_;
01480 }
01481 if (rhs.pivotVariable_) {
01482 pivotVariable_ = new int[numberRows_];
01483 ClpDisjointCopyN ( rhs.pivotVariable_, numberRows_ , pivotVariable_);
01484 } else {
01485 pivotVariable_=NULL;
01486 }
01487 if (rhs.factorization_) {
01488 factorization_ = new ClpFactorization(*rhs.factorization_);
01489 } else {
01490 factorization_=NULL;
01491 }
01492 rowScale_ = ClpCopyOfArray(rhs.rowScale_,numberRows_);
01493 savedSolution_ = ClpCopyOfArray(rhs.savedSolution_,numberColumns_+numberRows_);
01494 columnScale_ = ClpCopyOfArray(rhs.columnScale_,numberColumns_);
01495 int i;
01496 for (i=0;i<6;i++) {
01497 rowArray_[i]=NULL;
01498 if (rhs.rowArray_[i])
01499 rowArray_[i] = new CoinIndexedVector(*rhs.rowArray_[i]);
01500 columnArray_[i]=NULL;
01501 if (rhs.columnArray_[i])
01502 columnArray_[i] = new CoinIndexedVector(*rhs.columnArray_[i]);
01503 }
01504 if (rhs.saveStatus_) {
01505 saveStatus_ = ClpCopyOfArray( rhs.saveStatus_,numberColumns_+numberRows_);
01506 }
01507 columnPrimalInfeasibility_ = rhs.columnPrimalInfeasibility_;
01508 columnPrimalSequence_ = rhs.columnPrimalSequence_;
01509 rowPrimalInfeasibility_ = rhs.rowPrimalInfeasibility_;
01510 rowPrimalSequence_ = rhs.rowPrimalSequence_;
01511 columnDualInfeasibility_ = rhs.columnDualInfeasibility_;
01512 columnDualSequence_ = rhs.columnDualSequence_;
01513 rowDualInfeasibility_ = rhs.rowDualInfeasibility_;
01514 rowDualSequence_ = rhs.rowDualSequence_;
01515 primalToleranceToGetOptimal_ = rhs.primalToleranceToGetOptimal_;
01516 remainingDualInfeasibility_ = rhs.remainingDualInfeasibility_;
01517 largeValue_ = rhs.largeValue_;
01518 largestPrimalError_ = rhs.largestPrimalError_;
01519 largestDualError_ = rhs.largestDualError_;
01520 largestSolutionError_ = rhs.largestSolutionError_;
01521 dualBound_ = rhs.dualBound_;
01522 alpha_ = rhs.alpha_;
01523 theta_ = rhs.theta_;
01524 lowerIn_ = rhs.lowerIn_;
01525 valueIn_ = rhs.valueIn_;
01526 upperIn_ = rhs.upperIn_;
01527 dualIn_ = rhs.dualIn_;
01528 sequenceIn_ = rhs.sequenceIn_;
01529 directionIn_ = rhs.directionIn_;
01530 lowerOut_ = rhs.lowerOut_;
01531 valueOut_ = rhs.valueOut_;
01532 upperOut_ = rhs.upperOut_;
01533 dualOut_ = rhs.dualOut_;
01534 sequenceOut_ = rhs.sequenceOut_;
01535 directionOut_ = rhs.directionOut_;
01536 pivotRow_ = rhs.pivotRow_;
01537 lastGoodIteration_ = rhs.lastGoodIteration_;
01538 numberRefinements_ = rhs.numberRefinements_;
01539 dualTolerance_ = rhs.dualTolerance_;
01540 primalTolerance_ = rhs.primalTolerance_;
01541 sumDualInfeasibilities_ = rhs.sumDualInfeasibilities_;
01542 numberDualInfeasibilities_ = rhs.numberDualInfeasibilities_;
01543 numberDualInfeasibilitiesWithoutFree_ =
01544 rhs.numberDualInfeasibilitiesWithoutFree_;
01545 sumPrimalInfeasibilities_ = rhs.sumPrimalInfeasibilities_;
01546 numberPrimalInfeasibilities_ = rhs.numberPrimalInfeasibilities_;
01547 dualRowPivot_ = rhs.dualRowPivot_->clone(true);
01548 primalColumnPivot_ = rhs.primalColumnPivot_->clone(true);
01549 scalingFlag_ = rhs.scalingFlag_;
01550 numberTimesOptimal_ = rhs.numberTimesOptimal_;
01551 changeMade_ = rhs.changeMade_;
01552 algorithm_ = rhs.algorithm_;
01553 forceFactorization_ = rhs.forceFactorization_;
01554 perturbation_ = rhs.perturbation_;
01555 infeasibilityCost_ = rhs.infeasibilityCost_;
01556 specialOptions_ = rhs.specialOptions_;
01557 lastBadIteration_ = rhs.lastBadIteration_;
01558 numberFake_ = rhs.numberFake_;
01559 progressFlag_ = rhs.progressFlag_;
01560 firstFree_ = rhs.firstFree_;
01561 incomingInfeasibility_ = rhs.incomingInfeasibility_;
01562 allowedInfeasibility_ = rhs.allowedInfeasibility_;
01563 if (rhs.progress_)
01564 progress_ = new ClpSimplexProgress(*rhs.progress_);
01565 else
01566 progress_=NULL;
01567 sumOfRelaxedDualInfeasibilities_ = rhs.sumOfRelaxedDualInfeasibilities_;
01568 sumOfRelaxedPrimalInfeasibilities_ = rhs.sumOfRelaxedPrimalInfeasibilities_;
01569 if (rhs.nonLinearCost_!=NULL)
01570 nonLinearCost_ = new ClpNonLinearCost(*rhs.nonLinearCost_);
01571 else
01572 nonLinearCost_=NULL;
01573 solveType_=rhs.solveType_;
01574 }
01575
01576 void
01577 ClpSimplex::gutsOfDelete(int type)
01578 {
01579 delete [] lower_;
01580 lower_=NULL;
01581 rowLowerWork_=NULL;
01582 columnLowerWork_=NULL;
01583 delete [] upper_;
01584 upper_=NULL;
01585 rowUpperWork_=NULL;
01586 columnUpperWork_=NULL;
01587 delete [] cost_;
01588 cost_=NULL;
01589 objectiveWork_=NULL;
01590 rowObjectiveWork_=NULL;
01591 delete [] dj_;
01592 dj_=NULL;
01593 reducedCostWork_=NULL;
01594 rowReducedCost_=NULL;
01595 delete [] solution_;
01596 solution_=NULL;
01597 rowActivityWork_=NULL;
01598 columnActivityWork_=NULL;
01599 delete [] rowScale_;
01600 rowScale_ = NULL;
01601 delete [] savedSolution_;
01602 savedSolution_ = NULL;
01603 delete [] columnScale_;
01604 columnScale_ = NULL;
01605 if ((specialOptions_&2)==0) {
01606 delete nonLinearCost_;
01607 nonLinearCost_ = NULL;
01608 }
01609 int i;
01610 for (i=0;i<6;i++) {
01611 delete rowArray_[i];
01612 rowArray_[i]=NULL;
01613 delete columnArray_[i];
01614 columnArray_[i]=NULL;
01615 }
01616 delete rowCopy_;
01617 rowCopy_=NULL;
01618 delete [] saveStatus_;
01619 saveStatus_=NULL;
01620 if (!type) {
01621
01622 delete factorization_;
01623 factorization_ = NULL;
01624 delete [] pivotVariable_;
01625 pivotVariable_=NULL;
01626 delete dualRowPivot_;
01627 dualRowPivot_ = NULL;
01628 delete primalColumnPivot_;
01629 primalColumnPivot_ = NULL;
01630 delete progress_;
01631 progress_=NULL;
01632 } else {
01633
01634 if (type>1) {
01635 factorization_->clearArrays();
01636 delete [] pivotVariable_;
01637 pivotVariable_=NULL;
01638 }
01639 dualRowPivot_->clearArrays();
01640 primalColumnPivot_->clearArrays();
01641 }
01642 }
01643
01644 void
01645 ClpSimplex::checkPrimalSolution(const double * rowActivities,
01646 const double * columnActivities)
01647 {
01648 double * solution;
01649 int iRow,iColumn;
01650
01651 objectiveValue_ = 0.0;
01652
01653 columnPrimalInfeasibility_=0.0;
01654 columnPrimalSequence_=-1;
01655 rowPrimalInfeasibility_=0.0;
01656 rowPrimalSequence_=-1;
01657 largestSolutionError_=0.0;
01658 solution = rowActivityWork_;
01659 sumPrimalInfeasibilities_=0.0;
01660 numberPrimalInfeasibilities_=0;
01661 double primalTolerance = primalTolerance_;
01662 double relaxedTolerance=primalTolerance_;
01663
01664 double error = min(1.0e-3,largestPrimalError_);
01665
01666 relaxedTolerance = relaxedTolerance + error;
01667 sumOfRelaxedPrimalInfeasibilities_ = 0.0;
01668
01669 for (iRow=0;iRow<numberRows_;iRow++) {
01670
01671 double infeasibility=0.0;
01672 objectiveValue_ += solution[iRow]*rowObjectiveWork_[iRow];
01673 if (solution[iRow]>rowUpperWork_[iRow]) {
01674 infeasibility=solution[iRow]-rowUpperWork_[iRow];
01675 } else if (solution[iRow]<rowLowerWork_[iRow]) {
01676 infeasibility=rowLowerWork_[iRow]-solution[iRow];
01677 }
01678 if (infeasibility>primalTolerance) {
01679 sumPrimalInfeasibilities_ += infeasibility-primalTolerance_;
01680 if (infeasibility>relaxedTolerance)
01681 sumOfRelaxedPrimalInfeasibilities_ += infeasibility-relaxedTolerance;
01682 numberPrimalInfeasibilities_ ++;
01683 }
01684 if (infeasibility>rowPrimalInfeasibility_) {
01685 rowPrimalInfeasibility_=infeasibility;
01686 rowPrimalSequence_=iRow;
01687 }
01688 infeasibility = fabs(rowActivities[iRow]-solution[iRow]);
01689 if (infeasibility>largestSolutionError_)
01690 largestSolutionError_=infeasibility;
01691 }
01692 solution = columnActivityWork_;
01693 for (iColumn=0;iColumn<numberColumns_;iColumn++) {
01694
01695 double infeasibility=0.0;
01696 objectiveValue_ += objectiveWork_[iColumn]*solution[iColumn];
01697 if (solution[iColumn]>columnUpperWork_[iColumn]) {
01698 infeasibility=solution[iColumn]-columnUpperWork_[iColumn];
01699 } else if (solution[iColumn]<columnLowerWork_[iColumn]) {
01700 infeasibility=columnLowerWork_[iColumn]-solution[iColumn];
01701 }
01702 if (infeasibility>columnPrimalInfeasibility_) {
01703 columnPrimalInfeasibility_=infeasibility;
01704 columnPrimalSequence_=iColumn;
01705 }
01706 if (infeasibility>primalTolerance) {
01707 sumPrimalInfeasibilities_ += infeasibility-primalTolerance_;
01708 if (infeasibility>relaxedTolerance)
01709 sumOfRelaxedPrimalInfeasibilities_ += infeasibility-relaxedTolerance;
01710 numberPrimalInfeasibilities_ ++;
01711 }
01712 infeasibility = fabs(columnActivities[iColumn]-solution[iColumn]);
01713 if (infeasibility>largestSolutionError_)
01714 largestSolutionError_=infeasibility;
01715 }
01716 }
01717 void
01718 ClpSimplex::checkDualSolution()
01719 {
01720
01721 int iRow,iColumn;
01722 sumDualInfeasibilities_=0.0;
01723 numberDualInfeasibilities_=0;
01724 numberDualInfeasibilitiesWithoutFree_=0;
01725 columnDualInfeasibility_=0.0;
01726 columnDualSequence_=-1;
01727 rowDualInfeasibility_=0.0;
01728 rowDualSequence_=-1;
01729 int firstFreePrimal = -1;
01730 int firstFreeDual = -1;
01731 int numberSuperBasicWithDj=0;
01732 primalToleranceToGetOptimal_=max(rowPrimalInfeasibility_,
01733 columnPrimalInfeasibility_);
01734 remainingDualInfeasibility_=0.0;
01735 double relaxedTolerance=dualTolerance_;
01736
01737 double error = min(1.0e-3,largestDualError_);
01738
01739 relaxedTolerance = relaxedTolerance + error;
01740 sumOfRelaxedDualInfeasibilities_ = 0.0;
01741
01742 for (iColumn=0;iColumn<numberColumns_;iColumn++) {
01743 if (getColumnStatus(iColumn) != basic&&!flagged(iColumn)) {
01744
01745 double distanceUp = columnUpperWork_[iColumn]-
01746 columnActivityWork_[iColumn];
01747 double distanceDown = columnActivityWork_[iColumn] -
01748 columnLowerWork_[iColumn];
01749 if (distanceUp>primalTolerance_) {
01750 double value = reducedCostWork_[iColumn];
01751
01752 if (distanceDown>primalTolerance_) {
01753 if (fabs(value)>1.0e2*relaxedTolerance) {
01754 numberSuperBasicWithDj++;
01755 if (firstFreeDual<0)
01756 firstFreeDual = iColumn;
01757 }
01758 if (firstFreePrimal<0)
01759 firstFreePrimal = iColumn;
01760 }
01761
01762 if (value<0.0) {
01763 value = - value;
01764 if (value>columnDualInfeasibility_) {
01765 columnDualInfeasibility_=value;
01766 columnDualSequence_=iColumn;
01767 }
01768 if (value>dualTolerance_) {
01769 if (getColumnStatus(iColumn) != isFree) {
01770 numberDualInfeasibilitiesWithoutFree_ ++;
01771 sumDualInfeasibilities_ += value-dualTolerance_;
01772 if (value>relaxedTolerance)
01773 sumOfRelaxedDualInfeasibilities_ += value-relaxedTolerance;
01774 numberDualInfeasibilities_ ++;
01775 } else {
01776
01777 value *= 0.01;
01778 if (value>dualTolerance_) {
01779 sumDualInfeasibilities_ += value-dualTolerance_;
01780 if (value>relaxedTolerance)
01781 sumOfRelaxedDualInfeasibilities_ += value-relaxedTolerance;
01782 numberDualInfeasibilities_ ++;
01783 }
01784 }
01785
01786 if (distanceUp<largeValue_) {
01787 if (distanceUp>primalToleranceToGetOptimal_)
01788 primalToleranceToGetOptimal_=distanceUp;
01789 } else {
01790
01791 remainingDualInfeasibility_=
01792 max(remainingDualInfeasibility_,value);
01793 }
01794 }
01795 }
01796 }
01797 if (distanceDown>primalTolerance_) {
01798 double value = reducedCostWork_[iColumn];
01799
01800 if (value>0.0) {
01801 if (value>columnDualInfeasibility_) {
01802 columnDualInfeasibility_=value;
01803 columnDualSequence_=iColumn;
01804 }
01805 if (value>dualTolerance_) {
01806 sumDualInfeasibilities_ += value-dualTolerance_;
01807 if (value>relaxedTolerance)
01808 sumOfRelaxedDualInfeasibilities_ += value-relaxedTolerance;
01809 numberDualInfeasibilities_ ++;
01810 if (getColumnStatus(iColumn) != isFree)
01811 numberDualInfeasibilitiesWithoutFree_ ++;
01812
01813 if (distanceDown<largeValue_&&
01814 distanceDown>primalToleranceToGetOptimal_)
01815 primalToleranceToGetOptimal_=distanceDown;
01816 }
01817 }
01818 }
01819 }
01820 }
01821 for (iRow=0;iRow<numberRows_;iRow++) {
01822 if (getRowStatus(iRow) != basic&&!flagged(iRow+numberColumns_)) {
01823
01824 double distanceUp = rowUpperWork_[iRow]-rowActivityWork_[iRow];
01825 double distanceDown = rowActivityWork_[iRow] -rowLowerWork_[iRow];
01826 if (distanceUp>primalTolerance_) {
01827 double value = rowReducedCost_[iRow];
01828
01829 if (distanceDown>primalTolerance_) {
01830 if (fabs(value)>1.0e2*relaxedTolerance) {
01831 numberSuperBasicWithDj++;
01832 if (firstFreeDual<0)
01833 firstFreeDual = iRow+numberColumns_;
01834 }
01835 if (firstFreePrimal<0)
01836 firstFreePrimal = iRow+numberColumns_;
01837 }
01838
01839 if (value<0.0) {
01840 value = - value;
01841 if (value>rowDualInfeasibility_) {
01842 rowDualInfeasibility_=value;
01843 rowDualSequence_=iRow;
01844 }
01845 if (value>dualTolerance_) {
01846 sumDualInfeasibilities_ += value-dualTolerance_;
01847 if (value>relaxedTolerance)
01848 sumOfRelaxedDualInfeasibilities_ += value-relaxedTolerance;
01849 numberDualInfeasibilities_ ++;
01850 if (getRowStatus(iRow) != isFree)
01851 numberDualInfeasibilitiesWithoutFree_ ++;
01852
01853 if (distanceUp<largeValue_) {
01854 if (distanceUp>primalToleranceToGetOptimal_)
01855 primalToleranceToGetOptimal_=distanceUp;
01856 } else {
01857
01858 remainingDualInfeasibility_=
01859 max(remainingDualInfeasibility_,value);
01860 }
01861 }
01862 }
01863 }
01864 if (distanceDown>primalTolerance_) {
01865 double value = rowReducedCost_[iRow];
01866
01867 if (value>0.0) {
01868 if (value>rowDualInfeasibility_) {
01869 rowDualInfeasibility_=value;
01870 rowDualSequence_=iRow;
01871 }
01872 if (value>dualTolerance_) {
01873 sumDualInfeasibilities_ += value-dualTolerance_;
01874 if (value>relaxedTolerance)
01875 sumOfRelaxedDualInfeasibilities_ += value-relaxedTolerance;
01876 numberDualInfeasibilities_ ++;
01877 if (getRowStatus(iRow) != isFree)
01878 numberDualInfeasibilitiesWithoutFree_ ++;
01879
01880 if (distanceDown<largeValue_&&
01881 distanceDown>primalToleranceToGetOptimal_)
01882 primalToleranceToGetOptimal_=distanceDown;
01883 }
01884 }
01885 }
01886 }
01887 }
01888 if (algorithm_<0&&firstFreeDual>=0) {
01889
01890 firstFree_ = firstFreeDual;
01891 } else if (numberSuperBasicWithDj||
01892 (progress_&&progress_->lastIterationNumber(0)<=0)) {
01893 firstFree_=firstFreePrimal;
01894 }
01895 }
01896
01897
01898
01899 void
01900 ClpSimplex::unpack(CoinIndexedVector * rowArray) const
01901 {
01902 rowArray->clear();
01903 if (sequenceIn_>=numberColumns_) {
01904
01905 rowArray->insert(sequenceIn_-numberColumns_,-1.0);
01906 } else {
01907
01908 matrix_->unpack(this,rowArray,sequenceIn_);
01909 }
01910 }
01911 void
01912 ClpSimplex::unpack(CoinIndexedVector * rowArray,int sequence) const
01913 {
01914 rowArray->clear();
01915 if (sequence>=numberColumns_) {
01916
01917 rowArray->insert(sequence-numberColumns_,-1.0);
01918 } else {
01919
01920 matrix_->unpack(this,rowArray,sequence);
01921 }
01922 }
01923
01924
01925
01926 void
01927 ClpSimplex::unpackPacked(CoinIndexedVector * rowArray)
01928 {
01929 rowArray->clear();
01930 if (sequenceIn_>=numberColumns_) {
01931
01932 int * index = rowArray->getIndices();
01933 double * array = rowArray->denseVector();
01934 array[0]=-1.0;
01935 index[0]=sequenceIn_-numberColumns_;
01936 rowArray->setNumElements(1);
01937 rowArray->setPackedMode(true);
01938 } else {
01939
01940 matrix_->unpackPacked(this,rowArray,sequenceIn_);
01941 }
01942 }
01943 void
01944 ClpSimplex::unpackPacked(CoinIndexedVector * rowArray,int sequence)
01945 {
01946 rowArray->clear();
01947 if (sequence>=numberColumns_) {
01948
01949 int * index = rowArray->getIndices();
01950 double * array = rowArray->denseVector();
01951 array[0]=-1.0;
01952 index[0]=sequence-numberColumns_;
01953 rowArray->setNumElements(1);
01954 rowArray->setPackedMode(true);
01955 } else {
01956
01957 matrix_->unpackPacked(this,rowArray,sequence);
01958 }
01959 }
01960 bool
01961 ClpSimplex::createRim(int what,bool makeRowCopy)
01962 {
01963 bool goodMatrix=true;
01964 int saveLevel=handler_->logLevel();
01965 if (problemStatus_==10) {
01966 handler_->setLogLevel(0);
01967 } else if (factorization_) {
01968
01969 if (handler_->logLevel()<3)
01970 factorization_->messageLevel(0);
01971 else
01972 factorization_->messageLevel(3);
01973 }
01974 int i;
01975 if ((what&(16+32))!=0) {
01976
01977 double direction = optimizationDirection_;
01978
01979 if (direction)
01980 direction = 1.0/direction;
01981 if (direction!=1.0) {
01982
01983 for (i=0;i<numberColumns_;i++)
01984 reducedCost_[i] *= direction;
01985 for (i=0;i<numberRows_;i++)
01986 dual_[i] *= direction;
01987 }
01988
01989 if (!dj_) {
01990 dj_ = new double[numberRows_+numberColumns_];
01991 reducedCostWork_ = dj_;
01992 rowReducedCost_ = dj_+numberColumns_;
01993 memcpy(reducedCostWork_,reducedCost_,numberColumns_*sizeof(double));
01994 memcpy(rowReducedCost_,dual_,numberRows_*sizeof(double));
01995 }
01996 if (!solution_||(what&32)!=0) {
01997 if (!solution_)
01998 solution_ = new double[numberRows_+numberColumns_];
01999 columnActivityWork_ = solution_;
02000 rowActivityWork_ = solution_+numberColumns_;
02001 memcpy(columnActivityWork_,columnActivity_,
02002 numberColumns_*sizeof(double));
02003 memcpy(rowActivityWork_,rowActivity_,
02004 numberRows_*sizeof(double));
02005 }
02006 }
02007 if ((what&16)!=0) {
02008
02009 if (!matrix_)
02010 matrix_=new ClpPackedMatrix();
02011 if (!matrix_->allElementsInRange(this,smallElement_,1.0e20)) {
02012 problemStatus_=4;
02013 goodMatrix= false;
02014 }
02015 if (makeRowCopy) {
02016 delete rowCopy_;
02017
02018 rowCopy_ = matrix_->reverseOrderedCopy();
02019 #ifdef TAKEOUT
02020 {
02021
02022 ClpPackedMatrix* rowCopy =
02023 dynamic_cast< ClpPackedMatrix*>(rowCopy_);
02024 const int * column = rowCopy->getIndices();
02025 const CoinBigIndex * rowStart = rowCopy->getVectorStarts();
02026 const double * element = rowCopy->getElements();
02027 int i;
02028 for (i=133;i<numberRows_;i++) {
02029 if (rowStart[i+1]-rowStart[i]==10||rowStart[i+1]-rowStart[i]==15)
02030 printf("Row %d has %d elements\n",i,rowStart[i+1]-rowStart[i]);
02031 }
02032 }
02033 #endif
02034 }
02035 }
02036 if ((what&4)!=0) {
02037 delete [] cost_;
02038
02039 int nTotal = numberRows_+numberColumns_;
02040
02041 cost_ = new double[nTotal];
02042 objectiveWork_ = cost_;
02043 rowObjectiveWork_ = cost_+numberColumns_;
02044 memcpy(objectiveWork_,objective(),numberColumns_*sizeof(double));
02045 if (rowObjective_)
02046 memcpy(rowObjectiveWork_,rowObjective_,numberRows_*sizeof(double));
02047 else
02048 memset(rowObjectiveWork_,0,numberRows_*sizeof(double));
02049
02050
02051 }
02052 if ((what&1)!=0) {
02053 delete [] lower_;
02054 delete [] upper_;
02055 lower_ = new double[numberColumns_+numberRows_];
02056 upper_ = new double[numberColumns_+numberRows_];
02057 rowLowerWork_ = lower_+numberColumns_;
02058 columnLowerWork_ = lower_;
02059 rowUpperWork_ = upper_+numberColumns_;
02060 columnUpperWork_ = upper_;
02061 memcpy(rowLowerWork_,rowLower_,numberRows_*sizeof(double));
02062 memcpy(rowUpperWork_,rowUpper_,numberRows_*sizeof(double));
02063 memcpy(columnLowerWork_,columnLower_,numberColumns_*sizeof(double));
02064 memcpy(columnUpperWork_,columnUpper_,numberColumns_*sizeof(double));
02065
02066 for (i=0;i<numberColumns_;i++) {
02067 if (columnLowerWork_[i]<-1.0e30)
02068 columnLowerWork_[i] = -COIN_DBL_MAX;
02069 if (columnUpperWork_[i]>1.0e30)
02070 columnUpperWork_[i] = COIN_DBL_MAX;
02071 }
02072
02073 for (i=0;i<numberRows_;i++) {
02074 if (rowLowerWork_[i]<-1.0e30)
02075 rowLowerWork_[i] = -COIN_DBL_MAX;
02076 if (rowUpperWork_[i]>1.0e30)
02077 rowUpperWork_[i] = COIN_DBL_MAX;
02078 }
02079 }
02080
02081 if (scalingFlag_>0&&!rowScale_) {
02082 if (matrix_->scale(this))
02083 scalingFlag_=-scalingFlag_;
02084 }
02085 if ((what&4)!=0) {
02086 double direction = optimizationDirection_;
02087
02088 if (direction)
02089 direction = 1.0/direction;
02090
02091
02092 if (!rowScale_) {
02093 if (direction!=1.0) {
02094 for (i=0;i<numberRows_;i++)
02095 rowObjectiveWork_[i] *= direction;
02096 for (i=0;i<numberColumns_;i++)
02097 objectiveWork_[i] *= direction;
02098 }
02099 } else {
02100 for (i=0;i<numberRows_;i++)
02101 rowObjectiveWork_[i] *= direction/rowScale_[i];
02102 for (i=0;i<numberColumns_;i++)
02103 objectiveWork_[i] *= direction*columnScale_[i];
02104 }
02105 }
02106 if ((what&(1+32))!=0&&rowScale_) {
02107 for (i=0;i<numberColumns_;i++) {
02108 double multiplier = 1.0/columnScale_[i];
02109 if (columnLowerWork_[i]>-1.0e50)
02110 columnLowerWork_[i] *= multiplier;
02111 if (columnUpperWork_[i]<1.0e50)
02112 columnUpperWork_[i] *= multiplier;
02113
02114 }
02115 for (i=0;i<numberRows_;i++) {
02116 if (rowLowerWork_[i]>-1.0e50)
02117 rowLowerWork_[i] *= rowScale_[i];
02118 if (rowUpperWork_[i]<1.0e50)
02119 rowUpperWork_[i] *= rowScale_[i];
02120 }
02121 }
02122 if ((what&(8+32))!=0&&rowScale_) {
02123
02124 for (i=0;i<numberColumns_;i++) {
02125 columnActivityWork_[i] /= columnScale_[i];
02126 reducedCostWork_[i] *= columnScale_[i];
02127 }
02128 for (i=0;i<numberRows_;i++) {
02129 rowActivityWork_[i] *= rowScale_[i];
02130 dual_[i] /= rowScale_[i];
02131 rowReducedCost_[i] = dual_[i];
02132 }
02133 }
02134
02135 if ((what&16)!=0) {
02136
02137 if (!sanityCheck())
02138 goodMatrix=false;
02139 }
02140
02141
02142 if ((what&8)!=0&&!pivotVariable_) {
02143 pivotVariable_=new int[numberRows_];
02144 }
02145
02146 if ((what&16)!=0&&!rowArray_[2]) {
02147
02148 int iRow,iColumn;
02149
02150
02151
02152
02153 for (iRow=0;iRow<4;iRow++) {
02154 if (!rowArray_[iRow]) {
02155 rowArray_[iRow]=new CoinIndexedVector();
02156 int length =numberRows_+factorization_->maximumPivots();
02157 if (iRow==3)
02158 length += numberColumns_;
02159 rowArray_[iRow]->reserve(length);
02160 }
02161 }
02162
02163 for (iColumn=0;iColumn<2;iColumn++) {
02164 if (!columnArray_[iColumn]) {
02165 columnArray_[iColumn]=new CoinIndexedVector();
02166 if (!iColumn)
02167 columnArray_[iColumn]->reserve(numberColumns_);
02168 else
02169 columnArray_[iColumn]->reserve(max(numberRows_,numberColumns_));
02170 }
02171 }
02172 }
02173 double primalTolerance=dblParam_[ClpPrimalTolerance];
02174 if ((what&1)!=0) {
02175
02176 for (i=0;i<numberColumns_;i++) {
02177 if (columnUpperWork_[i]-columnLowerWork_[i]<=primalTolerance) {
02178 if (columnLowerWork_[i]>=0.0) {
02179 columnUpperWork_[i] = columnLowerWork_[i];
02180 } else if (columnUpperWork_[i]<=0.0) {
02181 columnLowerWork_[i] = columnUpperWork_[i];
02182 } else {
02183 columnUpperWork_[i] = 0.0;
02184 columnLowerWork_[i] = 0.0;
02185 }
02186 }
02187 }
02188 for (i=0;i<numberRows_;i++) {
02189 if (rowUpperWork_[i]-rowLowerWork_[i]<=primalTolerance) {
02190 if (rowLowerWork_[i]>=0.0) {
02191 rowUpperWork_[i] = rowLowerWork_[i];
02192 } else if (rowUpperWork_[i]<=0.0) {
02193 rowLowerWork_[i] = rowUpperWork_[i];
02194 } else {
02195 rowUpperWork_[i] = 0.0;
02196 rowLowerWork_[i] = 0.0;
02197 }
02198 }
02199 }
02200 }
02201 if (problemStatus_==10) {
02202 problemStatus_=-1;
02203 handler_->setLogLevel(saveLevel);
02204 }
02205 return goodMatrix;
02206 }
02207 void
02208 ClpSimplex::deleteRim(int getRidOfFactorizationData)
02209 {
02210 int i;
02211 if (problemStatus_!=1&&problemStatus_!=2) {
02212 delete [] ray_;
02213 ray_=NULL;
02214 }
02215
02216 if (rowScale_) {
02217
02218 int numberPrimalScaled=0;
02219 int numberPrimalUnscaled=0;
02220 int numberDualScaled=0;
02221 int numberDualUnscaled=0;
02222 for (i=0;i<numberColumns_;i++) {
02223 double scaleFactor = columnScale_[i];
02224 double valueScaled = columnActivityWork_[i];
02225 if (valueScaled<columnLowerWork_[i]-primalTolerance_)
02226 numberPrimalScaled++;
02227 else if (valueScaled>columnUpperWork_[i]+primalTolerance_)
02228 numberPrimalScaled++;
02229 columnActivity_[i] = valueScaled*scaleFactor;
02230 double value = columnActivity_[i];
02231 if (value<columnLower_[i]-primalTolerance_)
02232 numberPrimalUnscaled++;
02233 else if (value>columnUpper_[i]+primalTolerance_)
02234 numberPrimalUnscaled++;
02235 double valueScaledDual = reducedCostWork_[i];
02236 if (valueScaled>columnLowerWork_[i]+primalTolerance_&&valueScaledDual>dualTolerance_)
02237 numberDualScaled++;
02238 if (valueScaled<columnUpperWork_[i]-primalTolerance_&&valueScaledDual<-dualTolerance_)
02239 numberDualScaled++;
02240 reducedCost_[i] = valueScaledDual/scaleFactor;
02241 double valueDual = reducedCost_[i];
02242 if (value>columnLower_[i]+primalTolerance_&&valueDual>dualTolerance_)
02243 numberDualUnscaled++;
02244 if (value<columnUpper_[i]-primalTolerance_&&valueDual<-dualTolerance_)
02245 numberDualUnscaled++;
02246 }
02247 for (i=0;i<numberRows_;i++) {
02248 double scaleFactor = rowScale_[i];
02249 double valueScaled = rowActivityWork_[i];
02250 if (valueScaled<rowLowerWork_[i]-primalTolerance_)
02251 numberPrimalScaled++;
02252 else if (valueScaled>rowUpperWork_[i]+primalTolerance_)
02253 numberPrimalScaled++;
02254 rowActivity_[i] = valueScaled/scaleFactor;
02255 double value = rowActivity_[i];
02256 if (value<rowLower_[i]-primalTolerance_)
02257 numberPrimalUnscaled++;
02258 else if (value>rowUpper_[i]+primalTolerance_)
02259 numberPrimalUnscaled++;
02260 double valueScaledDual = dual_[i]+rowObjectiveWork_[i];;
02261 if (valueScaled>rowLowerWork_[i]+primalTolerance_&&valueScaledDual>dualTolerance_)
02262 numberDualScaled++;
02263 if (valueScaled<rowUpperWork_[i]-primalTolerance_&&valueScaledDual<-dualTolerance_)
02264 numberDualScaled++;
02265 dual_[i] = valueScaledDual*scaleFactor;
02266 double valueDual = dual_[i];
02267 if (rowObjective_)
02268 valueDual += rowObjective_[i];
02269 if (value>rowLower_[i]+primalTolerance_&&valueDual>dualTolerance_)
02270 numberDualUnscaled++;
02271 if (value<rowUpper_[i]-primalTolerance_&&valueDual<-dualTolerance_)
02272 numberDualUnscaled++;
02273 }
02274 if (!problemStatus_&&!secondaryStatus_) {
02275
02276 if (numberPrimalUnscaled) {
02277 if (numberDualUnscaled)
02278 secondaryStatus_=4;
02279 else
02280 secondaryStatus_=2;
02281 } else {
02282 if (numberDualUnscaled)
02283 secondaryStatus_=3;
02284 }
02285 }
02286 if (problemStatus_==2) {
02287 for (i=0;i<numberColumns_;i++) {
02288 ray_[i] *= columnScale_[i];
02289 }
02290 } else if (problemStatus_==1&&ray_) {
02291 for (i=0;i<numberRows_;i++) {
02292 ray_[i] *= rowScale_[i];
02293 }
02294 }
02295 } else {
02296 for (i=0;i<numberColumns_;i++) {
02297 columnActivity_[i] = columnActivityWork_[i];
02298 reducedCost_[i] = reducedCostWork_[i];
02299 }
02300 for (i=0;i<numberRows_;i++) {
02301 rowActivity_[i] = rowActivityWork_[i];
02302 }
02303 }
02304 if (optimizationDirection_!=1.0) {
02305
02306 for (i=0;i<numberColumns_;i++)
02307 reducedCost_[i] *= optimizationDirection_;
02308 for (i=0;i<numberRows_;i++)
02309 dual_[i] *= optimizationDirection_;
02310 }
02311
02312 scalingFlag_ = abs(scalingFlag_);
02313 if(getRidOfFactorizationData>=0)
02314 gutsOfDelete(getRidOfFactorizationData+1);
02315 }
02316 void
02317 ClpSimplex::setDualBound(double value)
02318 {
02319 if (value>0.0)
02320 dualBound_=value;
02321 }
02322 void
02323 ClpSimplex::setInfeasibilityCost(double value)
02324 {
02325 if (value>0.0)
02326 infeasibilityCost_=value;
02327 }
02328 void ClpSimplex::setNumberRefinements( int value)
02329 {
02330 if (value>=0&&value<10)
02331 numberRefinements_=value;
02332 }
02333
02334 void
02335 ClpSimplex::setDualRowPivotAlgorithm(ClpDualRowPivot & choice)
02336 {
02337 delete dualRowPivot_;
02338 dualRowPivot_ = choice.clone(true);
02339 }
02340
02341 void
02342 ClpSimplex::setPrimalColumnPivotAlgorithm(ClpPrimalColumnPivot & choice)
02343 {
02344 delete primalColumnPivot_;
02345 primalColumnPivot_ = choice.clone(true);
02346 }
02347
02348 void
02349 ClpSimplex::scaling(int mode)
02350 {
02351 if (mode>0&&mode<4) {
02352 scalingFlag_=mode;
02353 } else if (!mode) {
02354 scalingFlag_=0;
02355 delete [] rowScale_;
02356 rowScale_ = NULL;
02357 delete [] columnScale_;
02358 columnScale_ = NULL;
02359 }
02360 }
02361
02362 void
02363 ClpSimplex::setFactorization( ClpFactorization & factorization)
02364 {
02365 delete factorization_;
02366 factorization_= new ClpFactorization(factorization);
02367 }
02368 void
02369 ClpSimplex::times(double scalar,
02370 const double * x, double * y) const
02371 {
02372 if (rowScale_)
02373 matrix_->times(scalar,x,y,rowScale_,columnScale_);
02374 else
02375 matrix_->times(scalar,x,y);
02376 }
02377 void
02378 ClpSimplex::transposeTimes(double scalar,
02379 const double * x, double * y) const
02380 {
02381 if (rowScale_)
02382 matrix_->transposeTimes(scalar,x,y,rowScale_,columnScale_);
02383 else
02384 matrix_->transposeTimes(scalar,x,y);
02385 }
02386
02387
02388
02389
02390
02391
02392
02393 void
02394 ClpSimplex::setPerturbation(int value)
02395 {
02396 if(value<=100&&value >=-1000) {
02397 perturbation_=value;
02398 }
02399 }
02400
02401 bool
02402 ClpSimplex::sparseFactorization() const
02403 {
02404 return factorization_->sparseThreshold()!=0;
02405 }
02406 void
02407 ClpSimplex::setSparseFactorization(bool value)
02408 {
02409 if (value) {
02410 if (!factorization_->sparseThreshold())
02411 factorization_->goSparse();
02412 } else {
02413 factorization_->sparseThreshold(0);
02414 }
02415 }
02416 void checkCorrect(ClpSimplex * model,int iRow,
02417 const double * element,const int * rowStart,const int * rowLength,
02418 const int * column,
02419 const double * columnLower_, const double * columnUpper_,
02420 int infiniteUpperC,
02421 int infiniteLowerC,
02422 double &maximumUpC,
02423 double &maximumDownC)
02424 {
02425 int infiniteUpper = 0;
02426 int infiniteLower = 0;
02427 double maximumUp = 0.0;
02428 double maximumDown = 0.0;
02429 CoinBigIndex rStart = rowStart[iRow];
02430 CoinBigIndex rEnd = rowStart[iRow]+rowLength[iRow];
02431 CoinBigIndex j;
02432 double large=1.0e15;
02433 int iColumn;
02434
02435
02436 for (j = rStart; j < rEnd; ++j) {
02437 double value=element[j];
02438 iColumn = column[j];
02439 if (value > 0.0) {
02440 if (columnUpper_[iColumn] >= large) {
02441 ++infiniteUpper;
02442 } else {
02443 maximumUp += columnUpper_[iColumn] * value;
02444 }
02445 if (columnLower_[iColumn] <= -large) {
02446 ++infiniteLower;
02447 } else {
02448 maximumDown += columnLower_[iColumn] * value;
02449 }
02450 } else if (value<0.0) {
02451 if (columnUpper_[iColumn] >= large) {
02452 ++infiniteLower;
02453 } else {
02454 maximumDown += columnUpper_[iColumn] * value;
02455 }
02456 if (columnLower_[iColumn] <= -large) {
02457 ++infiniteUpper;
02458 } else {
02459 maximumUp += columnLower_[iColumn] * value;
02460 }
02461 }
02462 }
02463 assert (infiniteLowerC==infiniteLower);
02464 assert (infiniteUpperC==infiniteUpper);
02465 if (fabs(maximumUp-maximumUpC)>1.0e-12*max(fabs(maximumUp),fabs(maximumUpC)))
02466 printf("row %d comp up %g, true up %g\n",iRow,
02467 maximumUpC,maximumUp);
02468 if (fabs(maximumDown-maximumDownC)>1.0e-12*max(fabs(maximumDown),fabs(maximumDownC)))
02469 printf("row %d comp down %g, true down %g\n",iRow,
02470 maximumDownC,maximumDown);
02471 maximumUpC=maximumUp;
02472 maximumDownC=maximumDown;
02473 }
02474
02475
02476
02477
02478
02479
02480
02481
02482
02483
02484 int
02485 ClpSimplex::tightenPrimalBounds(double factor)
02486 {
02487
02488
02489 CoinPackedMatrix copy;
02490 copy.reverseOrderedCopyOf(*matrix());
02491
02492 const int * column = copy.getIndices();
02493 const CoinBigIndex * rowStart = copy.getVectorStarts();
02494 const int * rowLength = copy.getVectorLengths();
02495 const double * element = copy.getElements();
02496 int numberChanged=1,iPass=0;
02497 double large = largeValue();
02498 #ifndef NDEBUG
02499 double large2= 1.0e10*large;
02500 #endif
02501 int numberInfeasible=0;
02502 int totalTightened = 0;
02503
02504 double tolerance = primalTolerance();
02505
02506
02507
02508 double * saveLower = new double [numberColumns_];
02509 memcpy(saveLower,columnLower_,numberColumns_*sizeof(double));
02510 double * saveUpper = new double [numberColumns_];
02511 memcpy(saveUpper,columnUpper_,numberColumns_*sizeof(double));
02512
02513 int iRow, iColumn;
02514
02515
02516 if (factor) {
02517 assert (factor>1.0);
02518 double largest=0.0;
02519 for (iColumn=0;iColumn<numberColumns_;iColumn++) {
02520 if (columnUpper_[iColumn]-columnLower_[iColumn]>tolerance) {
02521 largest = max(largest,fabs(columnActivity_[iColumn]));
02522 }
02523 }
02524 largest *= factor;
02525 for (iColumn=0;iColumn<numberColumns_;iColumn++) {
02526 if (columnUpper_[iColumn]-columnLower_[iColumn]>tolerance) {
02527 columnUpper_[iColumn] = min(columnUpper_[iColumn],largest);
02528 columnLower_[iColumn] = max(columnLower_[iColumn],-largest);
02529 }
02530 }
02531 }
02532 #define MAXPASS 10
02533
02534
02535
02536
02537 int numberCheck=-1;
02538 while(numberChanged>numberCheck) {
02539
02540 numberChanged = 0;
02541
02542 if (iPass==MAXPASS) break;
02543 iPass++;
02544
02545 for (iRow = 0; iRow < numberRows_; iRow++) {
02546
02547 if (rowLower_[iRow]>-large||rowUpper_[iRow]<large) {
02548
02549
02550 int infiniteUpper = 0;
02551 int infiniteLower = 0;
02552 double maximumUp = 0.0;
02553 double maximumDown = 0.0;
02554 double newBound;
02555 CoinBigIndex rStart = rowStart[iRow];
02556 CoinBigIndex rEnd = rowStart[iRow]+rowLength[iRow];
02557 CoinBigIndex j;
02558
02559
02560 for (j = rStart; j < rEnd; ++j) {
02561 double value=element[j];
02562 iColumn = column[j];
02563 if (value > 0.0) {
02564 if (columnUpper_[iColumn] >= large) {
02565 ++infiniteUpper;
02566 } else {
02567 maximumUp += columnUpper_[iColumn] * value;
02568 }
02569 if (columnLower_[iColumn] <= -large) {
02570 ++infiniteLower;
02571 } else {
02572 maximumDown += columnLower_[iColumn] * value;
02573 }
02574 } else if (value<0.0) {
02575 if (columnUpper_[iColumn] >= large) {
02576 ++infiniteLower;
02577 } else {
02578 maximumDown += columnUpper_[iColumn] * value;
02579 }
02580 if (columnLower_[iColumn] <= -large) {
02581 ++infiniteUpper;
02582 } else {
02583 maximumUp += columnLower_[iColumn] * value;
02584 }
02585 }
02586 }
02587
02588 maximumUp += 1.0e-8*fabs(maximumUp);
02589 maximumDown -= 1.0e-8*fabs(maximumDown);
02590 double maxUp = maximumUp+infiniteUpper*1.0e31;
02591 double maxDown = maximumDown-infiniteLower*1.0e31;
02592 if (maxUp <= rowUpper_[iRow] + tolerance &&
02593 maxDown >= rowLower_[iRow] - tolerance) {
02594
02595
02596
02597
02598
02599
02600
02601 } else {
02602 if (maxUp < rowLower_[iRow] -100.0*tolerance ||
02603 maxDown > rowUpper_[iRow]+100.0*tolerance) {
02604
02605 numberInfeasible++;
02606 break;
02607 }
02608 double lower = rowLower_[iRow];
02609 double upper = rowUpper_[iRow];
02610 for (j = rStart; j < rEnd; ++j) {
02611 double value=element[j];
02612 iColumn = column[j];
02613 double nowLower = columnLower_[iColumn];
02614 double nowUpper = columnUpper_[iColumn];
02615 if (value > 0.0) {
02616
02617 if (lower>-large) {
02618 if (!infiniteUpper) {
02619 assert(nowUpper < large2);
02620 newBound = nowUpper +
02621 (lower - maximumUp) / value;
02622
02623 if (fabs(maximumUp)>1.0e8)
02624 newBound -= 1.0e-12*fabs(maximumUp);
02625 } else if (infiniteUpper==1&&nowUpper>large) {
02626 newBound = (lower -maximumUp) / value;
02627
02628 if (fabs(maximumUp)>1.0e8)
02629 newBound -= 1.0e-12*fabs(maximumUp);
02630 } else {
02631 newBound = -COIN_DBL_MAX;
02632 }
02633 if (newBound > nowLower + 1.0e-12&&newBound>-large) {
02634
02635 columnLower_[iColumn] = newBound;
02636 numberChanged++;
02637
02638 if (nowUpper - newBound <
02639 -100.0*tolerance) {
02640 numberInfeasible++;
02641 }
02642
02643 double now;
02644 if (nowLower<-large) {
02645 now=0.0;
02646 infiniteLower--;
02647 } else {
02648 now = nowLower;
02649 }
02650 maximumDown += (newBound-now) * value;
02651 nowLower = newBound;
02652 #ifdef DEBUG
02653 checkCorrect(this,iRow,
02654 element, rowStart, rowLength,
02655 column,
02656 columnLower_, columnUpper_,
02657 infiniteUpper,
02658 infiniteLower,
02659 maximumUp,
02660 maximumDown);
02661 #endif
02662 }
02663 }
02664 if (upper <large) {
02665 if (!infiniteLower) {
02666 assert(nowLower >- large2);
02667 newBound = nowLower +
02668 (upper - maximumDown) / value;
02669
02670 if (fabs(maximumDown)>1.0e8)
02671 newBound += 1.0e-12*fabs(maximumDown);
02672 } else if (infiniteLower==1&&nowLower<-large) {
02673 newBound = (upper - maximumDown) / value;
02674
02675 if (fabs(maximumDown)>1.0e8)
02676 newBound += 1.0e-12*fabs(maximumDown);
02677 } else {
02678 newBound = COIN_DBL_MAX;
02679 }
02680 if (newBound < nowUpper - 1.0e-12&&newBound<large) {
02681
02682 columnUpper_[iColumn] = newBound;
02683 numberChanged++;
02684
02685 if (newBound - nowLower <
02686 -100.0*tolerance) {
02687 numberInfeasible++;
02688 }
02689
02690 double now;
02691 if (nowUpper>large) {
02692 now=0.0;
02693 infiniteUpper--;
02694 } else {
02695 now = nowUpper;
02696 }
02697 maximumUp += (newBound-now) * value;
02698 nowUpper = newBound;
02699 #ifdef DEBUG
02700 checkCorrect(this,iRow,
02701 element, rowStart, rowLength,
02702 column,
02703 columnLower_, columnUpper_,
02704 infiniteUpper,
02705 infiniteLower,
02706 maximumUp,
02707 maximumDown);
02708 #endif
02709 }
02710 }
02711 } else {
02712
02713 if (lower>-large) {
02714 if (!infiniteUpper) {
02715 assert(nowLower < large2);
02716 newBound = nowLower +
02717 (lower - maximumUp) / value;
02718
02719 if (fabs(maximumUp)>1.0e8)
02720 newBound += 1.0e-12*fabs(maximumUp);
02721 } else if (infiniteUpper==1&&nowLower<-large) {
02722 newBound = (lower -maximumUp) / value;
02723
02724 if (fabs(maximumUp)>1.0e8)
02725 newBound += 1.0e-12*fabs(maximumUp);
02726 } else {
02727 newBound = COIN_DBL_MAX;
02728 }
02729 if (newBound < nowUpper - 1.0e-12&&newBound<large) {
02730
02731 columnUpper_[iColumn] = newBound;
02732 numberChanged++;
02733
02734 if (newBound - nowLower <
02735 -100.0*tolerance) {
02736 numberInfeasible++;
02737 }
02738
02739 double now;
02740 if (nowUpper>large) {
02741 now=0.0;
02742 infiniteLower--;
02743 } else {
02744 now = nowUpper;
02745 }
02746 maximumDown += (newBound-now) * value;
02747 nowUpper = newBound;
02748 #ifdef DEBUG
02749 checkCorrect(this,iRow,
02750 element, rowStart, rowLength,
02751 column,
02752 columnLower_, columnUpper_,
02753 infiniteUpper,
02754 infiniteLower,
02755 maximumUp,
02756 maximumDown);
02757 #endif
02758 }
02759 }
02760 if (upper <large) {
02761 if (!infiniteLower) {
02762 assert(nowUpper < large2);
02763 newBound = nowUpper +
02764 (upper - maximumDown) / value;
02765
02766 if (fabs(maximumDown)>1.0e8)
02767 newBound -= 1.0e-12*fabs(maximumDown);
02768 } else if (infiniteLower==1&&nowUpper>large) {
02769 newBound = (upper - maximumDown) / value;
02770
02771 if (fabs(maximumDown)>1.0e8)
02772 newBound -= 1.0e-12*fabs(maximumDown);
02773 } else {
02774 newBound = -COIN_DBL_MAX;
02775 }
02776 if (newBound > nowLower + 1.0e-12&&newBound>-large) {
02777
02778 columnLower_[iColumn] = newBound;
02779 numberChanged++;
02780
02781 if (nowUpper - newBound <
02782 -100.0*tolerance) {
02783 numberInfeasible++;
02784 }
02785
02786 double now;
02787 if (nowLower<-large) {
02788 now=0.0;
02789 infiniteUpper--;
02790 } else {
02791 now = nowLower;
02792 }
02793 maximumUp += (newBound-now) * value;
02794 nowLower = newBound;
02795 #ifdef DEBUG
02796 checkCorrect(this,iRow,
02797 element, rowStart, rowLength,
02798 column,
02799 columnLower_, columnUpper_,
02800 infiniteUpper,
02801 infiniteLower,
02802 maximumUp,
02803 maximumDown);
02804 #endif
02805 }
02806 }
02807 }
02808 }
02809 }
02810 }
02811 }
02812 totalTightened += numberChanged;
02813 if (iPass==1)
02814 numberCheck=numberChanged>>4;
02815 if (numberInfeasible) break;
02816 }
02817 if (!numberInfeasible) {
02818 handler_->message(CLP_SIMPLEX_BOUNDTIGHTEN,messages_)
02819 <<totalTightened
02820 <<CoinMessageEol;
02821
02822 double useTolerance = 1.0e-3;
02823 for (iColumn=0;iColumn<numberColumns_;iColumn++) {
02824 if (saveUpper[iColumn]>saveLower[iColumn]+useTolerance) {
02825 if (columnUpper_[iColumn]-columnLower_[iColumn]<useTolerance+1.0e8) {
02826
02827 #if 1
02828 columnLower_[iColumn]=max(saveLower[iColumn],
02829 columnLower_[iColumn]-100.0*useTolerance);
02830 columnUpper_[iColumn]=min(saveUpper[iColumn],
02831 columnUpper_[iColumn]+100.0*useTolerance);
02832 #else
02833 if (fabs(columnUpper_[iColumn])<fabs(columnLower_[iColumn])) {
02834 if (columnUpper_[iColumn]- 100.0*useTolerance>saveLower[iColumn]) {
02835 columnLower_[iColumn]=columnUpper_[iColumn]-100.0*useTolerance;
02836 } else {
02837 columnLower_[iColumn]=saveLower[iColumn];
02838 columnUpper_[iColumn]=min(saveUpper[iColumn],
02839 saveLower[iColumn]+100.0*useTolerance);
02840 }
02841 } else {
02842 if (columnLower_[iColumn]+100.0*useTolerance<saveUpper[iColumn]) {
02843 columnUpper_[iColumn]=columnLower_[iColumn]+100.0*useTolerance;
02844 } else {
02845 columnUpper_[iColumn]=saveUpper[iColumn];
02846 columnLower_[iColumn]=max(saveLower[iColumn],
02847 saveUpper[iColumn]-100.0*useTolerance);
02848 }
02849 }
02850 #endif
02851 } else {
02852 if (columnUpper_[iColumn]<saveUpper[iColumn]) {
02853
02854 columnUpper_[iColumn] = min(columnUpper_[iColumn]+100.0*useTolerance,
02855 saveUpper[iColumn]);
02856 }
02857 if (columnLower_[iColumn]>saveLower[iColumn]) {
02858
02859 columnLower_[iColumn] = max(columnLower_[iColumn]-100.0*useTolerance,
02860 saveLower[iColumn]);
02861 }
02862 }
02863 }
02864 }
02865 } else {
02866 handler_->message(CLP_SIMPLEX_INFEASIBILITIES,messages_)
02867 <<numberInfeasible
02868 <<CoinMessageEol;
02869
02870 memcpy(columnLower_,saveLower,numberColumns_*sizeof(double));
02871 memcpy(columnUpper_,saveUpper,numberColumns_*sizeof(double));
02872 }
02873 delete [] saveLower;
02874 delete [] saveUpper;
02875 return (numberInfeasible);
02876 }
02877
02878 #include "ClpSimplexDual.hpp"
02879 #include "ClpSimplexPrimal.hpp"
02880 int ClpSimplex::dual (int ifValuesPass )
02881 {
02882 assert (ifValuesPass>=0&&ifValuesPass<2);
02883 int returnCode = ((ClpSimplexDual *) this)->dual(ifValuesPass);
02884 if (problemStatus_==10) {
02885
02886 int savePerturbation = perturbation_;
02887 perturbation_=100;
02888 bool denseFactorization = initialDenseFactorization();
02889
02890 setInitialDenseFactorization(true);
02891 returnCode = ((ClpSimplexPrimal *) this)->primal(1);
02892 setInitialDenseFactorization(denseFactorization);
02893 perturbation_=savePerturbation;
02894 if (problemStatus_==10)
02895 problemStatus_=0;
02896 }
02897 return returnCode;
02898 }
02899
02900 int ClpSimplex::primal (int ifValuesPass )
02901 {
02902 assert (ifValuesPass>=0&&ifValuesPass<2);
02903 int returnCode = ((ClpSimplexPrimal *) this)->primal(ifValuesPass);
02904 if (problemStatus_==10) {
02905
02906 int savePerturbation = perturbation_;
02907 perturbation_=100;
02908 bool denseFactorization = initialDenseFactorization();
02909
02910 setInitialDenseFactorization(true);
02911 returnCode = ((ClpSimplexDual *) this)->dual(0);
02912 setInitialDenseFactorization(denseFactorization);
02913 perturbation_=savePerturbation;
02914 if (problemStatus_==10)
02915 problemStatus_=0;
02916 }
02917 return returnCode;
02918 }
02919 #include "ClpSimplexPrimalQuadratic.hpp"
02920
02921
02922
02923 int
02924 ClpSimplex::quadraticSLP(int numberPasses, double deltaTolerance)
02925 {
02926 return ((ClpSimplexPrimalQuadratic *) this)->primalSLP(numberPasses,deltaTolerance);
02927 }
02928
02929 int
02930 ClpSimplex::quadraticPrimal(int phase)
02931 {
02932 return ((ClpSimplexPrimalQuadratic *) this)->primalQuadratic(phase);
02933 }
02934
02935
02936
02937
02938
02939 int ClpSimplex::strongBranching(int numberVariables,const int * variables,
02940 double * newLower, double * newUpper,
02941 double ** outputSolution,
02942 int * outputStatus, int * outputIterations,
02943 bool stopOnFirstInfeasible,
02944 bool alwaysFinish)
02945 {
02946 return ((ClpSimplexDual *) this)->strongBranching(numberVariables,variables,
02947 newLower, newUpper,outputSolution,
02948 outputStatus, outputIterations,
02949 stopOnFirstInfeasible,
02950 alwaysFinish);
02951 }
02952
02953
02954
02955
02956 void
02957 ClpSimplex::borrowModel(ClpModel & otherModel)
02958 {
02959 ClpModel::borrowModel(otherModel);
02960 createStatus();
02961 ClpDualRowSteepest steep1;
02962 setDualRowPivotAlgorithm(steep1);
02963 ClpPrimalColumnSteepest steep2;
02964 setPrimalColumnPivotAlgorithm(steep2);
02965 }
02966 typedef struct {
02967 double optimizationDirection;
02968 double dblParam[ClpLastDblParam];
02969 double objectiveValue;
02970 double dualBound;
02971 double dualTolerance;
02972 double primalTolerance;
02973 double sumDualInfeasibilities;
02974 double sumPrimalInfeasibilities;
02975 double infeasibilityCost;
02976 int numberRows;
02977 int numberColumns;
02978 int intParam[ClpLastIntParam];
02979 int numberIterations;
02980 int problemStatus;
02981 int maximumIterations;
02982 int lengthNames;
02983 int numberDualInfeasibilities;
02984 int numberDualInfeasibilitiesWithoutFree;
02985 int numberPrimalInfeasibilities;
02986 int numberRefinements;
02987 int scalingFlag;
02988 int algorithm;
02989 unsigned int specialOptions;
02990 int dualPivotChoice;
02991 int primalPivotChoice;
02992 int matrixStorageChoice;
02993 } Clp_scalars;
02994
02995 int outDoubleArray(double * array, int length, FILE * fp)
02996 {
02997 int numberWritten;
02998 if (array&&length) {
02999 numberWritten = fwrite(&length,sizeof(int),1,fp);
03000 if (numberWritten!=1)
03001 return 1;
03002 numberWritten = fwrite(array,sizeof(double),length,fp);
03003 if (numberWritten!=length)
03004 return 1;
03005 } else {
03006 length = 0;
03007 numberWritten = fwrite(&length,sizeof(int),1,fp);
03008 if (numberWritten!=1)
03009 return 1;
03010 }
03011 return 0;
03012 }
03013
03014 int
03015 ClpSimplex::saveModel(const char * fileName)
03016 {
03017 FILE * fp = fopen(fileName,"wb");
03018 if (fp) {
03019 Clp_scalars scalars;
03020 int i;
03021 CoinBigIndex numberWritten;
03022
03023 scalars.optimizationDirection = optimizationDirection_;
03024 memcpy(scalars.dblParam, dblParam_,ClpLastDblParam * sizeof(double));
03025 scalars.objectiveValue = objectiveValue_;
03026 scalars.dualBound = dualBound_;
03027 scalars.dualTolerance = dualTolerance_;
03028 scalars.primalTolerance = primalTolerance_;
03029 scalars.sumDualInfeasibilities = sumDualInfeasibilities_;
03030 scalars.sumPrimalInfeasibilities = sumPrimalInfeasibilities_;
03031 scalars.infeasibilityCost = infeasibilityCost_;
03032 scalars.numberRows = numberRows_;
03033 scalars.numberColumns = numberColumns_;
03034 memcpy(scalars.intParam, intParam_,ClpLastIntParam * sizeof(double));
03035 scalars.numberIterations = numberIterations_;
03036 scalars.problemStatus = problemStatus_;
03037 scalars.maximumIterations = maximumIterations();
03038 scalars.lengthNames = lengthNames_;
03039 scalars.numberDualInfeasibilities = numberDualInfeasibilities_;
03040 scalars.numberDualInfeasibilitiesWithoutFree
03041 = numberDualInfeasibilitiesWithoutFree_;
03042 scalars.numberPrimalInfeasibilities = numberPrimalInfeasibilities_;
03043 scalars.numberRefinements = numberRefinements_;
03044 scalars.scalingFlag = scalingFlag_;
03045 scalars.algorithm = algorithm_;
03046 scalars.specialOptions = specialOptions_;
03047 scalars.dualPivotChoice = dualRowPivot_->type();
03048 scalars.primalPivotChoice = primalColumnPivot_->type();
03049 scalars.matrixStorageChoice = matrix_->type();
03050
03051
03052 numberWritten = fwrite(&scalars,sizeof(Clp_scalars),1,fp);
03053 if (numberWritten!=1)
03054 return 1;
03055
03056 CoinBigIndex length;
03057 for (i=0;i<ClpLastStrParam;i++) {
03058 length = strParam_[i].size();
03059 numberWritten = fwrite(&length,sizeof(int),1,fp);
03060 if (numberWritten!=1)
03061 return 1;
03062 if (length) {
03063 numberWritten = fwrite(strParam_[i].c_str(),length,1,fp);
03064 if (numberWritten!=1)
03065 return 1;
03066 }
03067 }
03068
03069 if (outDoubleArray(rowActivity_,numberRows_,fp))
03070 return 1;
03071 if (outDoubleArray(columnActivity_,numberColumns_,fp))
03072 return 1;
03073 if (outDoubleArray(dual_,numberRows_,fp))
03074 return 1;
03075 if (outDoubleArray(reducedCost_,numberColumns_,fp))
03076 return 1;
03077 if (outDoubleArray(rowLower_,numberRows_,fp))
03078 return 1;
03079 if (outDoubleArray(rowUpper_,numberRows_,fp))
03080 return 1;
03081 if (outDoubleArray(objective(),numberColumns_,fp))
03082 return 1;
03083 if (outDoubleArray(rowObjective_,numberRows_,fp))
03084 return 1;
03085 if (outDoubleArray(columnLower_,numberColumns_,fp))
03086 return 1;
03087 if (outDoubleArray(columnUpper_,numberColumns_,fp))
03088 return 1;
03089 if (ray_) {
03090 if (problemStatus_==1)
03091 if (outDoubleArray(ray_,numberRows_,fp))
03092 return 1;
03093 else if (problemStatus_==2)
03094 if (outDoubleArray(ray_,numberColumns_,fp))
03095 return 1;
03096 else
03097 if (outDoubleArray(NULL,0,fp))
03098 return 1;
03099 } else {
03100 if (outDoubleArray(NULL,0,fp))
03101 return 1;
03102 }
03103 if (status_&&(numberRows_+numberColumns_)>0) {
03104 length = numberRows_+numberColumns_;
03105 numberWritten = fwrite(&length,sizeof(int),1,fp);
03106 if (numberWritten!=1)
03107 return 1;
03108 numberWritten = fwrite(status_,sizeof(char),length, fp);
03109 if (numberWritten!=length)
03110 return 1;
03111 } else {
03112 length = 0;
03113 numberWritten = fwrite(&length,sizeof(int),1,fp);
03114 if (numberWritten!=1)
03115 return 1;
03116 }
03117 if (lengthNames_) {
03118 char * array =
03119 new char[max(numberRows_,numberColumns_)*(lengthNames_+1)];
03120 char * put = array;
03121 assert (numberRows_ == (int) rowNames_.size());
03122 for (i=0;i<numberRows_;i++) {
03123 assert((int)rowNames_[i].size()<=lengthNames_);
03124 strcpy(put,rowNames_[i].c_str());
03125 put += lengthNames_+1;
03126 }
03127 numberWritten = fwrite(array,lengthNames_+1,numberRows_,fp);
03128 if (numberWritten!=numberRows_)
03129 return 1;
03130 put=array;
03131 assert (numberColumns_ == (int) columnNames_.size());
03132 for (i=0;i<numberColumns_;i++) {
03133 assert((int) columnNames_[i].size()<=lengthNames_);
03134 strcpy(put,columnNames_[i].c_str());
03135 put += lengthNames_+1;
03136 }
03137 numberWritten = fwrite(array,lengthNames_+1,numberColumns_,fp);
03138 if (numberWritten!=numberColumns_)
03139 return 1;
03140 delete [] array;
03141 }
03142
03143 assert (matrix_->type()==1);
03144 assert (matrix_->getNumCols() == numberColumns_);
03145 assert (matrix_->getNumRows() == numberRows_);
03146
03147 length = matrix_->getVectorStarts()[numberColumns_-1]
03148 + matrix_->getVectorLengths()[numberColumns_-1];
03149 numberWritten = fwrite(&length,sizeof(int),1,fp);
03150 if (numberWritten!=1)
03151 return 1;
03152 numberWritten = fwrite(matrix_->getElements(),
03153 sizeof(double),length,fp);
03154 if (numberWritten!=length)
03155 return 1;
03156 numberWritten = fwrite(matrix_->getIndices(),
03157 sizeof(int),length,fp);
03158 if (numberWritten!=length)
03159 return 1;
03160 numberWritten = fwrite(matrix_->getVectorStarts(),
03161 sizeof(int),numberColumns_+1,fp);
03162 if (numberWritten!=numberColumns_+1)
03163 return 1;
03164 numberWritten = fwrite(matrix_->getVectorLengths(),
03165 sizeof(int),numberColumns_,fp);
03166 if (numberWritten!=numberColumns_)
03167 return 1;
03168
03169 fclose(fp);
03170 return 0;
03171 } else {
03172 return -1;
03173 }
03174 }
03175
03176 int inDoubleArray(double * &array, int length, FILE * fp)
03177 {
03178 int numberRead;
03179 int length2;
03180 numberRead = fread(&length2,sizeof(int),1,fp);
03181 if (numberRead!=1)
03182 return 1;
03183 if (length2) {
03184
03185 if (length!=length2)
03186 return 2;
03187 array = new double[length];
03188 numberRead = fread(array,sizeof(double),length,fp);
03189 if (numberRead!=length)
03190 return 1;
03191 }
03192 return 0;
03193 }
03194
03195
03196 int
03197 ClpSimplex::restoreModel(const char * fileName)
03198 {
03199 FILE * fp = fopen(fileName,"rb");
03200 if (fp) {
03201
03202 ClpModel::gutsOfDelete();
03203 gutsOfDelete(0);
03204 int i;
03205 for (i=0;i<6;i++) {
03206 rowArray_[i]=NULL;
03207 columnArray_[i]=NULL;
03208 }
03209
03210 factorization_ = new ClpFactorization();
03211
03212 factorization_->sparseThreshold(1);
03213 Clp_scalars scalars;
03214 CoinBigIndex numberRead;
03215
03216
03217 numberRead = fread(&scalars,sizeof(Clp_scalars),1,fp);
03218 if (numberRead!=1)
03219 return 1;
03220
03221 optimizationDirection_ = scalars.optimizationDirection;
03222 memcpy(dblParam_, scalars.dblParam, ClpLastDblParam * sizeof(double));
03223 objectiveValue_ = scalars.objectiveValue;
03224 dualBound_ = scalars.dualBound;
03225 dualTolerance_ = scalars.dualTolerance;
03226 primalTolerance_ = scalars.primalTolerance;
03227 sumDualInfeasibilities_ = scalars.sumDualInfeasibilities;
03228 sumPrimalInfeasibilities_ = scalars.sumPrimalInfeasibilities;
03229 infeasibilityCost_ = scalars.infeasibilityCost;
03230 numberRows_ = scalars.numberRows;
03231 numberColumns_ = scalars.numberColumns;
03232 memcpy(intParam_, scalars.intParam,ClpLastIntParam * sizeof(double));
03233 numberIterations_ = scalars.numberIterations;
03234 problemStatus_ = scalars.problemStatus;
03235 setMaximumIterations(scalars.maximumIterations);
03236 lengthNames_ = scalars.lengthNames;
03237 numberDualInfeasibilities_ = scalars.numberDualInfeasibilities;
03238 numberDualInfeasibilitiesWithoutFree_
03239 = scalars.numberDualInfeasibilitiesWithoutFree;
03240 numberPrimalInfeasibilities_ = scalars.numberPrimalInfeasibilities;
03241 numberRefinements_ = scalars.numberRefinements;
03242 scalingFlag_ = scalars.scalingFlag;
03243 algorithm_ = scalars.algorithm;
03244 specialOptions_ = scalars.specialOptions;
03245
03246 CoinBigIndex length;
03247 for (i=0;i<ClpLastStrParam;i++) {
03248 numberRead = fread(&length,sizeof(int),1,fp);
03249 if (numberRead!=1)
03250 return 1;
03251 if (length) {
03252 char * array = new char[length+1];
03253 numberRead = fread(array,length,1,fp);
03254 if (numberRead!=1)
03255 return 1;
03256 array[length]='\0';
03257 strParam_[i]=array;
03258 delete [] array;
03259 }
03260 }
03261
03262 if (inDoubleArray(rowActivity_,numberRows_,fp))
03263 return 1;
03264 if (inDoubleArray(columnActivity_,numberColumns_,fp))
03265 return 1;
03266 if (inDoubleArray(dual_,numberRows_,fp))
03267 return 1;
03268 if (inDoubleArray(reducedCost_,numberColumns_,fp))
03269 return 1;
03270 if (inDoubleArray(rowLower_,numberRows_,fp))
03271 return 1;
03272 if (inDoubleArray(rowUpper_,numberRows_,fp))
03273 return 1;
03274 double * objective;
03275 if (inDoubleArray(objective,numberColumns_,fp))
03276 return 1;
03277 delete objective_;
03278 objective_ = new ClpLinearObjective(objective,numberColumns_);
03279 delete [] objective;
03280 if (inDoubleArray(rowObjective_,numberRows_,fp))
03281 return 1;
03282 if (inDoubleArray(columnLower_,numberColumns_,fp))
03283 return 1;
03284 if (inDoubleArray(columnUpper_,numberColumns_,fp))
03285 return 1;
03286 if (problemStatus_==1) {
03287 if (inDoubleArray(ray_,numberRows_,fp))
03288 return 1;
03289 } else if (problemStatus_==2) {
03290 if (inDoubleArray(ray_,numberColumns_,fp))
03291 return 1;
03292 } else {
03293
03294 numberRead = fread(&length,sizeof(int),1,fp);
03295 if (numberRead!=1)
03296 return 1;
03297 if (length)
03298 return 2;
03299 }
03300 delete [] status_;
03301 status_=NULL;
03302
03303 numberRead = fread(&length,sizeof(int),1,fp);
03304 if (numberRead!=1)
03305 return 1;
03306 if (length) {
03307 if (length!=numberRows_+numberColumns_)
03308 return 1;
03309 status_ = new char unsigned[length];
03310 numberRead = fread(status_,sizeof(char),length, fp);
03311 if (numberRead!=length)
03312 return 1;
03313 }
03314 if (lengthNames_) {
03315 char * array =
03316 new char[max(numberRows_,numberColumns_)*(lengthNames_+1)];
03317 char * get = array;
03318 numberRead = fread(array,lengthNames_+1,numberRows_,fp);
03319 if (numberRead!=numberRows_)
03320 return 1;
03321 rowNames_ = std::vector<std::string> ();
03322 rowNames_.resize(numberRows_);
03323 for (i=0;i<numberRows_;i++) {
03324 rowNames_.push_back(get);
03325 get += lengthNames_+1;
03326 }
03327 get = array;
03328 numberRead = fread(array,lengthNames_+1,numberColumns_,fp);
03329 if (numberRead!=numberColumns_)
03330 return 1;
03331 columnNames_ = std::vector<std::string> ();
03332 columnNames_.resize(numberColumns_);
03333 for (i=0;i<numberColumns_;i++) {
03334 columnNames_.push_back(get);
03335 get += lengthNames_+1;
03336 }
03337 delete [] array;
03338 }
03339
03340 assert(scalars.dualPivotChoice>0&&(scalars.dualPivotChoice&63)<3);
03341 delete dualRowPivot_;
03342 switch ((scalars.dualPivotChoice&63)) {
03343 default:
03344 printf("Need another dualPivot case %d\n",scalars.dualPivotChoice&63);
03345 case 1:
03346
03347 dualRowPivot_ = new ClpDualRowDantzig();
03348 break;
03349 case 2:
03350
03351 dualRowPivot_ = new ClpDualRowSteepest(scalars.dualPivotChoice>>6);
03352 break;
03353 }
03354 assert(scalars.primalPivotChoice>0&&(scalars.primalPivotChoice&63)<3);
03355 delete primalColumnPivot_;
03356 switch ((scalars.primalPivotChoice&63)) {
03357 default:
03358 printf("Need another primalPivot case %d\n",
03359 scalars.primalPivotChoice&63);
03360 case 1:
03361
03362 primalColumnPivot_ = new ClpPrimalColumnDantzig();
03363 break;
03364 case 2:
03365
03366 primalColumnPivot_
03367 = new ClpPrimalColumnSteepest(scalars.primalPivotChoice>>6);
03368 break;
03369 }
03370 assert(scalars.matrixStorageChoice==1);
03371 delete matrix_;
03372
03373 numberRead = fread(&length,sizeof(int),1,fp);
03374 if (numberRead!=1)
03375 return 1;
03376 double * elements = new double[length];
03377 int * indices = new int[length];
03378 CoinBigIndex * starts = new CoinBigIndex[numberColumns_+1];
03379 int * lengths = new int[numberColumns_];
03380 numberRead = fread(elements, sizeof(double),length,fp);
03381 if (numberRead!=length)
03382 return 1;
03383 numberRead = fread(indices, sizeof(int),length,fp);
03384 if (numberRead!=length)
03385 return 1;
03386 numberRead = fread(starts, sizeof(int),numberColumns_+1,fp);
03387 if (numberRead!=numberColumns_+1)
03388 return 1;
03389 numberRead = fread(lengths, sizeof(int),numberColumns_,fp);
03390 if (numberRead!=numberColumns_)
03391 return 1;
03392
03393 CoinPackedMatrix * matrix = new CoinPackedMatrix();
03394 matrix->assignMatrix(true, numberRows_, numberColumns_,
03395 length, elements, indices, starts, lengths);
03396
03397 matrix_ = new ClpPackedMatrix(matrix);
03398
03399 fclose(fp);
03400 return 0;
03401 } else {
03402 return -1;
03403 }
03404 return 0;
03405 }
03406
03407 double
03408 ClpSimplex::valueIncomingDual() const
03409 {
03410
03411 double valueIncoming = (dualOut_/alpha_)*directionOut_;
03412 if (directionIn_==-1)
03413 valueIncoming = upperIn_-valueIncoming;
03414 else
03415 valueIncoming = lowerIn_-valueIncoming;
03416 return valueIncoming;
03417 }
03418
03419 bool
03420 ClpSimplex::sanityCheck()
03421 {
03422
03423 if (!numberRows_||!numberColumns_||!matrix_->getNumElements()) {
03424 handler_->message(CLP_EMPTY_PROBLEM,messages_)
03425 <<numberRows_
03426 <<numberColumns_
03427 <<matrix_->getNumElements()
03428 <<CoinMessageEol;
03429 problemStatus_=4;
03430 return false;
03431 }
03432 int numberBad ;
03433 double largestBound, smallestBound, minimumGap;
03434 double smallestObj, largestObj;
03435 int firstBad;
03436 int modifiedBounds=0;
03437 int i;
03438 numberBad=0;
03439 firstBad=-1;
03440 minimumGap=1.0e100;
03441 smallestBound=1.0e100;
03442 largestBound=0.0;
03443 smallestObj=1.0e100;
03444 largestObj=0.0;
03445
03446 double fixTolerance = 10.0*primalTolerance_;
03447 for (i=numberColumns_;i<numberColumns_+numberRows_;i++) {
03448 double value;
03449 value = fabs(cost_[i]);
03450 if (value>1.0e50) {
03451 numberBad++;
03452 if (firstBad<0)
03453 firstBad=i;
03454 } else if (value) {
03455 if (value>largestObj)
03456 largestObj=value;
03457 if (value<smallestObj)
03458 smallestObj=value;
03459 }
03460 value=upper_[i]-lower_[i];
03461 if (value<-primalTolerance_) {
03462 numberBad++;
03463 if (firstBad<0)
03464 firstBad=i;
03465 } else if (value<=fixTolerance) {
03466 if (value) {
03467
03468 upper_[i] = lower_[i];
03469 modifiedBounds++;
03470 }
03471 } else {
03472 if (value<minimumGap)
03473 minimumGap=value;
03474 }
03475 if (lower_[i]>-1.0e100&&lower_[i]) {
03476 value = fabs(lower_[i]);
03477 if (value>largestBound)
03478 largestBound=value;
03479 if (value<smallestBound)
03480 smallestBound=value;
03481 }
03482 if (upper_[i]<1.0e100&&upper_[i]) {
03483 value = fabs(upper_[i]);
03484 if (value>largestBound)
03485 largestBound=value;
03486 if (value<smallestBound)
03487 smallestBound=value;
03488 }
03489 }
03490 if (largestBound)
03491 handler_->message(CLP_RIMSTATISTICS3,messages_)
03492 <<smallestBound
03493 <<largestBound
03494 <<minimumGap
03495 <<CoinMessageEol;
03496 minimumGap=1.0e100;
03497 smallestBound=1.0e100;
03498 largestBound=0.0;
03499 for (i=0;i<numberColumns_;i++) {
03500 double value;
03501 value = fabs(cost_[i]);
03502 if (value>1.0e50) {
03503 numberBad++;
03504 if (firstBad<0)
03505 firstBad=i;
03506 } else if (value) {
03507 if (value>largestObj)
03508 largestObj=value;
03509 if (value<smallestObj)
03510 smallestObj=value;
03511 }
03512 value=upper_[i]-lower_[i];
03513 if (value<-primalTolerance_) {
03514 numberBad++;
03515 if (firstBad<0)
03516 firstBad=i;
03517 } else if (value<=fixTolerance) {
03518 if (value) {
03519
03520 upper_[i] = lower_[i];
03521 modifiedBounds++;
03522 }
03523 } else {
03524 if (value<minimumGap)
03525 minimumGap=value;
03526 }
03527 if (lower_[i]>-1.0e100&&lower_[i]) {
03528 value = fabs(lower_[i]);
03529 if (value>largestBound)
03530 largestBound=value;
03531 if (value<smallestBound)
03532 smallestBound=value;
03533 }
03534 if (upper_[i]<1.0e100&&upper_[i]) {
03535 value = fabs(upper_[i]);
03536 if (value>largestBound)
03537 largestBound=value;
03538 if (value<smallestBound)
03539 smallestBound=value;
03540 }
03541 }
03542 char rowcol[]={'R','C'};
03543 if (numberBad) {
03544 handler_->message(CLP_BAD_BOUNDS,messages_)
03545 <<numberBad
03546 <<rowcol[isColumn(firstBad)]<<sequenceWithin(firstBad)
03547 <<CoinMessageEol;
03548 problemStatus_=4;
03549 return false;
03550 }
03551 if (modifiedBounds)
03552 handler_->message(CLP_MODIFIEDBOUNDS,messages_)
03553 <<modifiedBounds
03554 <<CoinMessageEol;
03555 handler_->message(CLP_RIMSTATISTICS1,messages_)
03556 <<smallestObj
03557 <<largestObj
03558 <<CoinMessageEol; if (largestBound)
03559 handler_->message(CLP_RIMSTATISTICS2,messages_)
03560 <<smallestBound
03561 <<largestBound
03562 <<minimumGap
03563 <<CoinMessageEol;
03564 return true;
03565 }
03566
03567 void
03568 ClpSimplex::createStatus()
03569 {
03570 if(!status_)
03571 status_ = new unsigned char [numberColumns_+numberRows_];
03572 memset(status_,0,(numberColumns_+numberRows_)*sizeof(char));
03573 int i;
03574
03575 for (i=0;i<numberColumns_;i++) {
03576 #if 0
03577 if (columnLower_[i]>=0.0) {
03578 setColumnStatus(i,atLowerBound);
03579 } else if (columnUpper_[i]<=0.0) {
03580 setColumnStatus(i,atUpperBound);
03581 } else if (columnLower_[i]<-1.0e20&&columnUpper_[i]>1.0e20) {
03582
03583 setColumnStatus(i,isFree);
03584 } else if (fabs(columnLower_[i])<fabs(columnUpper_[i])) {
03585 setColumnStatus(i,atLowerBound);
03586 } else {
03587 setColumnStatus(i,atUpperBound);
03588 }
03589 #else
03590 setColumnStatus(i,atLowerBound);
03591 #endif
03592 }
03593 for (i=0;i<numberRows_;i++) {
03594 setRowStatus(i,basic);
03595 }
03596 }
03597
03598
03599
03600
03601
03602
03603
03604
03605
03606
03607
03608 void
03609 ClpSimplex::loadProblem ( const ClpMatrixBase& matrix,
03610 const double* collb, const double* colub,
03611 const double* obj,
03612 const double* rowlb, const double* rowub,
03613 const double * rowObjective)
03614 {
03615 ClpModel::loadProblem(matrix, collb, colub, obj, rowlb, rowub,
03616 rowObjective);
03617 createStatus();
03618 }
03619 void
03620 ClpSimplex::loadProblem ( const CoinPackedMatrix& matrix,
03621 const double* collb, const double* colub,
03622 const double* obj,
03623 const double* rowlb, const double* rowub,
03624 const double * rowObjective)
03625 {
03626 ClpModel::loadProblem(matrix, collb, colub, obj, rowlb, rowub,
03627 rowObjective);
03628 createStatus();
03629 }
03630
03631
03632
03633 void
03634 ClpSimplex::loadProblem ( const int numcols, const int numrows,
03635 const CoinBigIndex* start, const int* index,
03636 const double* value,
03637 const double* collb, const double* colub,
03638 const double* obj,
03639 const double* rowlb, const double* rowub,
03640 const double * rowObjective)
03641 {
03642 ClpModel::loadProblem(numcols, numrows, start, index, value,
03643 collb, colub, obj, rowlb, rowub,
03644 rowObjective);
03645 createStatus();
03646 }
03647 void
03648 ClpSimplex::loadProblem ( const int numcols, const int numrows,
03649 const CoinBigIndex* start, const int* index,
03650 const double* value,const int * length,
03651 const double* collb, const double* colub,
03652 const double* obj,
03653 const double* rowlb, const double* rowub,
03654 const double * rowObjective)
03655 {
03656 ClpModel::loadProblem(numcols, numrows, start, index, value, length,
03657 collb, colub, obj, rowlb, rowub,
03658 rowObjective);
03659 createStatus();
03660 }
03661
03662 int
03663 ClpSimplex::readMps(const char *filename,
03664 bool keepNames,
03665 bool ignoreErrors)
03666 {
03667 int status = ClpModel::readMps(filename,keepNames,ignoreErrors);
03668 createStatus();
03669 return status;
03670 }
03671
03672 void
03673 ClpSimplex::checkSolution()
03674 {
03675
03676 createRim(7+8+16);
03677 dualTolerance_=dblParam_[ClpDualTolerance];
03678 primalTolerance_=dblParam_[ClpPrimalTolerance];
03679 checkPrimalSolution( rowActivityWork_, columnActivityWork_);
03680 checkDualSolution();
03681 if (!numberDualInfeasibilities_&&
03682 !numberPrimalInfeasibilities_)
03683 problemStatus_=0;
03684 else
03685 problemStatus_=-1;
03686 #ifdef CLP_DEBUG
03687 int i;
03688 double value=0.0;
03689 for (i=0;i<numberRows_+numberColumns_;i++)
03690 value += dj_[i]*solution_[i];
03691 printf("dual value %g, primal %g\n",value,objectiveValue());
03692 #endif
03693
03694 deleteRim(0);
03695 }
03696
03697
03698
03699
03700
03701
03702
03703
03704
03705
03706
03707
03708
03709
03710 int
03711 ClpSimplex::crash(double gap,int pivot)
03712 {
03713 assert(!rowObjective_);
03714 int iColumn;
03715 int numberBad=0;
03716 int numberBasic=0;
03717 double dualTolerance=dblParam_[ClpDualTolerance];
03718
03719 int returnCode=0;
03720
03721 if (!status_)
03722 createStatus();
03723
03724 for (iColumn=0;iColumn<numberColumns_;iColumn++) {
03725 if (getColumnStatus(iColumn)==basic)
03726 numberBasic++;
03727 }
03728 if (!numberBasic) {
03729
03730 double * dj = new double [numberColumns_];
03731 double * solution = columnActivity_;
03732 const double * linearObjective = objective();
03733
03734 int iColumn;
03735 double direction = optimizationDirection_;
03736
03737 if (direction)
03738 direction = 1.0/direction;
03739 for (iColumn=0;iColumn<numberColumns_;iColumn++)
03740 dj[iColumn] = direction*linearObjective[iColumn];
03741 for (iColumn=0;iColumn<numberColumns_;iColumn++) {
03742
03743 double lowerBound = columnLower_[iColumn];
03744 double upperBound = columnUpper_[iColumn];
03745 if (lowerBound>-1.0e20||upperBound<1.0e20) {
03746 bool atLower;
03747 if (fabs(upperBound)<fabs(lowerBound)) {
03748 atLower=false;
03749 setColumnStatus(iColumn,atUpperBound);
03750 solution[iColumn]=upperBound;
03751 } else {
03752 atLower=true;
03753 setColumnStatus(iColumn,atLowerBound);
03754 solution[iColumn]=lowerBound;
03755 }
03756 if (dj[iColumn]<0.0) {
03757
03758 if (atLower) {
03759
03760 if (upperBound-lowerBound<=gap) {
03761 columnActivity_[iColumn]=upperBound;
03762 setColumnStatus(iColumn,atUpperBound);
03763 } else if (dj[iColumn]<-dualTolerance) {
03764 numberBad++;
03765 }
03766 }
03767 } else if (dj[iColumn]>0.0) {
03768
03769 if (!atLower) {
03770
03771 if (upperBound-lowerBound<=gap) {
03772 columnActivity_[iColumn]=lowerBound;
03773 setColumnStatus(iColumn,atLowerBound);
03774 } else if (dj[iColumn]>dualTolerance) {
03775 numberBad++;
03776 }
03777 }
03778 }
03779 } else {
03780
03781 setColumnStatus(iColumn,isFree);
03782 if (fabs(dj[iColumn])>dualTolerance)
03783 numberBad++;
03784 }
03785 }
03786 if (numberBad||pivot) {
03787 if (!pivot) {
03788 delete [] dj;
03789 returnCode = 1;
03790 } else {
03791
03792 double * pi = new double[numberRows_];
03793 memset (pi,0,numberRows_*sizeof(double));
03794 int * way = new int[numberColumns_];
03795 int numberIn = 0;
03796
03797
03798 CoinPackedMatrix * columnCopy = matrix();
03799
03800 CoinPackedMatrix copy;
03801 copy.reverseOrderedCopyOf(*columnCopy);
03802
03803 const int * column = copy.getIndices();
03804 const CoinBigIndex * rowStart = copy.getVectorStarts();
03805 const int * rowLength = copy.getVectorLengths();
03806 const double * elementByRow = copy.getElements();
03807
03808
03809
03810
03811
03812
03813
03814
03815
03816 for (iColumn=0;iColumn<numberColumns_;iColumn++) {
03817
03818 int thisWay = 100;
03819 double lowerBound = columnLower_[iColumn];
03820 double upperBound = columnUpper_[iColumn];
03821 if (upperBound>lowerBound) {
03822 switch(getColumnStatus(iColumn)) {
03823
03824 case basic:
03825 thisWay=0;
03826 case ClpSimplex::isFixed:
03827 break;
03828 case isFree:
03829 case superBasic:
03830 if (dj[iColumn]<-dualTolerance)
03831 thisWay = 1;
03832 else if (dj[iColumn]>dualTolerance)
03833 thisWay = -1;
03834 else
03835 thisWay =0;
03836 break;
03837 case atUpperBound:
03838 if (dj[iColumn]>dualTolerance)
03839 thisWay = -1;
03840 else if (dj[iColumn]<-dualTolerance)
03841 thisWay = -3;
03842 else
03843 thisWay = -2;
03844 break;
03845 case atLowerBound:
03846 if (dj[iColumn]<-dualTolerance)
03847 thisWay = 1;
03848 else if (dj[iColumn]>dualTolerance)
03849 thisWay = 3;
03850 else
03851 thisWay = 2;
03852 break;
03853 }
03854 }
03855 way[iColumn] = thisWay;
03856 }
03857
03858
03859
03860 int lastNumberIn = -100000;
03861 int numberPasses=5;
03862 while (numberIn>lastNumberIn+numberRows_/100) {
03863 lastNumberIn = numberIn;
03864
03865 int iRow;
03866 for (iRow=0;iRow<numberRows_;iRow++) {
03867 double lowerBound = rowLower_[iRow];
03868 double upperBound = rowUpper_[iRow];
03869 if (getRowStatus(iRow)==basic) {
03870
03871 int j;
03872
03873 double maximumDown = COIN_DBL_MAX;
03874 double maximumUp = COIN_DBL_MAX;
03875 double minimumDown =0.0;
03876 double minimumUp =0.0;
03877 int iUp=-1;
03878 int iDown=-1;
03879 int iUpB=-1;
03880 int iDownB=-1;
03881 if (lowerBound<-1.0e20)
03882 maximumUp = -1.0;
03883 if (upperBound>1.0e20)
03884 maximumDown = -1.0;
03885 for (j=rowStart[iRow];j<rowStart[iRow]+rowLength[iRow];j++) {
03886 int iColumn = column[j];
03887 double value = elementByRow[j];
03888 double djValue = dj[iColumn];
03889
03890
03891
03892
03893
03894
03895
03896
03897
03898
03899 if (way[iColumn]!=100) {
03900 switch(way[iColumn]) {
03901
03902 case -3:
03903 if (value>0.0) {
03904 if (maximumDown*value>-djValue) {
03905 maximumDown = -djValue/value;
03906 iDown = iColumn;
03907 }
03908 } else {
03909 if (-maximumUp*value>-djValue) {
03910 maximumUp = djValue/value;
03911 iUp = iColumn;
03912 }
03913 }
03914 break;
03915 case -2:
03916 if (value>0.0) {
03917 maximumDown = 0.0;
03918 } else {
03919 maximumUp = 0.0;
03920 }
03921 break;
03922 case -1:
03923
03924
03925 if (value>0.0) {
03926 maximumDown=0.0;
03927 if (maximumUp*value<djValue-dualTolerance) {
03928 maximumUp = 0.0;
03929 } else {
03930 if (minimumUp*value<djValue) {
03931 minimumUp = djValue/value;
03932 iUpB = iColumn;
03933 }
03934 }
03935 } else {
03936 maximumUp=0.0;
03937 if (-maximumDown*value<djValue-dualTolerance) {
03938 maximumDown = 0.0;
03939 } else {
03940 if (-minimumDown*value<djValue) {
03941 minimumDown = -djValue/value;
03942 iDownB = iColumn;
03943 }
03944 }
03945 }
03946
03947 break;
03948 case 0:
03949 maximumDown = -1.0;
03950 maximumUp=-1.0;
03951 break;
03952 case 1:
03953
03954
03955 if (value>0.0) {
03956 maximumUp=0.0;
03957 if (maximumDown*value<-djValue-dualTolerance) {
03958 maximumDown = 0.0;
03959 } else {
03960 if (minimumDown*value<-djValue) {
03961 minimumDown = -djValue/value;
03962 iDownB = iColumn;
03963 }
03964 }
03965 } else {
03966 maximumDown=0.0;
03967 if (-maximumUp*value<-djValue-dualTolerance) {
03968 maximumUp = 0.0;
03969 } else {
03970 if (-minimumUp*value<-djValue) {
03971 minimumUp = djValue/value;
03972 iUpB = iColumn;
03973 }
03974 }
03975 }
03976
03977 break;
03978 case 2:
03979 if (value>0.0) {
03980 maximumUp = 0.0;
03981 } else {
03982 maximumDown = 0.0;
03983 }
03984
03985 break;
03986 case 3:
03987 if (value>0.0) {
03988 if (maximumUp*value>djValue) {
03989 maximumUp = djValue/value;
03990 iUp = iColumn;
03991 }
03992 } else {
03993 if (-maximumDown*value>djValue) {
03994 maximumDown = -djValue/value;
03995 iDown = iColumn;
03996 }
03997 }
03998
03999 break;
04000 default:
04001 break;
04002 }
04003 }
04004 }
04005 if (iUpB>=0)
04006 iUp=iUpB;
04007 if (maximumUp<=dualTolerance||maximumUp<minimumUp)
04008 iUp=-1;
04009 if (iDownB>=0)
04010 iDown=iDownB;
04011 if (maximumDown<=dualTolerance||maximumDown<minimumDown)
04012 iDown=-1;
04013 if (iUp>=0||iDown>=0) {
04014
04015 if (iUp>=0&&iDown>=0) {
04016 if (maximumDown>maximumUp)
04017 iUp=-1;
04018 }
04019 double change;
04020 int kColumn;
04021 if (iUp>=0) {
04022 kColumn=iUp;
04023 change=maximumUp;
04024
04025
04026 if (minimumUp>0.0)
04027 change=minimumUp;
04028 setRowStatus(iRow,atUpperBound);
04029 } else {
04030 kColumn=iDown;
04031 change=-maximumDown;
04032
04033
04034 if (minimumDown>0.0)
04035 change=-minimumDown;
04036 setRowStatus(iRow,atLowerBound);
04037 }
04038 assert (fabs(change)<1.0e20);
04039 setColumnStatus(kColumn,basic);
04040 numberIn++;
04041 pi[iRow]=change;
04042 for (j=rowStart[iRow];j<rowStart[iRow]+rowLength[iRow];j++) {
04043 int iColumn = column[j];
04044 double value = elementByRow[j];
04045 double djValue = dj[iColumn]-change*value;
04046 dj[iColumn]=djValue;
04047 if (abs(way[iColumn])==1) {
04048 numberBad--;
04049
04050
04051
04052 lastNumberIn=-1000000;
04053 }
04054 int thisWay = 100;
04055 double lowerBound = columnLower_[iColumn];
04056 double upperBound = columnUpper_[iColumn];
04057 if (upperBound>lowerBound) {
04058 switch(getColumnStatus(iColumn)) {
04059
04060 case basic:
04061 thisWay=0;
04062 case isFixed:
04063 break;
04064 case isFree:
04065 case superBasic:
04066 if (djValue<-dualTolerance)
04067 thisWay = 1;
04068 else if (djValue>dualTolerance)
04069 thisWay = -1;
04070 else
04071 { thisWay =0; abort();}
04072 break;
04073 case atUpperBound:
04074 if (djValue>dualTolerance)
04075 { thisWay =-1; abort();}
04076 else if (djValue<-dualTolerance)
04077 thisWay = -3;
04078 else
04079 thisWay = -2;
04080 break;
04081 case atLowerBound:
04082 if (djValue<-dualTolerance)
04083 { thisWay =1; abort();}
04084 else if (djValue>dualTolerance)
04085 thisWay = 3;
04086 else
04087 thisWay = 2;
04088 break;
04089 }
04090 }
04091 way[iColumn] = thisWay;
04092 }
04093 }
04094 }
04095 }
04096 if (numberIn==lastNumberIn||numberBad||pivot<2)
04097 break;
04098 if (!(--numberPasses))
04099 break;
04100
04101 }
04102
04103 for (iColumn=0;iColumn<numberColumns_;iColumn++) {
04104 double lowerBound = columnLower_[iColumn];
04105 double upperBound = columnUpper_[iColumn];
04106 if (upperBound-lowerBound<=gap&&upperBound>lowerBound) {
04107 double djValue=dj[iColumn];
04108 switch(getColumnStatus(iColumn)) {
04109
04110 case basic:
04111 case ClpSimplex::isFixed:
04112 break;
04113 case isFree:
04114 case superBasic:
04115 break;
04116 case atUpperBound:
04117 if (djValue>dualTolerance) {
04118 setColumnStatus(iColumn,atUpperBound);
04119 solution[iColumn]=upperBound;
04120 }
04121 break;
04122 case atLowerBound:
04123 if (djValue<-dualTolerance) {
04124 setColumnStatus(iColumn,atUpperBound);
04125 solution[iColumn]=upperBound;
04126 }
04127 break;
04128 }
04129 }
04130 }
04131 delete [] pi;
04132 delete [] dj;
04133 delete [] way;
04134 handler_->message(CLP_CRASH,messages_)
04135 <<numberIn
04136 <<numberBad
04137 <<CoinMessageEol;
04138 returnCode = -1;
04139 }
04140 } else {
04141 delete [] dj;
04142 returnCode = -1;
04143 }
04144
04145 }
04146 return returnCode;
04147 }
04148
04149
04150
04151
04152
04153 int ClpSimplex::pivot()
04154 {
04155
04156 assert (!scalingFlag_);
04157
04158
04159 lowerIn_ = lower_[sequenceIn_];
04160 valueIn_ = solution_[sequenceIn_];
04161 upperIn_ = upper_[sequenceIn_];
04162 dualIn_ = dj_[sequenceIn_];
04163 if (sequenceOut_>=0&&sequenceIn_!=sequenceIn_) {
04164 assert (pivotRow_>=0&&pivotRow_<numberRows_);
04165 assert (pivotVariable_[pivotRow_]==sequenceOut_);
04166 lowerOut_ = lower_[sequenceOut_];
04167 valueOut_ = solution_[sequenceOut_];
04168 upperOut_ = upper_[sequenceOut_];
04169
04170 dualOut_ = dj_[sequenceOut_];
04171 assert(fabs(dualOut_)<1.0e-6);
04172 } else {
04173 assert (pivotRow_<0);
04174 }
04175 bool roundAgain = true;
04176 int returnCode=0;
04177 while (roundAgain) {
04178 roundAgain=false;
04179 unpack(rowArray_[1]);
04180 factorization_->updateColumnFT(rowArray_[2],rowArray_[1]);
04181
04182 double movement;
04183
04184 if (sequenceOut_<0||sequenceIn_==sequenceOut_) {
04185
04186 movement = ((directionIn_>0) ? upperIn_ : lowerIn_) - valueIn_;
04187 } else {
04188
04189 double outValue = (directionOut_>0) ? upperOut_ : lowerOut_;
04190
04191 movement = (outValue-valueOut_)/alpha_;
04192
04193 directionIn_ = (movement>0) ? 1 :-1;
04194 }
04195
04196 {
04197 int i;
04198 int * index = rowArray_[1]->getIndices();
04199 int number = rowArray_[1]->getNumElements();
04200 double * element = rowArray_[1]->denseVector();
04201 for (i=0;i<number;i++) {
04202 int ii = index[i];
04203
04204 ii = pivotVariable_[ii];
04205 solution_[ii] -= movement*element[i];
04206 element[i]=0.0;
04207 }
04208
04209 if (sequenceOut_<0) {
04210 if (directionIn_<0) {
04211 assert (fabs(solution_[sequenceIn_]-upperIn_)<1.0e-7);
04212 solution_[sequenceIn_]=upperIn_;
04213 } else {
04214 assert (fabs(solution_[sequenceIn_]-lowerIn_)<1.0e-7);
04215 solution_[sequenceIn_]=lowerIn_;
04216 }
04217 } else {
04218 if (directionOut_<0) {
04219 assert (fabs(solution_[sequenceOut_]-upperOut_)<1.0e-7);
04220 solution_[sequenceOut_]=upperOut_;
04221 } else {
04222 assert (fabs(solution_[sequenceOut_]-lowerOut_)<1.0e-7);
04223 solution_[sequenceOut_]=lowerOut_;
04224 }
04225 solution_[sequenceIn_]=valueIn_+movement;
04226 }
04227 }
04228 double objectiveChange = dualIn_*movement;
04229
04230 if (pivotRow_>=0) {
04231 alpha_ = rowArray_[1]->denseVector()[pivotRow_];
04232 assert (fabs(alpha_)>1.0e-8);
04233 double multiplier = dualIn_/alpha_;
04234 rowArray_[0]->insert(pivotRow_,multiplier);
04235 factorization_->updateColumnTranspose(rowArray_[2],rowArray_[0]);
04236
04237 matrix_->transposeTimes(this,-1.0,
04238 rowArray_[0],columnArray_[1],columnArray_[0]);
04239
04240 int i;
04241 int * index = columnArray_[0]->getIndices();
04242 int number = columnArray_[0]->getNumElements();
04243 double * element = columnArray_[0]->denseVector();
04244 for (i=0;i<number;i++) {
04245 int ii = index[i];
04246 dj_[ii] += element[ii];
04247 element[ii]=0.0;
04248 }
04249 columnArray_[0]->setNumElements(0);
04250
04251 index = rowArray_[0]->getIndices();
04252 number = rowArray_[0]->getNumElements();
04253 element = rowArray_[0]->denseVector();
04254 for (i=0;i<number;i++) {
04255 int ii = index[i];
04256 dj_[ii+numberColumns_] += element[ii];
04257 dual_[ii] = dj_[ii+numberColumns_];
04258 element[ii]=0.0;
04259 }
04260 rowArray_[0]->setNumElements(0);
04261
04262 assert (fabs(dj_[sequenceIn_])<1.0e-6);
04263 }
04264
04265
04266 int updateStatus = factorization_->replaceColumn(rowArray_[2],
04267 pivotRow_,
04268 alpha_);
04269 bool takePivot=true;
04270
04271 if (updateStatus==2&&
04272 lastGoodIteration_==numberIterations_&&fabs(alpha_)>1.0e-5)
04273 updateStatus=4;
04274 if (updateStatus==1||updateStatus==4) {
04275
04276 if (factorization_->pivots()>5||updateStatus==4) {
04277 returnCode=-1;
04278 }
04279 } else if (updateStatus==2) {
04280
04281 rowArray_[1]->clear();
04282 takePivot=false;
04283 if (factorization_->pivots()) {
04284
04285 statusOfProblem();
04286 roundAgain=true;
04287 } else {
04288 returnCode=1;
04289 }
04290 } else if (updateStatus==3) {
04291
04292
04293 if (factorization_->pivots()<
04294 0.5*factorization_->maximumPivots()&&
04295 factorization_->pivots()<200)
04296 factorization_->areaFactor(
04297 factorization_->areaFactor() * 1.1);
04298 returnCode =-1;
04299 }
04300 if (takePivot) {
04301 int save = algorithm_;
04302
04303 algorithm_=1;
04304 housekeeping(objectiveChange);
04305 algorithm_=save;
04306 }
04307 }
04308 if (returnCode == -1) {
04309
04310 statusOfProblem();
04311 } else {
04312
04313 gutsOfSolution(NULL,NULL);
04314 }
04315 return returnCode;
04316 }
04317
04318
04319
04320
04321
04322
04323 int ClpSimplex::primalPivotResult()
04324 {
04325 assert (sequenceIn_>=0);
04326 valueIn_=solution_[sequenceIn_];
04327 lowerIn_=lower_[sequenceIn_];
04328 upperIn_=upper_[sequenceIn_];
04329 dualIn_=dj_[sequenceIn_];
04330
04331 int returnCode = ((ClpSimplexPrimal *) this)->pivotResult();
04332 if (returnCode<0&&returnCode>-4) {
04333 return 0;
04334 } else {
04335 printf("Return code of %d from ClpSimplexPrimal::pivotResult\n",
04336 returnCode);
04337 return -1;
04338 }
04339 }
04340
04341
04342
04343
04344
04345
04346
04347 int
04348 ClpSimplex::dualPivotResult()
04349 {
04350 return ((ClpSimplexDual *) this)->pivotResult();
04351 }
04352
04353 int
04354 ClpSimplex::factorizationFrequency() const
04355 {
04356 if (factorization_)
04357 return factorization_->maximumPivots();
04358 else
04359 return -1;
04360 }
04361 void
04362 ClpSimplex::setFactorizationFrequency(int value)
04363 {
04364 if (factorization_)
04365 factorization_->maximumPivots(value);
04366 }
04367
04368 int
04369 ClpSimplex::startup(int ifValuesPass)
04370 {
04371
04372
04373 if (!matrix_||!matrix_->getNumElements()) {
04374 handler_->message(CLP_EMPTY_PROBLEM,messages_)
04375 <<numberRows_
04376 <<numberColumns_
04377 <<0
04378 <<CoinMessageEol;
04379 problemStatus_=4;
04380 return 2;
04381 }
04382 pivotRow_=-1;
04383 sequenceIn_=-1;
04384 sequenceOut_=-1;
04385 secondaryStatus_=0;
04386
04387 primalTolerance_=dblParam_[ClpPrimalTolerance];
04388 dualTolerance_=dblParam_[ClpDualTolerance];
04389 if (problemStatus_!=10)
04390 numberIterations_=0;
04391
04392
04393
04394 bool goodMatrix=createRim(7+8+16,true);
04395
04396 if (goodMatrix) {
04397
04398
04399
04400
04401
04402
04403 factorization_->increasingRows(2);
04404
04405 factorization_->slackValue(-1.0);
04406 factorization_->zeroTolerance(1.0e-13);
04407
04408 int saveThreshold = factorization_->denseThreshold();
04409 factorization_->setDenseThreshold(0);
04410
04411 if (ifValuesPass) {
04412
04413
04414 if (perturbation_<100) {
04415 if (algorithm_>0) {
04416 ((ClpSimplexPrimal *) this)->perturb(0);
04417 } else if (algorithm_<0) {
04418 ((ClpSimplexDual *) this)->perturb();
04419 }
04420 }
04421 }
04422
04423 if (nonLinearCost_==NULL&&algorithm_>0) {
04424
04425 delete nonLinearCost_;
04426 nonLinearCost_= new ClpNonLinearCost(this);
04427 }
04428
04429
04430 int numberThrownOut = -1;
04431 int totalNumberThrownOut=0;
04432 while(numberThrownOut) {
04433 int status = internalFactorize(0+10*ifValuesPass);
04434 if (status<0)
04435 return 1;
04436 else
04437 numberThrownOut = status;
04438
04439
04440 if (!numberThrownOut)
04441 numberThrownOut = gutsOfSolution( NULL,NULL,
04442 ifValuesPass!=0);
04443 totalNumberThrownOut+= numberThrownOut;
04444
04445 }
04446
04447 if (totalNumberThrownOut)
04448 handler_->message(CLP_SINGULARITIES,messages_)
04449 <<totalNumberThrownOut
04450 <<CoinMessageEol;
04451
04452 factorization_->setDenseThreshold(saveThreshold);
04453
04454 problemStatus_ = -1;
04455
04456
04457 numberTimesOptimal_=0;
04458
04459 return 0;
04460 } else {
04461
04462 return 2;
04463 }
04464
04465 }
04466
04467
04468 void
04469 ClpSimplex::finish()
04470 {
04471
04472 deleteRim();
04473
04474 if (problemStatus_!=10) {
04475 assert(problemStatus_>=0&&problemStatus_<5);
04476 handler_->message(CLP_SIMPLEX_FINISHED+problemStatus_,messages_)
04477 <<objectiveValue()
04478 <<CoinMessageEol;
04479 }
04480 factorization_->relaxAccuracyCheck(1.0);
04481
04482 factorization_->cleanUp();
04483 }
04484
04485 ClpDataSave
04486 ClpSimplex::saveData()
04487 {
04488 ClpDataSave saved;
04489 saved.dualBound_ = dualBound_;
04490 saved.infeasibilityCost_ = infeasibilityCost_;
04491 saved.sparseThreshold_ = factorization_->sparseThreshold();
04492 saved.perturbation_ = perturbation_;
04493
04494 delete progress_;
04495 progress_ = new ClpSimplexProgress (this);
04496 return saved;
04497 }
04498
04499 void
04500 ClpSimplex::restoreData(ClpDataSave saved)
04501 {
04502 factorization_->sparseThreshold(saved.sparseThreshold_);
04503 perturbation_ = saved.perturbation_;
04504 infeasibilityCost_ = saved.infeasibilityCost_;
04505 dualBound_ = saved.dualBound_;
04506 delete progress_;
04507 progress_=NULL;
04508 }
04509
04510 bool
04511 ClpSimplex::statusOfProblem()
04512 {
04513
04514 assert (internalFactorize(1)==0);
04515
04516
04517 createRim(4+32);
04518
04519
04520 gutsOfSolution(NULL,NULL);
04521
04522
04523
04524 deleteRim(-1);
04525 return (primalFeasible()&&dualFeasible());
04526 }
04527
04528 void
04529 ClpSimplex::returnModel(ClpSimplex & otherModel)
04530 {
04531 ClpModel::returnModel(otherModel);
04532 otherModel.columnPrimalInfeasibility_ = columnPrimalInfeasibility_;
04533 otherModel.columnPrimalSequence_ = columnPrimalSequence_;
04534 otherModel.rowPrimalInfeasibility_ = rowPrimalInfeasibility_;
04535 otherModel.rowPrimalSequence_ = rowPrimalSequence_;
04536 otherModel.columnDualInfeasibility_ = columnDualInfeasibility_;
04537 otherModel.columnDualSequence_ = columnDualSequence_;
04538 otherModel.rowDualInfeasibility_ = rowDualInfeasibility_;
04539 otherModel.rowDualSequence_ = rowDualSequence_;
04540 otherModel.primalToleranceToGetOptimal_ = primalToleranceToGetOptimal_;
04541 otherModel.remainingDualInfeasibility_ = remainingDualInfeasibility_;
04542 otherModel.largestPrimalError_ = largestPrimalError_;
04543 otherModel.largestDualError_ = largestDualError_;
04544 otherModel.largestSolutionError_ = largestSolutionError_;
04545 otherModel.alpha_ = alpha_;
04546 otherModel.theta_ = theta_;
04547 otherModel.lowerIn_ = lowerIn_;
04548 otherModel.valueIn_ = valueIn_;
04549 otherModel.upperIn_ = upperIn_;
04550 otherModel.dualIn_ = dualIn_;
04551 otherModel.sequenceIn_ = sequenceIn_;
04552 otherModel.directionIn_ = directionIn_;
04553 otherModel.lowerOut_ = lowerOut_;
04554 otherModel.valueOut_ = valueOut_;
04555 otherModel.upperOut_ = upperOut_;
04556 otherModel.dualOut_ = dualOut_;
04557 otherModel.sequenceOut_ = sequenceOut_;
04558 otherModel.directionOut_ = directionOut_;
04559 otherModel.pivotRow_ = pivotRow_;
04560 otherModel.sumDualInfeasibilities_ = sumDualInfeasibilities_;
04561 otherModel.numberDualInfeasibilities_ = numberDualInfeasibilities_;
04562 otherModel.numberDualInfeasibilitiesWithoutFree_ =
04563 numberDualInfeasibilitiesWithoutFree_;
04564 otherModel.sumPrimalInfeasibilities_ = sumPrimalInfeasibilities_;
04565 otherModel.numberPrimalInfeasibilities_ = numberPrimalInfeasibilities_;
04566 otherModel.numberTimesOptimal_ = numberTimesOptimal_;
04567 otherModel.sumOfRelaxedDualInfeasibilities_ = sumOfRelaxedDualInfeasibilities_;
04568 otherModel.sumOfRelaxedPrimalInfeasibilities_ = sumOfRelaxedPrimalInfeasibilities_;
04569 }
04570
04571
04572
04573
04574
04575
04576 int
04577 ClpSimplex::createPiecewiseLinearCosts(const int * starts,
04578 const double * lower, const double * gradient)
04579 {
04580 delete nonLinearCost_;
04581
04582 int iColumn;
04583 int returnCode=0;
04584
04585 for (iColumn=0;iColumn<numberColumns_;iColumn++) {
04586 int iIndex = starts[iColumn];
04587 int end = starts[iColumn+1]-1;
04588 columnLower_[iColumn] = lower[iIndex];
04589 columnUpper_[iColumn] = lower[end];
04590 double value = columnLower_[iColumn];
04591 iIndex++;
04592 for (;iIndex<end;iIndex++) {
04593 if (lower[iIndex]<value)
04594 returnCode++;
04595 value=lower[iIndex];
04596 }
04597 }
04598 nonLinearCost_ = new ClpNonLinearCost(this,starts,lower,gradient);
04599 specialOptions_ |= 2;
04600 return returnCode;
04601 }
04602
04603
04604
04605
04606
04607
04608
04609
04610
04611
04612 void
04613 ClpSimplex::setValuesPassAction(float incomingInfeasibility,
04614 float allowedInfeasibility)
04615 {
04616 incomingInfeasibility_=incomingInfeasibility;
04617 allowedInfeasibility_=allowedInfeasibility;
04618 assert(incomingInfeasibility_>=0.0);
04619 assert(allowedInfeasibility_>=incomingInfeasibility_);
04620 }
04621
04622
04623 ClpSimplexProgress::ClpSimplexProgress ()
04624 {
04625 int i;
04626 for (i=0;i<CLP_PROGRESS;i++) {
04627 objective_[i] = COIN_DBL_MAX;
04628 infeasibility_[i] = -1.0;
04629 numberInfeasibilities_[i]=-1;
04630 iterationNumber_[i]=-1;
04631 }
04632 for (i=0;i<CLP_CYCLE;i++) {
04633 obj_[i]=COIN_DBL_MAX;
04634 in_[i]=-1;
04635 out_[i]=-1;
04636 way_[i]=0;
04637 }
04638 numberTimes_ = 0;
04639 numberBadTimes_ = 0;
04640 model_ = NULL;
04641 oddState_=0;
04642 }
04643
04644
04645
04646
04647 ClpSimplexProgress::~ClpSimplexProgress ()
04648 {
04649 }
04650
04651 ClpSimplexProgress::ClpSimplexProgress(const ClpSimplexProgress &rhs)
04652 {
04653 int i;
04654 for (i=0;i<CLP_PROGRESS;i++) {
04655 objective_[i] = rhs.objective_[i];
04656 infeasibility_[i] = rhs.infeasibility_[i];
04657 numberInfeasibilities_[i]=rhs.numberInfeasibilities_[i];
04658 iterationNumber_[i]=rhs.iterationNumber_[i];
04659 }
04660 for (i=0;i<CLP_CYCLE;i++) {
04661 obj_[i]=rhs.obj_[i];
04662 in_[i]=rhs.in_[i];
04663 out_[i]=rhs.out_[i];
04664 way_[i]=rhs.way_[i];
04665 }
04666 numberTimes_ = rhs.numberTimes_;
04667 numberBadTimes_ = rhs.numberBadTimes_;
04668 model_ = rhs.model_;
04669 oddState_=rhs.oddState_;
04670 }
04671
04672 ClpSimplexProgress::ClpSimplexProgress(ClpSimplex * model)
04673 {
04674 model_ = model;
04675 int i;
04676 for (i=0;i<CLP_PROGRESS;i++) {
04677 if (model_->algorithm()>=0)
04678 objective_[i] = COIN_DBL_MAX;
04679 else
04680 objective_[i] = -COIN_DBL_MAX;
04681 infeasibility_[i] = -1.0;
04682 numberInfeasibilities_[i]=-1;
04683 iterationNumber_[i]=-1;
04684 }
04685 for (i=0;i<CLP_CYCLE;i++) {
04686 obj_[i]=COIN_DBL_MAX;
04687 in_[i]=-1;
04688 out_[i]=-1;
04689 way_[i]=0;
04690 }
04691 numberTimes_ = 0;
04692 numberBadTimes_ = 0;
04693 oddState_=0;
04694 }
04695
04696 ClpSimplexProgress &
04697 ClpSimplexProgress::operator=(const ClpSimplexProgress & rhs)
04698 {
04699 if (this != &rhs) {
04700 int i;
04701 for (i=0;i<CLP_PROGRESS;i++) {
04702 objective_[i] = rhs.objective_[i];
04703 infeasibility_[i] = rhs.infeasibility_[i];
04704 numberInfeasibilities_[i]=rhs.numberInfeasibilities_[i];
04705 iterationNumber_[i]=rhs.iterationNumber_[i];
04706 }
04707 for (i=0;i<CLP_CYCLE;i++) {
04708 obj_[i]=rhs.obj_[i];
04709 in_[i]=rhs.in_[i];
04710 out_[i]=rhs.out_[i];
04711 way_[i]=rhs.way_[i];
04712 }
04713 numberTimes_ = rhs.numberTimes_;
04714 numberBadTimes_ = rhs.numberBadTimes_;
04715 model_ = rhs.model_;
04716 oddState_=rhs.oddState_;
04717 }
04718 return *this;
04719 }
04720
04721 static bool equalDouble(double value1, double value2)
04722 {
04723 unsigned int *i1 = (unsigned int *) &value1;
04724 unsigned int *i2 = (unsigned int *) &value2;
04725 if (sizeof(unsigned int)*2==sizeof(double))
04726 return (i1[0]==i2[0]&&i1[1]==i2[1]);
04727 else
04728 return (i1[0]==i2[0]);
04729 }
04730 int
04731 ClpSimplexProgress::looping()
04732 {
04733 if (!model_)
04734 return -1;
04735 double objective = model_->rawObjectiveValue();
04736 double infeasibility;
04737 int numberInfeasibilities;
04738 int iterationNumber = model_->numberIterations();
04739 if (model_->algorithm()<0) {
04740
04741 infeasibility = model_->sumPrimalInfeasibilities();
04742 numberInfeasibilities = model_->numberPrimalInfeasibilities();
04743 } else {
04744
04745 infeasibility = model_->sumDualInfeasibilities();
04746 numberInfeasibilities = model_->numberDualInfeasibilities();
04747 }
04748 int i;
04749 int numberMatched=0;
04750 int matched=0;
04751 int nsame=0;
04752 for (i=0;i<CLP_PROGRESS;i++) {
04753 bool matchedOnObjective = equalDouble(objective,objective_[i]);
04754 bool matchedOnInfeasibility = equalDouble(infeasibility,infeasibility_[i]);
04755 bool matchedOnInfeasibilities =
04756 (numberInfeasibilities==numberInfeasibilities_[i]);
04757
04758 if (matchedOnObjective&&matchedOnInfeasibility&&matchedOnInfeasibilities) {
04759 matched |= (1<<i);
04760
04761 if (iterationNumber!=iterationNumber_[i]) {
04762 numberMatched++;
04763
04764 if (model_->messageHandler()->logLevel()>10)
04765 printf("%d %d %d %d %d loop check\n",i,numberMatched,
04766 matchedOnObjective, matchedOnInfeasibility,
04767 matchedOnInfeasibilities);
04768 } else {
04769
04770 nsame++;
04771 }
04772 }
04773 if (i) {
04774 objective_[i-1] = objective_[i];
04775 infeasibility_[i-1] = infeasibility_[i];
04776 numberInfeasibilities_[i-1]=numberInfeasibilities_[i];
04777 iterationNumber_[i-1]=iterationNumber_[i];
04778 }
04779 }
04780 objective_[CLP_PROGRESS-1] = objective;
04781 infeasibility_[CLP_PROGRESS-1] = infeasibility;
04782 numberInfeasibilities_[CLP_PROGRESS-1]=numberInfeasibilities;
04783 iterationNumber_[CLP_PROGRESS-1]=iterationNumber;
04784 if (nsame==CLP_PROGRESS)
04785 numberMatched=CLP_PROGRESS;
04786 if (model_->progressFlag())
04787 numberMatched=0;
04788 numberTimes_++;
04789 if (numberTimes_<10)
04790 numberMatched=0;
04791
04792 if (matched==(1<<(CLP_PROGRESS-1)))
04793 numberMatched=0;
04794 if (numberMatched) {
04795 model_->messageHandler()->message(CLP_POSSIBLELOOP,model_->messages())
04796 <<numberMatched
04797 <<matched
04798 <<numberTimes_
04799 <<CoinMessageEol;
04800 numberBadTimes_++;
04801 if (numberBadTimes_<10) {
04802
04803 model_->forceFactorization(1);
04804 if (model_->algorithm()<0) {
04805
04806 model_->setCurrentDualTolerance(model_->currentDualTolerance()*1.05);
04807
04808 if (model_->dualBound()<1.0e17) {
04809 model_->setDualBound(model_->dualBound()*1.1);
04810 }
04811 } else {
04812
04813 if (numberBadTimes_>3)
04814 model_->setCurrentPrimalTolerance(model_->currentPrimalTolerance()*1.05);
04815
04816 if (model_->nonLinearCost()->numberInfeasibilities()&&
04817 model_->infeasibilityCost()<1.0e17) {
04818 model_->setInfeasibilityCost(model_->infeasibilityCost()*1.1);
04819 }
04820 }
04821 return -2;
04822 } else {
04823
04824 if (infeasibility<1.0e-4) {
04825 return 0;
04826 } else {
04827 model_->messageHandler()->message(CLP_LOOP,model_->messages())
04828 <<CoinMessageEol;
04829 #ifndef NDEBUG
04830 abort();
04831 #endif
04832 return 3;
04833 }
04834 }
04835 }
04836 return -1;
04837 }
04838
04839 double
04840 ClpSimplexProgress::lastObjective(int back) const
04841 {
04842 return objective_[CLP_PROGRESS-1-back];
04843 }
04844
04845 void
04846 ClpSimplexProgress::modifyObjective(double value)
04847 {
04848 objective_[CLP_PROGRESS-1]=value;
04849 }
04850
04851 int
04852 ClpSimplexProgress::lastIterationNumber(int back) const
04853 {
04854 return iterationNumber_[CLP_PROGRESS-1-back];
04855 }
04856
04857 void
04858 ClpSimplexProgress::startCheck()
04859 {
04860 int i;
04861 for (i=0;i<CLP_CYCLE;i++) {
04862 obj_[i]=COIN_DBL_MAX;
04863 in_[i]=-1;
04864 out_[i]=-1;
04865 way_[i]=0;
04866 }
04867 }
04868
04869 int
04870 ClpSimplexProgress::cycle(int in, int out,int wayIn,int wayOut)
04871 {
04872 int i;
04873 int matched=0;
04874
04875 for (i=1;i<CLP_CYCLE;i++) {
04876 if (in==out_[i]) {
04877
04878 matched=-1;
04879 break;
04880 }
04881 }
04882 if (!matched||in_[0]<0) {
04883
04884 for (i=0;i<CLP_CYCLE-1;i++) {
04885 obj_[i]=obj_[i+1];
04886 in_[i]=in_[i+1];
04887 out_[i]=out_[i+1];
04888 way_[i]=way_[i+1];
04889 }
04890 } else {
04891
04892 matched=0;
04893 for (i=0;i<CLP_CYCLE-1;i++) {
04894 int k;
04895 char wayThis = way_[i];
04896 int inThis = in_[i];
04897 int outThis = out_[i];
04898
04899 for(k=i+1;k<CLP_CYCLE;k++) {
04900 if (inThis==in_[k]&&outThis==out_[k]&&wayThis==way_[k]) {
04901 if (k+(k-i)<CLP_CYCLE) {
04902
04903 int j=k+(k-i);
04904 if (inThis==in_[j]&&outThis==out_[j]&&wayThis==way_[j]) {
04905 matched=k-i;
04906 break;
04907 }
04908 } else {
04909 matched=k-i;
04910 break;
04911 }
04912 }
04913 }
04914 obj_[i]=obj_[i+1];
04915 in_[i]=in_[i+1];
04916 out_[i]=out_[i+1];
04917 way_[i]=way_[i+1];
04918 }
04919 }
04920 char way = 1-wayIn+4*(1-wayOut);
04921 obj_[i]=model_->objectiveValue();
04922 in_[CLP_CYCLE-1]=in;
04923 out_[CLP_CYCLE-1]=out;
04924 way_[CLP_CYCLE-1]=way;
04925 return matched;
04926 }
04927
04928 void
04929 ClpSimplex::setInitialDenseFactorization(bool onOff)
04930 {
04931 if (onOff)
04932 specialOptions_ |= 8;
04933 else
04934 specialOptions_ &= ~8;
04935 }
04936 bool
04937 ClpSimplex::initialDenseFactorization() const
04938 {
04939 return (specialOptions_&8)!=0;
04940 }
04941
04942
04943
04944 ClpSimplex::ClpSimplex (ClpSimplex * wholeModel,
04945 int numberColumns, const int * whichColumns)
04946 {
04947
04948
04949 numberRows_ = wholeModel->numberRows_;
04950 int * whichRow = new int [numberRows_];
04951 int iRow;
04952 for (iRow=0;iRow<numberRows_;iRow++)
04953 whichRow[iRow]=iRow;
04954
04955 matrix_ = wholeModel->matrix_;
04956 rowCopy_ = wholeModel->rowCopy_;
04957 if (wholeModel->rowCopy_) {
04958
04959 wholeModel->rowCopy_ = wholeModel->rowCopy_->subsetClone(numberRows_,whichRow,
04960 numberColumns,whichColumns);
04961 } else {
04962 wholeModel->rowCopy_=NULL;
04963 }
04964 assert (wholeModel->matrix_);
04965 wholeModel->matrix_ = wholeModel->matrix_->subsetClone(numberRows_,whichRow,
04966 numberColumns,whichColumns);
04967 delete [] whichRow;
04968 numberColumns_ = wholeModel->numberColumns_;
04969
04970 ClpPrimalColumnSteepest * steep =
04971 dynamic_cast< ClpPrimalColumnSteepest*>(wholeModel->primalColumnPivot_);
04972 #ifdef NDEBUG
04973 if (!steep)
04974 abort();
04975 #else
04976 assert (steep);
04977 #endif
04978 delete wholeModel->primalColumnPivot_;
04979 wholeModel->primalColumnPivot_ = new ClpPrimalColumnSteepest(0);
04980 nonLinearCost_ = wholeModel->nonLinearCost_;
04981
04982
04983 int iColumn;
04984 int numberTotal = numberRows_+numberColumns;
04985 printf("%d %d %d\n",numberTotal,numberRows_,numberColumns);
04986
04987 int * mapping = new int[numberRows_+numberColumns_];
04988 for (iColumn=0;iColumn<numberColumns_;iColumn++)
04989 mapping[iColumn]=-1;
04990 for (iRow=0;iRow<numberRows_;iRow++)
04991 mapping[iRow+numberColumns_] = iRow+numberColumns;
04992
04993 wholeModel->createRim(5,false);
04994 lower_ = wholeModel->lower_;
04995 wholeModel->lower_ = new double [numberTotal];
04996 memcpy(wholeModel->lower_+numberColumns,lower_+numberColumns_,numberRows_*sizeof(double));
04997 for (iColumn=0;iColumn<numberColumns;iColumn++) {
04998 int jColumn = whichColumns[iColumn];
04999 wholeModel->lower_[iColumn]=lower_[jColumn];
05000
05001 mapping[jColumn]=iColumn;
05002 }
05003 #ifdef CLP_DEBUG
05004 for (iColumn=0;iColumn<numberRows_+numberColumns_;iColumn++)
05005 printf("mapx %d %d\n",iColumn,mapping[iColumn]);
05006 #endif
05007
05008 for (iRow=0;iRow<numberRows_;iRow++) {
05009 int iPivot = wholeModel->pivotVariable_[iRow];
05010 wholeModel->pivotVariable_[iRow]=mapping[iPivot];
05011 #ifdef CLP_DEBUG
05012 printf("p row %d, pivot %d -> %d\n",iRow,iPivot,mapping[iPivot]);
05013 #endif
05014 assert (wholeModel->pivotVariable_[iRow]>=0);
05015 }
05016
05017 for (iColumn=0;iColumn<numberColumns;iColumn++)
05018 mapping[iColumn]=whichColumns[iColumn];
05019 for (;iColumn<numberRows_+numberColumns;iColumn++)
05020 mapping[iColumn] = iColumn + (numberColumns_-numberColumns);
05021 #ifdef CLP_DEBUG
05022 for (iColumn=0;iColumn<numberRows_+numberColumns;iColumn++)
05023 printf("map %d %d\n",iColumn,mapping[iColumn]);
05024 #endif
05025
05026 rowUpper_ = (double *) mapping;
05027 upper_ = wholeModel->upper_;
05028 wholeModel->upper_ = new double [numberTotal];
05029 for (iColumn=0;iColumn<numberTotal;iColumn++) {
05030 int jColumn = mapping[iColumn];
05031 wholeModel->upper_[iColumn]=upper_[jColumn];
05032 }
05033 cost_ = wholeModel->cost_;
05034 wholeModel->cost_ = new double [numberTotal];
05035 for (iColumn=0;iColumn<numberTotal;iColumn++) {
05036 int jColumn = mapping[iColumn];
05037 wholeModel->cost_[iColumn]=cost_[jColumn];
05038 }
05039 dj_ = wholeModel->dj_;
05040 wholeModel->dj_ = new double [numberTotal];
05041 for (iColumn=0;iColumn<numberTotal;iColumn++) {
05042 int jColumn = mapping[iColumn];
05043 wholeModel->dj_[iColumn]=dj_[jColumn];
05044 }
05045 solution_ = wholeModel->solution_;
05046 wholeModel->solution_ = new double [numberTotal];
05047 for (iColumn=0;iColumn<numberTotal;iColumn++) {
05048 int jColumn = mapping[iColumn];
05049 wholeModel->solution_[iColumn]=solution_[jColumn];
05050 }
05051
05052 double * rowSolution = wholeModel->solution_+numberColumns;
05053 double * fullSolution = solution_;
05054 double * sumFixed = new double[numberRows_];
05055 memset (sumFixed,0,numberRows_*sizeof(double));
05056
05057 for (iColumn=0;iColumn<numberColumns;iColumn++) {
05058 int jColumn = mapping[iColumn];
05059 fullSolution[jColumn]=0.0;
05060 }
05061
05062 double originalOffset;
05063 wholeModel->getDblParam(ClpObjOffset,originalOffset);
05064 double offset=0.0;
05065 const double * cost = cost_;
05066 for (iColumn=0;iColumn<numberColumns_;iColumn++)
05067 offset += fullSolution[iColumn]*cost[iColumn];
05068 wholeModel->setDblParam(ClpObjOffset,originalOffset-offset);
05069 setDblParam(ClpObjOffset,originalOffset);
05070 matrix_->times(1.0,fullSolution,sumFixed,wholeModel->rowScale_,wholeModel->columnScale_);
05071
05072 double * lower = lower_+numberColumns;
05073 double * upper = upper_+numberColumns;
05074 double fixed=0.0;
05075 for (iRow=0;iRow<numberRows_;iRow++) {
05076 fixed += fabs(sumFixed[iRow]);
05077 if (lower[iRow]>-1.0e50)
05078 lower[iRow] -= sumFixed[iRow];
05079 if (upper[iRow]<1.0e50)
05080 upper[iRow] -= sumFixed[iRow];
05081 rowSolution[iRow] -= sumFixed[iRow];
05082 }
05083 printf("offset %g sumfixed %g\n",offset,fixed);
05084 delete [] sumFixed;
05085 columnScale_ = wholeModel->columnScale_;
05086 if (columnScale_) {
05087 wholeModel->columnScale_ = new double [numberTotal];
05088 for (iColumn=0;iColumn<numberColumns;iColumn++) {
05089 int jColumn = mapping[iColumn];
05090 wholeModel->columnScale_[iColumn]=columnScale_[jColumn];
05091 }
05092 }
05093 status_ = wholeModel->status_;
05094 wholeModel->status_ = new unsigned char [numberTotal];
05095 for (iColumn=0;iColumn<numberTotal;iColumn++) {
05096 int jColumn = mapping[iColumn];
05097 wholeModel->status_[iColumn]=status_[jColumn];
05098 }
05099 savedSolution_ = wholeModel->savedSolution_;
05100 if (savedSolution_) {
05101 wholeModel->savedSolution_ = new double [numberTotal];
05102 for (iColumn=0;iColumn<numberTotal;iColumn++) {
05103 int jColumn = mapping[iColumn];
05104 wholeModel->savedSolution_[iColumn]=savedSolution_[jColumn];
05105 }
05106 }
05107 saveStatus_ = wholeModel->saveStatus_;
05108 if (saveStatus_) {
05109 wholeModel->saveStatus_ = new unsigned char [numberTotal];
05110 for (iColumn=0;iColumn<numberTotal;iColumn++) {
05111 int jColumn = mapping[iColumn];
05112 wholeModel->saveStatus_[iColumn]=saveStatus_[jColumn];
05113 }
05114 }
05115
05116 wholeModel->numberColumns_ = numberColumns;
05117
05118 wholeModel->primalColumnPivot_->saveWeights(wholeModel,2);
05119
05120 wholeModel->nonLinearCost_ = new ClpNonLinearCost(wholeModel);
05121 wholeModel->nonLinearCost_->checkInfeasibilities();
05122 printf("after contraction %d infeasibilities summing to %g\n",
05123 nonLinearCost_->numberInfeasibilities(),nonLinearCost_->sumInfeasibilities());
05124
05125 wholeModel->reducedCostWork_ = wholeModel->dj_;
05126 wholeModel->rowReducedCost_ = wholeModel->dj_+wholeModel->numberColumns_;
05127 wholeModel->columnActivityWork_ = wholeModel->solution_;
05128 wholeModel->rowActivityWork_ = wholeModel->solution_+wholeModel->numberColumns_;
05129 wholeModel->objectiveWork_ = wholeModel->cost_;
05130 wholeModel->rowObjectiveWork_ = wholeModel->cost_+wholeModel->numberColumns_;
05131 wholeModel->rowLowerWork_ = wholeModel->lower_+wholeModel->numberColumns_;
05132 wholeModel->columnLowerWork_ = wholeModel->lower_;
05133 wholeModel->rowUpperWork_ = wholeModel->upper_+wholeModel->numberColumns_;
05134 wholeModel->columnUpperWork_ = wholeModel->upper_;
05135 #ifndef NDEBUG
05136
05137 ClpSimplex * xxxx = wholeModel;
05138 int nBasic=0;
05139 for (iColumn=0;iColumn<xxxx->numberRows_+xxxx->numberColumns_;iColumn++)
05140 if (xxxx->getStatus(iColumn)==basic)
05141 nBasic++;
05142 assert (nBasic==xxxx->numberRows_);
05143 for (iRow=0;iRow<xxxx->numberRows_;iRow++) {
05144 int iPivot=xxxx->pivotVariable_[iRow];
05145 assert (xxxx->getStatus(iPivot)==basic);
05146 }
05147 #endif
05148 }
05149
05150
05151 void
05152 ClpSimplex::originalModel(ClpSimplex * miniModel)
05153 {
05154 int numberSmall = numberColumns_;
05155 numberColumns_ = miniModel->numberColumns_;
05156 int numberTotal = numberSmall+numberRows_;
05157
05158 int iColumn;
05159 int * mapping = (int *) miniModel->rowUpper_;
05160 #ifdef CLP_DEBUG
05161 for (iColumn=0;iColumn<numberRows_+numberColumns_;iColumn++)
05162 printf("mapb %d %d\n",iColumn,mapping[iColumn]);
05163 #endif
05164
05165
05166 double * fullSolution = miniModel->solution_;
05167 double * sumFixed = new double[numberRows_];
05168 memset (sumFixed,0,numberRows_*sizeof(double));
05169 miniModel->matrix_->times(1.0,fullSolution,sumFixed,rowScale_,miniModel->columnScale_);
05170
05171 for (iColumn=0;iColumn<numberTotal;iColumn++) {
05172 int jColumn = mapping[iColumn];
05173 miniModel->lower_[jColumn]=lower_[iColumn];
05174 miniModel->upper_[jColumn]=upper_[iColumn];
05175 miniModel->cost_[jColumn]=cost_[iColumn];
05176 miniModel->dj_[jColumn]=dj_[iColumn];
05177 miniModel->solution_[jColumn]=solution_[iColumn];
05178 miniModel->status_[jColumn]=status_[iColumn];
05179 #ifdef CLP_DEBUG
05180 printf("%d in small -> %d in original\n",iColumn,jColumn);
05181 #endif
05182 }
05183 delete [] lower_;
05184 lower_ = miniModel->lower_;
05185 delete [] upper_;
05186 upper_ = miniModel->upper_;
05187 delete [] cost_;
05188 cost_ = miniModel->cost_;
05189 delete [] dj_;
05190 dj_ = miniModel->dj_;
05191 delete [] solution_;
05192 solution_ = miniModel->solution_;
05193 delete [] status_;
05194 status_ = miniModel->status_;
05195 if (columnScale_) {
05196 for (iColumn=0;iColumn<numberSmall;iColumn++) {
05197 int jColumn = mapping[iColumn];
05198 miniModel->columnScale_[jColumn]=columnScale_[iColumn];
05199 }
05200 delete [] columnScale_;
05201 columnScale_ = miniModel->columnScale_;
05202 }
05203 if (savedSolution_) {
05204 if (!miniModel->savedSolution_) {
05205 miniModel->savedSolution_ = ClpCopyOfArray(solution_,numberColumns_+numberRows_);
05206 } else {
05207 for (iColumn=0;iColumn<numberTotal;iColumn++) {
05208 int jColumn = mapping[iColumn];
05209 miniModel->savedSolution_[jColumn]=savedSolution_[iColumn];
05210 }
05211 }
05212 delete [] savedSolution_;
05213 savedSolution_ = miniModel->savedSolution_;
05214 }
05215 if (saveStatus_) {
05216 if (!miniModel->saveStatus_) {
05217 miniModel->saveStatus_ = ClpCopyOfArray(status_,numberColumns_+numberRows_);
05218 } else {
05219 for (iColumn=0;iColumn<numberTotal;iColumn++) {
05220 int jColumn = mapping[iColumn];
05221 miniModel->saveStatus_[jColumn]=saveStatus_[iColumn];
05222 }
05223 }
05224 delete [] saveStatus_;
05225 saveStatus_ = miniModel->saveStatus_;
05226 }
05227
05228 int iRow;
05229 for (iRow=0;iRow<numberRows_;iRow++) {
05230 int iPivot = pivotVariable_[iRow];
05231 #ifdef CLP_DEBUG
05232 printf("pb row %d, pivot %d -> %d\n",iRow,iPivot,mapping[iPivot]);
05233 #endif
05234 pivotVariable_[iRow]=mapping[iPivot];
05235 assert (pivotVariable_[iRow]>=0);
05236 }
05237
05238 delete matrix_;
05239 delete rowCopy_;
05240 delete primalColumnPivot_;
05241 delete nonLinearCost_;
05242 matrix_ = miniModel->matrix_;
05243 rowCopy_ = miniModel->rowCopy_;
05244 nonLinearCost_ = miniModel->nonLinearCost_;
05245 double originalOffset;
05246 miniModel->getDblParam(ClpObjOffset,originalOffset);
05247 setDblParam(ClpObjOffset,originalOffset);
05248
05249 reducedCostWork_ = dj_;
05250 rowReducedCost_ = dj_+numberColumns_;
05251 columnActivityWork_ = solution_;
05252 rowActivityWork_ = solution_+numberColumns_;
05253 objectiveWork_ = cost_;
05254 rowObjectiveWork_ = cost_+numberColumns_;
05255 rowLowerWork_ = lower_+numberColumns_;
05256 columnLowerWork_ = lower_;
05257 rowUpperWork_ = upper_+numberColumns_;
05258 columnUpperWork_ = upper_;
05259
05260 for (iRow=0;iRow<numberRows_;iRow++) {
05261 double value = rowActivityWork_[iRow] + sumFixed[iRow];
05262 rowActivityWork_[iRow] = value;
05263 switch(getRowStatus(iRow)) {
05264
05265 case basic:
05266 break;
05267 case atUpperBound:
05268
05269 break;
05270 case ClpSimplex::isFixed:
05271 case atLowerBound:
05272
05273 break;
05274 case isFree:
05275 break;
05276
05277 case superBasic:
05278 break;
05279 }
05280 }
05281 delete [] sumFixed;
05282 nonLinearCost_->checkInfeasibilities();
05283 printf("in original %d infeasibilities summing to %g\n",
05284 nonLinearCost_->numberInfeasibilities(),nonLinearCost_->sumInfeasibilities());
05285
05286 primalColumnPivot_ = new ClpPrimalColumnSteepest(10);
05287 primalColumnPivot_->saveWeights(this,2);
05288 #ifndef NDEBUG
05289
05290 ClpSimplex * xxxx = this;
05291 int nBasic=0;
05292 for (iColumn=0;iColumn<xxxx->numberRows_+xxxx->numberColumns_;iColumn++)
05293 if (xxxx->getStatus(iColumn)==basic)
05294 nBasic++;
05295 assert (nBasic==xxxx->numberRows_);
05296 for (iRow=0;iRow<xxxx->numberRows_;iRow++) {
05297 int iPivot=xxxx->pivotVariable_[iRow];
05298 assert (xxxx->getStatus(iPivot)==basic);
05299 }
05300 #endif
05301 }