00001
00002
00003
00004 #include "CoinPragma.hpp"
00005
00006 #include "ClpSimplex.hpp"
00007 #include "ClpPrimalColumnSteepest.hpp"
00008 #include "CoinIndexedVector.hpp"
00009 #include "ClpFactorization.hpp"
00010 #include "ClpNonLinearCost.hpp"
00011 #include "ClpMessage.hpp"
00012 #include "CoinHelperFunctions.hpp"
00013 #include <stdio.h>
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 ClpPrimalColumnSteepest::ClpPrimalColumnSteepest (int mode)
00024 : ClpPrimalColumnPivot(),
00025 devex_(0.0),
00026 weights_(NULL),
00027 infeasible_(NULL),
00028 alternateWeights_(NULL),
00029 savedWeights_(NULL),
00030 reference_(NULL),
00031 state_(-1),
00032 mode_(mode),
00033 numberSwitched_(0),
00034 pivotSequence_(-1),
00035 savedPivotSequence_(-1),
00036 savedSequenceOut_(-1),
00037 sizeFactorization_(0)
00038 {
00039 type_=2+64*mode;
00040 }
00041
00042
00043
00044
00045 ClpPrimalColumnSteepest::ClpPrimalColumnSteepest (const ClpPrimalColumnSteepest & rhs)
00046 : ClpPrimalColumnPivot(rhs)
00047 {
00048 state_=rhs.state_;
00049 mode_ = rhs.mode_;
00050 numberSwitched_ = rhs.numberSwitched_;
00051 model_ = rhs.model_;
00052 pivotSequence_ = rhs.pivotSequence_;
00053 savedPivotSequence_ = rhs.savedPivotSequence_;
00054 savedSequenceOut_ = rhs.savedSequenceOut_;
00055 sizeFactorization_ = rhs.sizeFactorization_;
00056 devex_ = rhs.devex_;
00057 if (rhs.infeasible_) {
00058 infeasible_= new CoinIndexedVector(rhs.infeasible_);
00059 } else {
00060 infeasible_=NULL;
00061 }
00062 reference_=NULL;
00063 if (rhs.weights_) {
00064 assert(model_);
00065 int number = model_->numberRows()+model_->numberColumns();
00066 weights_= new double[number];
00067 ClpDisjointCopyN(rhs.weights_,number,weights_);
00068 savedWeights_= new double[number];
00069 ClpDisjointCopyN(rhs.savedWeights_,number,savedWeights_);
00070 if (mode_!=1) {
00071 reference_ = new unsigned int[(number+31)>>5];
00072 memcpy(reference_,rhs.reference_,((number+31)>>5)*sizeof(unsigned int));
00073 }
00074 } else {
00075 weights_=NULL;
00076 savedWeights_=NULL;
00077 }
00078 if (rhs.alternateWeights_) {
00079 alternateWeights_= new CoinIndexedVector(rhs.alternateWeights_);
00080 } else {
00081 alternateWeights_=NULL;
00082 }
00083 }
00084
00085
00086
00087
00088 ClpPrimalColumnSteepest::~ClpPrimalColumnSteepest ()
00089 {
00090 delete [] weights_;
00091 delete infeasible_;
00092 delete alternateWeights_;
00093 delete [] savedWeights_;
00094 delete [] reference_;
00095 }
00096
00097
00098
00099
00100 ClpPrimalColumnSteepest &
00101 ClpPrimalColumnSteepest::operator=(const ClpPrimalColumnSteepest& rhs)
00102 {
00103 if (this != &rhs) {
00104 ClpPrimalColumnPivot::operator=(rhs);
00105 state_=rhs.state_;
00106 mode_ = rhs.mode_;
00107 numberSwitched_ = rhs.numberSwitched_;
00108 model_ = rhs.model_;
00109 pivotSequence_ = rhs.pivotSequence_;
00110 savedPivotSequence_ = rhs.savedPivotSequence_;
00111 savedSequenceOut_ = rhs.savedSequenceOut_;
00112 sizeFactorization_ = rhs.sizeFactorization_;
00113 devex_ = rhs.devex_;
00114 delete [] weights_;
00115 delete [] reference_;
00116 reference_=NULL;
00117 delete infeasible_;
00118 delete alternateWeights_;
00119 delete [] savedWeights_;
00120 savedWeights_ = NULL;
00121 if (rhs.infeasible_!=NULL) {
00122 infeasible_= new CoinIndexedVector(rhs.infeasible_);
00123 } else {
00124 infeasible_=NULL;
00125 }
00126 if (rhs.weights_!=NULL) {
00127 assert(model_);
00128 int number = model_->numberRows()+model_->numberColumns();
00129 weights_= new double[number];
00130 ClpDisjointCopyN(rhs.weights_,number,weights_);
00131 savedWeights_= new double[number];
00132 ClpDisjointCopyN(rhs.savedWeights_,number,savedWeights_);
00133 if (mode_!=1) {
00134 reference_ = new unsigned int[(number+31)>>5];
00135 memcpy(reference_,rhs.reference_,
00136 ((number+31)>>5)*sizeof(unsigned int));
00137 }
00138 } else {
00139 weights_=NULL;
00140 }
00141 if (rhs.alternateWeights_!=NULL) {
00142 alternateWeights_= new CoinIndexedVector(rhs.alternateWeights_);
00143 } else {
00144 alternateWeights_=NULL;
00145 }
00146 }
00147 return *this;
00148 }
00149
00150 #define TRY_NORM 1.0e-4
00151 #define ADD_ONE 1.0
00152
00153
00154
00155
00156 int
00157 ClpPrimalColumnSteepest::pivotColumn(CoinIndexedVector * updates,
00158 CoinIndexedVector * spareRow1,
00159 CoinIndexedVector * spareRow2,
00160 CoinIndexedVector * spareColumn1,
00161 CoinIndexedVector * spareColumn2)
00162 {
00163 assert(model_);
00164 if (model_->nonLinearCost()->lookBothWays()||model_->algorithm()==2) {
00165
00166 updates->expand();
00167 return pivotColumnOldMethod(updates,spareRow1,spareRow2,
00168 spareColumn1,spareColumn2);
00169 }
00170 int number=0;
00171 int * index;
00172 double tolerance=model_->currentDualTolerance();
00173
00174
00175 double error = min(1.0e-3,model_->largestDualError());
00176
00177 tolerance = tolerance + error;
00178 int pivotRow = model_->pivotRow();
00179 int anyUpdates;
00180 double * infeas = infeasible_->denseVector();
00181
00182
00183 int switchType;
00184 if (mode_==4)
00185 switchType = 5-numberSwitched_;
00186 else if (mode_>=10)
00187 switchType=3;
00188 else
00189 switchType = mode_;
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199 if (updates->getNumElements()>1) {
00200
00201 anyUpdates=2;
00202 } else if (updates->getNumElements()) {
00203 if (updates->getIndices()[0]==pivotRow&&fabs(updates->denseVector()[0])>1.0e-6) {
00204
00205 anyUpdates=1;
00206
00207
00208 } else {
00209
00210 anyUpdates=2;
00211 }
00212 } else if (pivotSequence_>=0){
00213
00214 anyUpdates=-1;
00215 } else {
00216
00217 anyUpdates=0;
00218 }
00219 int sequenceOut = model_->sequenceOut();
00220 if (switchType==5) {
00221
00222 if (model_->clpMatrix()->canDoPartialPricing()) {
00223 pivotSequence_=-1;
00224 pivotRow=-1;
00225
00226 int numberRows = model_->numberRows();
00227 int numberWanted=0;
00228 int numberColumns = model_->numberColumns();
00229 double ratio = (double) sizeFactorization_/(double) numberRows;
00230
00231 int numberDual = model_->numberDualInfeasibilities();
00232 int numberLook = min(numberDual,numberColumns/10);
00233 if (ratio<1.0) {
00234 numberWanted = 100;
00235 numberWanted = max(numberWanted,numberLook/20);
00236 } else if (ratio<3.0) {
00237 numberWanted = 500;
00238 numberWanted = max(numberWanted,numberLook/15);
00239 } else if (ratio<4.0) {
00240 numberWanted = 1000;
00241 numberWanted = max(numberWanted,numberLook/10);
00242 } else {
00243 switchType=4;
00244
00245 numberSwitched_++;
00246
00247 delete [] weights_;
00248 weights_=NULL;
00249 model_->computeDuals(NULL);
00250 saveWeights(model_,4);
00251 anyUpdates=0;
00252 printf("switching to devex %d nel ratio %g\n",sizeFactorization_,ratio);
00253 }
00254 if (switchType==5) {
00255 if (model_->numberIterations()%1000==0)
00256 printf("numels %d ratio %g wanted %d\n",sizeFactorization_,ratio,numberWanted);
00257
00258
00259 return partialPricing(updates,spareRow2,
00260 numberWanted);
00261 }
00262 }
00263 }
00264 if (switchType==5) {
00265 if (anyUpdates>0) {
00266 justDjs(updates,spareRow1,spareRow2,
00267 spareColumn1,spareColumn2);
00268 }
00269 } else if (anyUpdates==1) {
00270 if (switchType<4) {
00271
00272 djsAndSteepest(updates,spareRow1,spareRow2,
00273 spareColumn1,spareColumn2);
00274 } else {
00275
00276 djsAndDevex(updates,spareRow1,spareRow2,
00277 spareColumn1,spareColumn2);
00278 }
00279 } else if (anyUpdates==-1) {
00280 if (switchType<4) {
00281
00282 justSteepest(updates,spareRow1,spareRow2,
00283 spareColumn1,spareColumn2);
00284 } else {
00285
00286 justDevex(updates,spareRow1,spareRow2,
00287 spareColumn1,spareColumn2);
00288 }
00289 } else if (anyUpdates==2) {
00290 if (switchType<4) {
00291
00292 djsAndSteepest2(updates,spareRow1,spareRow2,
00293 spareColumn1,spareColumn2);
00294 } else {
00295
00296 djsAndDevex2(updates,spareRow1,spareRow2,
00297 spareColumn1,spareColumn2);
00298 }
00299 }
00300 alternateWeights_->checkClear();
00301
00302 if (sequenceOut>=0) {
00303 ClpSimplex::Status status = model_->getStatus(sequenceOut);
00304 double value = model_->reducedCost(sequenceOut);
00305
00306 switch(status) {
00307
00308 case ClpSimplex::basic:
00309 case ClpSimplex::isFixed:
00310 break;
00311 case ClpSimplex::isFree:
00312 case ClpSimplex::superBasic:
00313 if (fabs(value)>FREE_ACCEPT*tolerance) {
00314
00315 value *= FREE_BIAS;
00316
00317 if (infeas[sequenceOut])
00318 infeas[sequenceOut] = value*value;
00319 else
00320 infeasible_->quickAdd(sequenceOut,value*value);
00321 } else {
00322 infeasible_->zero(sequenceOut);
00323 }
00324 break;
00325 case ClpSimplex::atUpperBound:
00326 if (value>tolerance) {
00327
00328 if (infeas[sequenceOut])
00329 infeas[sequenceOut] = value*value;
00330 else
00331 infeasible_->quickAdd(sequenceOut,value*value);
00332 } else {
00333 infeasible_->zero(sequenceOut);
00334 }
00335 break;
00336 case ClpSimplex::atLowerBound:
00337 if (value<-tolerance) {
00338
00339 if (infeas[sequenceOut])
00340 infeas[sequenceOut] = value*value;
00341 else
00342 infeasible_->quickAdd(sequenceOut,value*value);
00343 } else {
00344 infeasible_->zero(sequenceOut);
00345 }
00346 }
00347 }
00348
00349
00350 int numberWanted=0;
00351 number = infeasible_->getNumElements();
00352 int numberColumns = model_->numberColumns();
00353 if (switchType==5) {
00354 pivotSequence_=-1;
00355 pivotRow=-1;
00356
00357 int numberRows = model_->numberRows();
00358
00359
00360 double ratio = (double) sizeFactorization_/(double) numberRows;
00361
00362 if (ratio<1.0) {
00363 numberWanted = max(100,number/200);
00364 } else if (ratio<2.0-1.0) {
00365 numberWanted = max(500,number/40);
00366 } else if (ratio<4.0-3.0) {
00367 numberWanted = max(2000,number/10);
00368 numberWanted = max(numberWanted,numberColumns/30);
00369 } else {
00370 switchType=4;
00371
00372 numberSwitched_++;
00373
00374 delete [] weights_;
00375 weights_=NULL;
00376 saveWeights(model_,4);
00377 printf("switching to devex %d nel ratio %g\n",sizeFactorization_,ratio);
00378 }
00379
00380
00381 }
00382 int numberRows = model_->numberRows();
00383
00384 double ratio = (double) sizeFactorization_/(double) numberRows;
00385 if(switchType==4) {
00386
00387
00388 if (ratio<5.0) {
00389 numberWanted = max(2000,number/10);
00390 numberWanted = max(numberWanted,numberColumns/20);
00391 } else if (ratio<7.0) {
00392 numberWanted = max(2000,number/5);
00393 numberWanted = max(numberWanted,numberColumns/10);
00394 } else {
00395
00396 updates->clear();
00397 spareColumn1->clear();
00398 switchType=3;
00399
00400 pivotSequence_=-1;
00401 pivotRow=-1;
00402 numberSwitched_++;
00403
00404 delete [] weights_;
00405 weights_=NULL;
00406 saveWeights(model_,4);
00407 printf("switching to exact %d nel ratio %g\n",sizeFactorization_,ratio);
00408 updates->clear();
00409 }
00410 if (model_->numberIterations()%1000==0)
00411 printf("numels %d ratio %g wanted %d type x\n",sizeFactorization_,ratio,numberWanted);
00412 }
00413 if (switchType<4) {
00414 if (switchType<2 ) {
00415 numberWanted = number+1;
00416 } else if (switchType==2) {
00417 numberWanted = max(2000,number/8);
00418 } else {
00419 if (ratio<1.0) {
00420 numberWanted = max(2000,number/20);
00421 } else if (ratio<5.0) {
00422 numberWanted = max(2000,number/10);
00423 numberWanted = max(numberWanted,numberColumns/40);
00424 } else if (ratio<10.0) {
00425 numberWanted = max(2000,number/8);
00426 numberWanted = max(numberWanted,numberColumns/20);
00427 } else {
00428 ratio = number * (ratio/80.0);
00429 if (ratio>number) {
00430 numberWanted=number+1;
00431 } else {
00432 numberWanted = max(2000,(int) ratio);
00433 numberWanted = max(numberWanted,numberColumns/10);
00434 }
00435 }
00436 }
00437
00438
00439
00440 }
00441
00442
00443 double bestDj = 1.0e-30;
00444 int bestSequence=-1;
00445
00446 int i,iSequence;
00447 index = infeasible_->getIndices();
00448 number = infeasible_->getNumElements();
00449
00450
00451 if (0&&model_->factorization()->pivots()>0&&
00452 (model_->factorization()->pivots()%100)==0) {
00453 int nLook = model_->numberRows()+numberColumns;
00454 number=0;
00455 for (i=0;i<nLook;i++) {
00456 if (infeas[i]) {
00457 if (fabs(infeas[i])>COIN_INDEXED_TINY_ELEMENT)
00458 index[number++]=i;
00459 else
00460 infeas[i]=0.0;
00461 }
00462 }
00463 infeasible_->setNumElements(number);
00464 }
00465 if(model_->numberIterations()<model_->lastBadIteration()+200) {
00466
00467 double checkTolerance = 1.0e-8;
00468 if (!model_->factorization()->pivots())
00469 checkTolerance = 1.0e-6;
00470 if (model_->largestDualError()>checkTolerance)
00471 tolerance *= model_->largestDualError()/checkTolerance;
00472
00473 tolerance = min(1000.0,tolerance);
00474 }
00475 #ifdef CLP_DEBUG
00476 if (model_->numberDualInfeasibilities()==1)
00477 printf("** %g %g %g %x %x %d\n",tolerance,model_->dualTolerance(),
00478 model_->largestDualError(),model_,model_->messageHandler(),
00479 number);
00480 #endif
00481
00482 double saveOutInfeasibility=0.0;
00483 if (sequenceOut>=0) {
00484 saveOutInfeasibility = infeas[sequenceOut];
00485 infeas[sequenceOut]=0.0;
00486 }
00487 if (model_->factorization()->pivots()&&model_->numberPrimalInfeasibilities())
00488 tolerance = max(tolerance,1.0e-10*model_->infeasibilityCost());
00489 tolerance *= tolerance;
00490
00491 int iPass;
00492
00493 int start[4];
00494 start[1]=number;
00495 start[2]=0;
00496 double dstart = ((double) number) * CoinDrand48();
00497 start[0]=(int) dstart;
00498 start[3]=start[0];
00499
00500
00501 for (iPass=0;iPass<2;iPass++) {
00502 int end = start[2*iPass+1];
00503 if (switchType<5) {
00504 for (i=start[2*iPass];i<end;i++) {
00505 iSequence = index[i];
00506 double value = infeas[iSequence];
00507 if (value>tolerance) {
00508 double weight = weights_[iSequence];
00509
00510 if (value>bestDj*weight) {
00511
00512 if (!model_->flagged(iSequence)) {
00513 bestDj=value/weight;
00514 bestSequence = iSequence;
00515 } else {
00516
00517 numberWanted++;
00518 }
00519 }
00520 }
00521 numberWanted--;
00522 if (!numberWanted)
00523 break;
00524 }
00525 } else {
00526
00527 for (i=start[2*iPass];i<end;i++) {
00528 iSequence = index[i];
00529 double value = infeas[iSequence];
00530 if (value>tolerance) {
00531 if (value>bestDj) {
00532
00533 if (!model_->flagged(iSequence)) {
00534 bestDj=value;
00535 bestSequence = iSequence;
00536 } else {
00537
00538 numberWanted++;
00539 }
00540 }
00541 }
00542 numberWanted--;
00543 if (!numberWanted)
00544 break;
00545 }
00546 }
00547 if (!numberWanted)
00548 break;
00549 }
00550 if (sequenceOut>=0) {
00551 infeas[sequenceOut]=saveOutInfeasibility;
00552 }
00553
00554
00555
00556 #ifndef NDEBUG
00557 if (bestSequence>=0) {
00558 if (model_->getStatus(bestSequence)==ClpSimplex::atLowerBound)
00559 assert(model_->reducedCost(bestSequence)<0.0);
00560 if (model_->getStatus(bestSequence)==ClpSimplex::atUpperBound)
00561 assert(model_->reducedCost(bestSequence)>0.0);
00562 }
00563 #endif
00564 return bestSequence;
00565 }
00566
00567 void
00568 ClpPrimalColumnSteepest::justDjs(CoinIndexedVector * updates,
00569 CoinIndexedVector * spareRow1,
00570 CoinIndexedVector * spareRow2,
00571 CoinIndexedVector * spareColumn1,
00572 CoinIndexedVector * spareColumn2)
00573 {
00574 int iSection,j;
00575 int number=0;
00576 int * index;
00577 double * updateBy;
00578 double * reducedCost;
00579 double tolerance=model_->currentDualTolerance();
00580
00581
00582 double error = min(1.0e-3,model_->largestDualError());
00583
00584 tolerance = tolerance + error;
00585 int pivotRow = model_->pivotRow();
00586 double * infeas = infeasible_->denseVector();
00587
00588 model_->factorization()->updateColumnTranspose(spareRow2,updates);
00589
00590
00591 model_->clpMatrix()->transposeTimes(model_,-1.0,
00592 updates,spareColumn2,spareColumn1);
00593
00594 for (iSection=0;iSection<2;iSection++) {
00595
00596 reducedCost=model_->djRegion(iSection);
00597 int addSequence;
00598
00599 if (!iSection) {
00600 number = updates->getNumElements();
00601 index = updates->getIndices();
00602 updateBy = updates->denseVector();
00603 addSequence = model_->numberColumns();
00604 } else {
00605 number = spareColumn1->getNumElements();
00606 index = spareColumn1->getIndices();
00607 updateBy = spareColumn1->denseVector();
00608 addSequence = 0;
00609 }
00610
00611 for (j=0;j<number;j++) {
00612 int iSequence = index[j];
00613 double value = reducedCost[iSequence];
00614 value -= updateBy[j];
00615 updateBy[j]=0.0;
00616 reducedCost[iSequence] = value;
00617 ClpSimplex::Status status = model_->getStatus(iSequence+addSequence);
00618
00619 switch(status) {
00620
00621 case ClpSimplex::basic:
00622 infeasible_->zero(iSequence+addSequence);
00623 case ClpSimplex::isFixed:
00624 break;
00625 case ClpSimplex::isFree:
00626 case ClpSimplex::superBasic:
00627 if (fabs(value)>FREE_ACCEPT*tolerance) {
00628
00629 value *= FREE_BIAS;
00630
00631 if (infeas[iSequence+addSequence])
00632 infeas[iSequence+addSequence] = value*value;
00633 else
00634 infeasible_->quickAdd(iSequence+addSequence,value*value);
00635 } else {
00636 infeasible_->zero(iSequence+addSequence);
00637 }
00638 break;
00639 case ClpSimplex::atUpperBound:
00640 if (value>tolerance) {
00641
00642 if (infeas[iSequence+addSequence])
00643 infeas[iSequence+addSequence] = value*value;
00644 else
00645 infeasible_->quickAdd(iSequence+addSequence,value*value);
00646 } else {
00647 infeasible_->zero(iSequence+addSequence);
00648 }
00649 break;
00650 case ClpSimplex::atLowerBound:
00651 if (value<-tolerance) {
00652
00653 if (infeas[iSequence+addSequence])
00654 infeas[iSequence+addSequence] = value*value;
00655 else
00656 infeasible_->quickAdd(iSequence+addSequence,value*value);
00657 } else {
00658 infeasible_->zero(iSequence+addSequence);
00659 }
00660 }
00661 }
00662 }
00663 updates->setNumElements(0);
00664 spareColumn1->setNumElements(0);
00665 if (pivotRow>=0) {
00666
00667 int sequenceIn = model_->sequenceIn();
00668 infeasible_->zero(sequenceIn);
00669 }
00670 }
00671
00672 void
00673 ClpPrimalColumnSteepest::djsAndDevex(CoinIndexedVector * updates,
00674 CoinIndexedVector * spareRow1,
00675 CoinIndexedVector * spareRow2,
00676 CoinIndexedVector * spareColumn1,
00677 CoinIndexedVector * spareColumn2)
00678 {
00679 int j;
00680 int number=0;
00681 int * index;
00682 double * updateBy;
00683 double * reducedCost;
00684 double tolerance=model_->currentDualTolerance();
00685
00686
00687 double error = min(1.0e-3,model_->largestDualError());
00688
00689 tolerance = tolerance + error;
00690
00691
00692 assert (pivotSequence_>=0);
00693 pivotSequence_=-1;
00694 double * infeas = infeasible_->denseVector();
00695
00696 model_->factorization()->updateColumnTranspose(spareRow2,updates);
00697
00698 double referenceIn=0.0;
00699 int sequenceIn = model_->sequenceIn();
00700 if (mode_!=1&&reference(sequenceIn))
00701 referenceIn=1.0;
00702
00703 double outgoingWeight=0.0;
00704 int sequenceOut = model_->sequenceOut();
00705 if (sequenceOut>=0)
00706 outgoingWeight=weights_[sequenceOut];
00707
00708 double scaleFactor = 1.0/updates->denseVector()[0];
00709
00710 model_->clpMatrix()->transposeTimes(model_,-1.0,
00711 updates,spareColumn2,spareColumn1);
00712
00713 double * weight;
00714 int numberColumns = model_->numberColumns();
00715
00716 reducedCost=model_->djRegion(0);
00717 int addSequence=model_->numberColumns();;
00718
00719 number = updates->getNumElements();
00720 index = updates->getIndices();
00721 updateBy = updates->denseVector();
00722 weight = weights_+numberColumns;
00723
00724 for (j=0;j<number;j++) {
00725 double thisWeight;
00726 double pivot;
00727 double value3;
00728 int iSequence = index[j];
00729 double value = reducedCost[iSequence];
00730 double value2 = updateBy[j];
00731 updateBy[j]=0.0;
00732 value -= value2;
00733 reducedCost[iSequence] = value;
00734 ClpSimplex::Status status = model_->getStatus(iSequence+addSequence);
00735
00736 switch(status) {
00737
00738 case ClpSimplex::basic:
00739 infeasible_->zero(iSequence+addSequence);
00740 case ClpSimplex::isFixed:
00741 break;
00742 case ClpSimplex::isFree:
00743 case ClpSimplex::superBasic:
00744 thisWeight = weight[iSequence];
00745
00746 pivot = value2*scaleFactor;
00747 value3 = pivot * pivot*devex_;
00748 if (reference(iSequence+numberColumns))
00749 value3 += 1.0;
00750 weight[iSequence] = max(0.99*thisWeight,value3);
00751 if (fabs(value)>FREE_ACCEPT*tolerance) {
00752
00753 value *= FREE_BIAS;
00754
00755 if (infeas[iSequence+addSequence])
00756 infeas[iSequence+addSequence] = value*value;
00757 else
00758 infeasible_->quickAdd(iSequence+addSequence,value*value);
00759 } else {
00760 infeasible_->zero(iSequence+addSequence);
00761 }
00762 break;
00763 case ClpSimplex::atUpperBound:
00764 thisWeight = weight[iSequence];
00765
00766 pivot = value2*scaleFactor;
00767 value3 = pivot * pivot*devex_;
00768 if (reference(iSequence+numberColumns))
00769 value3 += 1.0;
00770 weight[iSequence] = max(0.99*thisWeight,value3);
00771 if (value>tolerance) {
00772
00773 if (infeas[iSequence+addSequence])
00774 infeas[iSequence+addSequence] = value*value;
00775 else
00776 infeasible_->quickAdd(iSequence+addSequence,value*value);
00777 } else {
00778 infeasible_->zero(iSequence+addSequence);
00779 }
00780 break;
00781 case ClpSimplex::atLowerBound:
00782 thisWeight = weight[iSequence];
00783
00784 pivot = value2*scaleFactor;
00785 value3 = pivot * pivot*devex_;
00786 if (reference(iSequence+numberColumns))
00787 value3 += 1.0;
00788 weight[iSequence] = max(0.99*thisWeight,value3);
00789 if (value<-tolerance) {
00790
00791 if (infeas[iSequence+addSequence])
00792 infeas[iSequence+addSequence] = value*value;
00793 else
00794 infeasible_->quickAdd(iSequence+addSequence,value*value);
00795 } else {
00796 infeasible_->zero(iSequence+addSequence);
00797 }
00798 }
00799 }
00800
00801
00802 weight = weights_;
00803
00804 scaleFactor = -scaleFactor;
00805 reducedCost=model_->djRegion(1);
00806 number = spareColumn1->getNumElements();
00807 index = spareColumn1->getIndices();
00808 updateBy = spareColumn1->denseVector();
00809
00810
00811
00812 for (j=0;j<number;j++) {
00813 double thisWeight;
00814 double pivot;
00815 double value3;
00816 int iSequence = index[j];
00817 double value = reducedCost[iSequence];
00818 double value2 = updateBy[j];
00819 value -= value2;
00820 updateBy[j]=0.0;
00821 reducedCost[iSequence] = value;
00822 ClpSimplex::Status status = model_->getStatus(iSequence);
00823
00824 switch(status) {
00825
00826 case ClpSimplex::basic:
00827 infeasible_->zero(iSequence);
00828 case ClpSimplex::isFixed:
00829 break;
00830 case ClpSimplex::isFree:
00831 case ClpSimplex::superBasic:
00832 thisWeight = weight[iSequence];
00833
00834 pivot = value2*scaleFactor;
00835 value3 = pivot * pivot*devex_;
00836 if (reference(iSequence))
00837 value3 += 1.0;
00838 weight[iSequence] = max(0.99*thisWeight,value3);
00839 if (fabs(value)>FREE_ACCEPT*tolerance) {
00840
00841 value *= FREE_BIAS;
00842
00843 if (infeas[iSequence])
00844 infeas[iSequence] = value*value;
00845 else
00846 infeasible_->quickAdd(iSequence,value*value);
00847 } else {
00848 infeasible_->zero(iSequence);
00849 }
00850 break;
00851 case ClpSimplex::atUpperBound:
00852 thisWeight = weight[iSequence];
00853
00854 pivot = value2*scaleFactor;
00855 value3 = pivot * pivot*devex_;
00856 if (reference(iSequence))
00857 value3 += 1.0;
00858 weight[iSequence] = max(0.99*thisWeight,value3);
00859 if (value>tolerance) {
00860
00861 if (infeas[iSequence])
00862 infeas[iSequence] = value*value;
00863 else
00864 infeasible_->quickAdd(iSequence,value*value);
00865 } else {
00866 infeasible_->zero(iSequence);
00867 }
00868 break;
00869 case ClpSimplex::atLowerBound:
00870 thisWeight = weight[iSequence];
00871
00872 pivot = value2*scaleFactor;
00873 value3 = pivot * pivot*devex_;
00874 if (reference(iSequence))
00875 value3 += 1.0;
00876 weight[iSequence] = max(0.99*thisWeight,value3);
00877 if (value<-tolerance) {
00878
00879 if (infeas[iSequence])
00880 infeas[iSequence] = value*value;
00881 else
00882 infeasible_->quickAdd(iSequence,value*value);
00883 } else {
00884 infeasible_->zero(iSequence);
00885 }
00886 }
00887 }
00888
00889 if (sequenceOut>=0)
00890 weights_[sequenceOut]=outgoingWeight;
00891
00892 infeasible_->zero(sequenceIn);
00893 spareRow2->setNumElements(0);
00894
00895 #ifdef SOME_DEBUG_1
00896
00897 int iCheck=229;
00898
00899 int numberRows = model_->numberRows();
00900
00901 for (iCheck=0;iCheck<numberRows+numberColumns;iCheck++) {
00902 if (model_->getStatus(iCheck)!=ClpSimplex::basic&&
00903 !model_->getStatus(iCheck)!=ClpSimplex::isFixed)
00904 checkAccuracy(iCheck,1.0e-1,updates,spareRow2);
00905 }
00906 #endif
00907 updates->setNumElements(0);
00908 spareColumn1->setNumElements(0);
00909 }
00910
00911 void
00912 ClpPrimalColumnSteepest::djsAndSteepest(CoinIndexedVector * updates,
00913 CoinIndexedVector * spareRow1,
00914 CoinIndexedVector * spareRow2,
00915 CoinIndexedVector * spareColumn1,
00916 CoinIndexedVector * spareColumn2)
00917 {
00918 int j;
00919 int number=0;
00920 int * index;
00921 double * updateBy;
00922 double * reducedCost;
00923 double tolerance=model_->currentDualTolerance();
00924
00925
00926 double error = min(1.0e-3,model_->largestDualError());
00927
00928 tolerance = tolerance + error;
00929
00930
00931 assert (pivotSequence_>=0);
00932 pivotSequence_=-1;
00933 double * infeas = infeasible_->denseVector();
00934 double scaleFactor = 1.0/updates->denseVector()[0];
00935
00936 model_->factorization()->updateColumnTranspose(spareRow2,updates);
00937
00938 model_->factorization()->updateColumnTranspose(spareRow2,
00939 alternateWeights_);
00940
00941 double referenceIn=0.0;
00942 int sequenceIn = model_->sequenceIn();
00943 if (mode_!=1&&reference(sequenceIn))
00944 referenceIn=1.0;
00945
00946 double outgoingWeight=0.0;
00947 int sequenceOut = model_->sequenceOut();
00948 if (sequenceOut>=0)
00949 outgoingWeight=weights_[sequenceOut];
00950
00951
00952 model_->clpMatrix()->transposeTimes(model_,-1.0,
00953 updates,spareColumn2,spareColumn1);
00954
00955
00956 model_->clpMatrix()->subsetTransposeTimes(model_,alternateWeights_,
00957 spareColumn1,
00958 spareRow2);
00959
00960 double * weight;
00961 double * other = alternateWeights_->denseVector();
00962 int numberColumns = model_->numberColumns();
00963
00964 reducedCost=model_->djRegion(0);
00965 int addSequence=model_->numberColumns();;
00966
00967 number = updates->getNumElements();
00968 index = updates->getIndices();
00969 updateBy = updates->denseVector();
00970 weight = weights_+numberColumns;
00971
00972 for (j=0;j<number;j++) {
00973 double thisWeight;
00974 double pivot;
00975 double modification;
00976 double pivotSquared;
00977 int iSequence = index[j];
00978 double value = reducedCost[iSequence];
00979 double value2 = updateBy[j];
00980 value -= value2;
00981 reducedCost[iSequence] = value;
00982 ClpSimplex::Status status = model_->getStatus(iSequence+addSequence);
00983 modification = other[iSequence];
00984 updateBy[j]=0.0;
00985
00986 switch(status) {
00987
00988 case ClpSimplex::basic:
00989 infeasible_->zero(iSequence+addSequence);
00990 case ClpSimplex::isFixed:
00991 break;
00992 case ClpSimplex::isFree:
00993 case ClpSimplex::superBasic:
00994 thisWeight = weight[iSequence];
00995
00996 pivot = value2*scaleFactor;
00997 pivotSquared = pivot * pivot;
00998
00999 thisWeight += pivotSquared * devex_ + pivot * modification;
01000 if (thisWeight<TRY_NORM) {
01001 if (mode_==1) {
01002
01003 thisWeight = max(TRY_NORM,ADD_ONE+pivotSquared);
01004 } else {
01005
01006 thisWeight = referenceIn*pivotSquared;
01007 if (reference(iSequence+numberColumns))
01008 thisWeight += 1.0;
01009 thisWeight = max(thisWeight,TRY_NORM);
01010 }
01011 }
01012 weight[iSequence] = thisWeight;
01013 if (fabs(value)>FREE_ACCEPT*tolerance) {
01014
01015 value *= FREE_BIAS;
01016
01017 if (infeas[iSequence+addSequence])
01018 infeas[iSequence+addSequence] = value*value;
01019 else
01020 infeasible_->quickAdd(iSequence+addSequence,value*value);
01021 } else {
01022 infeasible_->zero(iSequence+addSequence);
01023 }
01024 break;
01025 case ClpSimplex::atUpperBound:
01026 thisWeight = weight[iSequence];
01027
01028 pivot = value2*scaleFactor;
01029 pivotSquared = pivot * pivot;
01030
01031 thisWeight += pivotSquared * devex_ + pivot * modification;
01032 if (thisWeight<TRY_NORM) {
01033 if (mode_==1) {
01034
01035 thisWeight = max(TRY_NORM,ADD_ONE+pivotSquared);
01036 } else {
01037
01038 thisWeight = referenceIn*pivotSquared;
01039 if (reference(iSequence+numberColumns))
01040 thisWeight += 1.0;
01041 thisWeight = max(thisWeight,TRY_NORM);
01042 }
01043 }
01044 weight[iSequence] = thisWeight;
01045 if (value>tolerance) {
01046
01047 if (infeas[iSequence+addSequence])
01048 infeas[iSequence+addSequence] = value*value;
01049 else
01050 infeasible_->quickAdd(iSequence+addSequence,value*value);
01051 } else {
01052 infeasible_->zero(iSequence+addSequence);
01053 }
01054 break;
01055 case ClpSimplex::atLowerBound:
01056 thisWeight = weight[iSequence];
01057
01058 pivot = value2*scaleFactor;
01059 pivotSquared = pivot * pivot;
01060
01061 thisWeight += pivotSquared * devex_ + pivot * modification;
01062 if (thisWeight<TRY_NORM) {
01063 if (mode_==1) {
01064
01065 thisWeight = max(TRY_NORM,ADD_ONE+pivotSquared);
01066 } else {
01067
01068 thisWeight = referenceIn*pivotSquared;
01069 if (reference(iSequence+numberColumns))
01070 thisWeight += 1.0;
01071 thisWeight = max(thisWeight,TRY_NORM);
01072 }
01073 }
01074 weight[iSequence] = thisWeight;
01075 if (value<-tolerance) {
01076
01077 if (infeas[iSequence+addSequence])
01078 infeas[iSequence+addSequence] = value*value;
01079 else
01080 infeasible_->quickAdd(iSequence+addSequence,value*value);
01081 } else {
01082 infeasible_->zero(iSequence+addSequence);
01083 }
01084 }
01085 }
01086 alternateWeights_->clear();
01087
01088 weight = weights_;
01089
01090 scaleFactor = -scaleFactor;
01091 reducedCost=model_->djRegion(1);
01092 number = spareColumn1->getNumElements();
01093 index = spareColumn1->getIndices();
01094 updateBy = spareColumn1->denseVector();
01095 double * updateBy2 = spareRow2->denseVector();
01096
01097 for (j=0;j<number;j++) {
01098 double thisWeight;
01099 double pivot;
01100 double modification;
01101 double pivotSquared;
01102 int iSequence = index[j];
01103 double value = reducedCost[iSequence];
01104 double value2 = updateBy[j];
01105 updateBy[j]=0.0;
01106 value -= value2;
01107 reducedCost[iSequence] = value;
01108 ClpSimplex::Status status = model_->getStatus(iSequence);
01109
01110 switch(status) {
01111
01112 case ClpSimplex::basic:
01113 infeasible_->zero(iSequence);
01114 updateBy2[j]=0.0;
01115 case ClpSimplex::isFixed:
01116 updateBy2[j]=0.0;
01117 break;
01118 case ClpSimplex::isFree:
01119 case ClpSimplex::superBasic:
01120 thisWeight = weight[iSequence];
01121 pivot = value2*scaleFactor;
01122 modification = updateBy2[j];
01123 updateBy2[j]=0.0;
01124 pivotSquared = pivot * pivot;
01125
01126 thisWeight += pivotSquared * devex_ + pivot * modification;
01127 if (thisWeight<TRY_NORM) {
01128 if (mode_==1) {
01129
01130 thisWeight = max(TRY_NORM,ADD_ONE+pivotSquared);
01131 } else {
01132
01133 thisWeight = referenceIn*pivotSquared;
01134 if (reference(iSequence))
01135 thisWeight += 1.0;
01136 thisWeight = max(thisWeight,TRY_NORM);
01137 }
01138 }
01139 weight[iSequence] = thisWeight;
01140 if (fabs(value)>FREE_ACCEPT*tolerance) {
01141
01142 value *= FREE_BIAS;
01143
01144 if (infeas[iSequence])
01145 infeas[iSequence] = value*value;
01146 else
01147 infeasible_->quickAdd(iSequence,value*value);
01148 } else {
01149 infeasible_->zero(iSequence);
01150 }
01151 break;
01152 case ClpSimplex::atUpperBound:
01153 thisWeight = weight[iSequence];
01154 pivot = value2*scaleFactor;
01155 modification = updateBy2[j];
01156 updateBy2[j]=0.0;
01157 pivotSquared = pivot * pivot;
01158
01159 thisWeight += pivotSquared * devex_ + pivot * modification;
01160 if (thisWeight<TRY_NORM) {
01161 if (mode_==1) {
01162
01163 thisWeight = max(TRY_NORM,ADD_ONE+pivotSquared);
01164 } else {
01165
01166 thisWeight = referenceIn*pivotSquared;
01167 if (reference(iSequence))
01168 thisWeight += 1.0;
01169 thisWeight = max(thisWeight,TRY_NORM);
01170 }
01171 }
01172 weight[iSequence] = thisWeight;
01173 if (value>tolerance) {
01174
01175 if (infeas[iSequence])
01176 infeas[iSequence] = value*value;
01177 else
01178 infeasible_->quickAdd(iSequence,value*value);
01179 } else {
01180 infeasible_->zero(iSequence);
01181 }
01182 break;
01183 case ClpSimplex::atLowerBound:
01184 thisWeight = weight[iSequence];
01185 pivot = value2*scaleFactor;
01186 modification = updateBy2[j];
01187 updateBy2[j]=0.0;
01188 pivotSquared = pivot * pivot;
01189
01190 thisWeight += pivotSquared * devex_ + pivot * modification;
01191 if (thisWeight<TRY_NORM) {
01192 if (mode_==1) {
01193
01194 thisWeight = max(TRY_NORM,ADD_ONE+pivotSquared);
01195 } else {
01196
01197 thisWeight = referenceIn*pivotSquared;
01198 if (reference(iSequence))
01199 thisWeight += 1.0;
01200 thisWeight = max(thisWeight,TRY_NORM);
01201 }
01202 }
01203 weight[iSequence] = thisWeight;
01204 if (value<-tolerance) {
01205
01206 if (infeas[iSequence])
01207 infeas[iSequence] = value*value;
01208 else
01209 infeasible_->quickAdd(iSequence,value*value);
01210 } else {
01211 infeasible_->zero(iSequence);
01212 }
01213 }
01214 }
01215
01216 if (sequenceOut>=0)
01217 weights_[sequenceOut]=outgoingWeight;
01218
01219 infeasible_->zero(sequenceIn);
01220 spareRow2->setNumElements(0);
01221
01222 #ifdef SOME_DEBUG_1
01223
01224 int iCheck=229;
01225
01226 int numberRows = model_->numberRows();
01227
01228 for (iCheck=0;iCheck<numberRows+numberColumns;iCheck++) {
01229 if (model_->getStatus(iCheck)!=ClpSimplex::basic&&
01230 !model_->getStatus(iCheck)!=ClpSimplex::isFixed)
01231 checkAccuracy(iCheck,1.0e-1,updates,spareRow2);
01232 }
01233 #endif
01234 updates->setNumElements(0);
01235 spareColumn1->setNumElements(0);
01236 }
01237
01238 void
01239 ClpPrimalColumnSteepest::djsAndDevex2(CoinIndexedVector * updates,
01240 CoinIndexedVector * spareRow1,
01241 CoinIndexedVector * spareRow2,
01242 CoinIndexedVector * spareColumn1,
01243 CoinIndexedVector * spareColumn2)
01244 {
01245 int iSection,j;
01246 int number=0;
01247 int * index;
01248 double * updateBy;
01249 double * reducedCost;
01250
01251 double dj = model_->dualIn();
01252 double tolerance=model_->currentDualTolerance();
01253
01254
01255 double error = min(1.0e-3,model_->largestDualError());
01256
01257 tolerance = tolerance + error;
01258 int pivotRow = model_->pivotRow();
01259 double * infeas = infeasible_->denseVector();
01260
01261 model_->factorization()->updateColumnTranspose(spareRow2,updates);
01262
01263
01264 model_->clpMatrix()->transposeTimes(model_,-1.0,
01265 updates,spareColumn2,spareColumn1);
01266
01267 for (iSection=0;iSection<2;iSection++) {
01268
01269 reducedCost=model_->djRegion(iSection);
01270 int addSequence;
01271
01272 if (!iSection) {
01273 number = updates->getNumElements();
01274 index = updates->getIndices();
01275 updateBy = updates->denseVector();
01276 addSequence = model_->numberColumns();
01277 } else {
01278 number = spareColumn1->getNumElements();
01279 index = spareColumn1->getIndices();
01280 updateBy = spareColumn1->denseVector();
01281 addSequence = 0;
01282 }
01283
01284 for (j=0;j<number;j++) {
01285 int iSequence = index[j];
01286 double value = reducedCost[iSequence];
01287 value -= updateBy[j];
01288 updateBy[j]=0.0;
01289 reducedCost[iSequence] = value;
01290 ClpSimplex::Status status = model_->getStatus(iSequence+addSequence);
01291
01292 switch(status) {
01293
01294 case ClpSimplex::basic:
01295 infeasible_->zero(iSequence+addSequence);
01296 case ClpSimplex::isFixed:
01297 break;
01298 case ClpSimplex::isFree:
01299 case ClpSimplex::superBasic:
01300 if (fabs(value)>FREE_ACCEPT*tolerance) {
01301
01302 value *= FREE_BIAS;
01303
01304 if (infeas[iSequence+addSequence])
01305 infeas[iSequence+addSequence] = value*value;
01306 else
01307 infeasible_->quickAdd(iSequence+addSequence,value*value);
01308 } else {
01309 infeasible_->zero(iSequence+addSequence);
01310 }
01311 break;
01312 case ClpSimplex::atUpperBound:
01313 if (value>tolerance) {
01314
01315 if (infeas[iSequence+addSequence])
01316 infeas[iSequence+addSequence] = value*value;
01317 else
01318 infeasible_->quickAdd(iSequence+addSequence,value*value);
01319 } else {
01320 infeasible_->zero(iSequence+addSequence);
01321 }
01322 break;
01323 case ClpSimplex::atLowerBound:
01324 if (value<-tolerance) {
01325
01326 if (infeas[iSequence+addSequence])
01327 infeas[iSequence+addSequence] = value*value;
01328 else
01329 infeasible_->quickAdd(iSequence+addSequence,value*value);
01330 } else {
01331 infeasible_->zero(iSequence+addSequence);
01332 }
01333 }
01334 }
01335 }
01336
01337 updates->setNumElements(0);
01338 spareColumn1->setNumElements(0);
01339
01340 int sequenceIn = model_->sequenceIn();
01341 infeasible_->zero(sequenceIn);
01342
01343 if (pivotSequence_>=0) {
01344 pivotRow = pivotSequence_;
01345
01346 pivotSequence_=-1;
01347
01348 const int * pivotVariable = model_->pivotVariable();
01349 sequenceIn = pivotVariable[pivotRow];
01350 infeasible_->zero(sequenceIn);
01351
01352 double referenceIn=0.0;
01353 if (mode_!=1&&reference(sequenceIn))
01354 referenceIn=1.0;
01355
01356 double outgoingWeight=0.0;
01357 int sequenceOut = model_->sequenceOut();
01358 if (sequenceOut>=0)
01359 outgoingWeight=weights_[sequenceOut];
01360
01361 updates->setNumElements(0);
01362 spareColumn1->setNumElements(0);
01363
01364 dj = 1.0;
01365 updates->insert(pivotRow,-dj);
01366 model_->factorization()->updateColumnTranspose(spareRow2,updates);
01367
01368 model_->clpMatrix()->transposeTimes(model_,-1.0,
01369 updates,spareColumn2,spareColumn1);
01370 double * weight;
01371 int numberColumns = model_->numberColumns();
01372
01373 number = updates->getNumElements();
01374 index = updates->getIndices();
01375 updateBy = updates->denseVector();
01376 weight = weights_+numberColumns;
01377
01378 assert (devex_>0.0);
01379 for (j=0;j<number;j++) {
01380 int iSequence = index[j];
01381 double thisWeight = weight[iSequence];
01382
01383 double pivot = - updateBy[iSequence];
01384 updateBy[iSequence]=0.0;
01385 double value = pivot * pivot*devex_;
01386 if (reference(iSequence+numberColumns))
01387 value += 1.0;
01388 weight[iSequence] = max(0.99*thisWeight,value);
01389 }
01390
01391
01392 weight = weights_;
01393
01394 number = spareColumn1->getNumElements();
01395 index = spareColumn1->getIndices();
01396 updateBy = spareColumn1->denseVector();
01397 for (j=0;j<number;j++) {
01398 int iSequence = index[j];
01399 double thisWeight = weight[iSequence];
01400
01401 double pivot = updateBy[iSequence];
01402 updateBy[iSequence]=0.0;
01403 double value = pivot * pivot*devex_;
01404 if (reference(iSequence))
01405 value += 1.0;
01406 weight[iSequence] = max(0.99*thisWeight,value);
01407 }
01408
01409 if (sequenceOut>=0)
01410 weights_[sequenceOut]=outgoingWeight;
01411 spareColumn2->setNumElements(0);
01412
01413 #ifdef SOME_DEBUG_1
01414
01415 int iCheck=229;
01416
01417 int numberRows = model_->numberRows();
01418
01419 for (iCheck=0;iCheck<numberRows+numberColumns;iCheck++) {
01420 if (model_->getStatus(iCheck)!=ClpSimplex::basic&&
01421 !model_->getStatus(iCheck)!=ClpSimplex::isFixed)
01422 checkAccuracy(iCheck,1.0e-1,updates,spareRow2);
01423 }
01424 #endif
01425 updates->setNumElements(0);
01426 spareColumn1->setNumElements(0);
01427 }
01428 }
01429
01430 void
01431 ClpPrimalColumnSteepest::djsAndSteepest2(CoinIndexedVector * updates,
01432 CoinIndexedVector * spareRow1,
01433 CoinIndexedVector * spareRow2,
01434 CoinIndexedVector * spareColumn1,
01435 CoinIndexedVector * spareColumn2)
01436 {
01437 int iSection,j;
01438 int number=0;
01439 int * index;
01440 double * updateBy;
01441 double * reducedCost;
01442
01443 double dj = model_->dualIn();
01444 double tolerance=model_->currentDualTolerance();
01445
01446
01447 double error = min(1.0e-3,model_->largestDualError());
01448
01449 tolerance = tolerance + error;
01450 int pivotRow = model_->pivotRow();
01451 double * infeas = infeasible_->denseVector();
01452
01453 model_->factorization()->updateColumnTranspose(spareRow2,updates);
01454
01455
01456 model_->clpMatrix()->transposeTimes(model_,-1.0,
01457 updates,spareColumn2,spareColumn1);
01458
01459 for (iSection=0;iSection<2;iSection++) {
01460
01461 reducedCost=model_->djRegion(iSection);
01462 int addSequence;
01463
01464 if (!iSection) {
01465 number = updates->getNumElements();
01466 index = updates->getIndices();
01467 updateBy = updates->denseVector();
01468 addSequence = model_->numberColumns();
01469 } else {
01470 number = spareColumn1->getNumElements();
01471 index = spareColumn1->getIndices();
01472 updateBy = spareColumn1->denseVector();
01473 addSequence = 0;
01474 }
01475
01476 for (j=0;j<number;j++) {
01477 int iSequence = index[j];
01478 double value = reducedCost[iSequence];
01479 value -= updateBy[j];
01480 updateBy[j]=0.0;
01481 reducedCost[iSequence] = value;
01482 ClpSimplex::Status status = model_->getStatus(iSequence+addSequence);
01483
01484 switch(status) {
01485
01486 case ClpSimplex::basic:
01487 infeasible_->zero(iSequence+addSequence);
01488 case ClpSimplex::isFixed:
01489 break;
01490 case ClpSimplex::isFree:
01491 case ClpSimplex::superBasic:
01492 if (fabs(value)>FREE_ACCEPT*tolerance) {
01493
01494 value *= FREE_BIAS;
01495
01496 if (infeas[iSequence+addSequence])
01497 infeas[iSequence+addSequence] = value*value;
01498 else
01499 infeasible_->quickAdd(iSequence+addSequence,value*value);
01500 } else {
01501 infeasible_->zero(iSequence+addSequence);
01502 }
01503 break;
01504 case ClpSimplex::atUpperBound:
01505 if (value>tolerance) {
01506
01507 if (infeas[iSequence+addSequence])
01508 infeas[iSequence+addSequence] = value*value;
01509 else
01510 infeasible_->quickAdd(iSequence+addSequence,value*value);
01511 } else {
01512 infeasible_->zero(iSequence+addSequence);
01513 }
01514 break;
01515 case ClpSimplex::atLowerBound:
01516 if (value<-tolerance) {
01517
01518 if (infeas[iSequence+addSequence])
01519 infeas[iSequence+addSequence] = value*value;
01520 else
01521 infeasible_->quickAdd(iSequence+addSequence,value*value);
01522 } else {
01523 infeasible_->zero(iSequence+addSequence);
01524 }
01525 }
01526 }
01527 }
01528
01529
01530 updates->setNumElements(0);
01531 spareColumn1->setNumElements(0);
01532 if (pivotRow>=0) {
01533
01534 int sequenceIn = model_->sequenceIn();
01535 infeasible_->zero(sequenceIn);
01536 }
01537
01538 pivotRow = pivotSequence_;
01539
01540 pivotSequence_=-1;
01541 if (pivotRow>=0) {
01542
01543 const int * pivotVariable = model_->pivotVariable();
01544 int sequenceIn = pivotVariable[pivotRow];
01545 infeasible_->zero(sequenceIn);
01546
01547 double referenceIn=0.0;
01548 if (mode_!=1&&reference(sequenceIn))
01549 referenceIn=1.0;
01550
01551 double outgoingWeight=0.0;
01552 int sequenceOut = model_->sequenceOut();
01553 if (sequenceOut>=0)
01554 outgoingWeight=weights_[sequenceOut];
01555
01556 updates->setNumElements(0);
01557 spareColumn1->setNumElements(0);
01558
01559 dj = -1.0;
01560 updates->createPacked(1,&pivotRow,&dj);
01561 model_->factorization()->updateColumnTranspose(spareRow2,updates);
01562
01563 model_->clpMatrix()->transposeTimes(model_,-1.0,
01564 updates,spareColumn2,spareColumn1);
01565 double * weight;
01566 double * other = alternateWeights_->denseVector();
01567 int numberColumns = model_->numberColumns();
01568
01569 number = updates->getNumElements();
01570 index = updates->getIndices();
01571 updateBy = updates->denseVector();
01572 weight = weights_+numberColumns;
01573
01574 if (mode_<4||numberSwitched_>1||mode_>=10) {
01575
01576
01577
01578 model_->factorization()->updateColumnTranspose(spareRow2,
01579 alternateWeights_);
01580
01581
01582 model_->clpMatrix()->subsetTransposeTimes(model_,alternateWeights_,
01583 spareColumn1,
01584 spareColumn2);
01585 for (j=0;j<number;j++) {
01586 int iSequence = index[j];
01587 double thisWeight = weight[iSequence];
01588
01589 double pivot = - updateBy[j];
01590 updateBy[j]=0.0;
01591 double modification = other[iSequence];
01592 double pivotSquared = pivot * pivot;
01593
01594 thisWeight += pivotSquared * devex_ + pivot * modification;
01595 if (thisWeight<TRY_NORM) {
01596 if (mode_==1) {
01597
01598 thisWeight = max(TRY_NORM,ADD_ONE+pivotSquared);
01599 } else {
01600
01601 thisWeight = referenceIn*pivotSquared;
01602 if (reference(iSequence+numberColumns))
01603 thisWeight += 1.0;
01604 thisWeight = max(thisWeight,TRY_NORM);
01605 }
01606 }
01607 weight[iSequence] = thisWeight;
01608 }
01609 } else if (mode_==4) {
01610
01611 assert (devex_>0.0);
01612 for (j=0;j<number;j++) {
01613 int iSequence = index[j];
01614 double thisWeight = weight[iSequence];
01615
01616 double pivot = -updateBy[j];
01617 updateBy[j]=0.0;
01618 double value = pivot * pivot*devex_;
01619 if (reference(iSequence+numberColumns))
01620 value += 1.0;
01621 weight[iSequence] = max(0.99*thisWeight,value);
01622 }
01623 }
01624
01625
01626 weight = weights_;
01627
01628 number = spareColumn1->getNumElements();
01629 index = spareColumn1->getIndices();
01630 updateBy = spareColumn1->denseVector();
01631 if (mode_<4||numberSwitched_>1||mode_>=10) {
01632
01633 double * updateBy2 = spareColumn2->denseVector();
01634 for (j=0;j<number;j++) {
01635 int iSequence = index[j];
01636 double thisWeight = weight[iSequence];
01637 double pivot = updateBy[j];
01638 updateBy[j]=0.0;
01639 double modification = updateBy2[j];
01640 updateBy2[j]=0.0;
01641 double pivotSquared = pivot * pivot;
01642
01643 thisWeight += pivotSquared * devex_ + pivot * modification;
01644 if (thisWeight<TRY_NORM) {
01645 if (mode_==1) {
01646
01647 thisWeight = max(TRY_NORM,ADD_ONE+pivotSquared);
01648 } else {
01649
01650 thisWeight = referenceIn*pivotSquared;
01651 if (reference(iSequence))
01652 thisWeight += 1.0;
01653 thisWeight = max(thisWeight,TRY_NORM);
01654 }
01655 }
01656 weight[iSequence] = thisWeight;
01657 }
01658 } else if (mode_==4) {
01659
01660 for (j=0;j<number;j++) {
01661 int iSequence = index[j];
01662 double thisWeight = weight[iSequence];
01663
01664 double pivot = updateBy[j];
01665 updateBy[j]=0.0;
01666 double value = pivot * pivot*devex_;
01667 if (reference(iSequence))
01668 value += 1.0;
01669 weight[iSequence] = max(0.99*thisWeight,value);
01670 }
01671 }
01672
01673 if (sequenceOut>=0)
01674 weights_[sequenceOut]=outgoingWeight;
01675 alternateWeights_->clear();
01676 spareColumn2->setNumElements(0);
01677
01678 #ifdef SOME_DEBUG_1
01679
01680 int iCheck=229;
01681
01682 int numberRows = model_->numberRows();
01683
01684 for (iCheck=0;iCheck<numberRows+numberColumns;iCheck++) {
01685 if (model_->getStatus(iCheck)!=ClpSimplex::basic&&
01686 !model_->getStatus(iCheck)!=ClpSimplex::isFixed)
01687 checkAccuracy(iCheck,1.0e-1,updates,spareRow2);
01688 }
01689 #endif
01690 }
01691 updates->setNumElements(0);
01692 spareColumn1->setNumElements(0);
01693 }
01694
01695 void
01696 ClpPrimalColumnSteepest::justDevex(CoinIndexedVector * updates,
01697 CoinIndexedVector * spareRow1,
01698 CoinIndexedVector * spareRow2,
01699 CoinIndexedVector * spareColumn1,
01700 CoinIndexedVector * spareColumn2)
01701 {
01702 int j;
01703 int number=0;
01704 int * index;
01705 double * updateBy;
01706
01707 double dj = model_->dualIn();
01708 double tolerance=model_->currentDualTolerance();
01709
01710
01711 double error = min(1.0e-3,model_->largestDualError());
01712
01713 tolerance = tolerance + error;
01714 int pivotRow = model_->pivotRow();
01715
01716 pivotRow = pivotSequence_;
01717 assert (pivotRow>=0);
01718
01719 const int * pivotVariable = model_->pivotVariable();
01720 int sequenceIn = pivotVariable[pivotRow];
01721 infeasible_->zero(sequenceIn);
01722
01723 double referenceIn=0.0;
01724 if (mode_!=1&&reference(sequenceIn))
01725 referenceIn=1.0;
01726
01727 double outgoingWeight=0.0;
01728 int sequenceOut = model_->sequenceOut();
01729 if (sequenceOut>=0)
01730 outgoingWeight=weights_[sequenceOut];
01731 assert (!updates->getNumElements());
01732 assert (!spareColumn1->getNumElements());
01733
01734 pivotSequence_=-1;
01735
01736 dj = -1.0;
01737 updates->createPacked(1,&pivotRow,&dj);
01738 model_->factorization()->updateColumnTranspose(spareRow2,updates);
01739
01740 model_->clpMatrix()->transposeTimes(model_,-1.0,
01741 updates,spareColumn2,spareColumn1);
01742 double * weight;
01743 int numberColumns = model_->numberColumns();
01744
01745 number = updates->getNumElements();
01746 index = updates->getIndices();
01747 updateBy = updates->denseVector();
01748 weight = weights_+numberColumns;
01749
01750
01751 assert (devex_>0.0);
01752 for (j=0;j<number;j++) {
01753 int iSequence = index[j];
01754 double thisWeight = weight[iSequence];
01755
01756 double pivot = - updateBy[j];
01757 updateBy[j]=0.0;
01758 double value = pivot * pivot*devex_;
01759 if (reference(iSequence+numberColumns))
01760 value += 1.0;
01761 weight[iSequence] = max(0.99*thisWeight,value);
01762 }
01763
01764
01765 weight = weights_;
01766
01767 number = spareColumn1->getNumElements();
01768 index = spareColumn1->getIndices();
01769 updateBy = spareColumn1->denseVector();
01770
01771 for (j=0;j<number;j++) {
01772 int iSequence = index[j];
01773 double thisWeight = weight[iSequence];
01774
01775 double pivot = updateBy[j];
01776 updateBy[j]=0.0;
01777 double value = pivot * pivot*devex_;
01778 if (reference(iSequence))
01779 value += 1.0;
01780 weight[iSequence] = max(0.99*thisWeight,value);
01781 }
01782
01783 if (sequenceOut>=0)
01784 weights_[sequenceOut]=outgoingWeight;
01785 spareColumn2->setNumElements(0);
01786
01787 #ifdef SOME_DEBUG_1
01788
01789 int iCheck=229;
01790
01791 int numberRows = model_->numberRows();
01792
01793 for (iCheck=0;iCheck<numberRows+numberColumns;iCheck++) {
01794 if (model_->getStatus(iCheck)!=ClpSimplex::basic&&
01795 !model_->getStatus(iCheck)!=ClpSimplex::isFixed)
01796 checkAccuracy(iCheck,1.0e-1,updates,spareRow2);
01797 }
01798 #endif
01799 updates->setNumElements(0);
01800 spareColumn1->setNumElements(0);
01801 }
01802
01803 void
01804 ClpPrimalColumnSteepest::justSteepest(CoinIndexedVector * updates,
01805 CoinIndexedVector * spareRow1,
01806 CoinIndexedVector * spareRow2,
01807 CoinIndexedVector * spareColumn1,
01808 CoinIndexedVector * spareColumn2)
01809 {
01810 int j;
01811 int number=0;
01812 int * index;
01813 double * updateBy;
01814
01815 double dj = model_->dualIn();
01816 double tolerance=model_->currentDualTolerance();
01817
01818
01819 double error = min(1.0e-3,model_->largestDualError());
01820
01821 tolerance = tolerance + error;
01822 int pivotRow = model_->pivotRow();
01823
01824 pivotRow = pivotSequence_;
01825
01826 pivotSequence_=-1;
01827 assert (pivotRow>=0);
01828
01829 const int * pivotVariable = model_->pivotVariable();
01830 int sequenceIn = pivotVariable[pivotRow];
01831 infeasible_->zero(sequenceIn);
01832
01833 double referenceIn=0.0;
01834 if (mode_!=1&&reference(sequenceIn))
01835 referenceIn=1.0;
01836
01837 double outgoingWeight=0.0;
01838 int sequenceOut = model_->sequenceOut();
01839 if (sequenceOut>=0)
01840 outgoingWeight=weights_[sequenceOut];
01841 assert (!updates->getNumElements());
01842 assert (!spareColumn1->getNumElements());
01843
01844
01845
01846
01847 dj = -1.0;
01848 updates->createPacked(1,&pivotRow,&dj);
01849 model_->factorization()->updateColumnTranspose(spareRow2,updates);
01850
01851 model_->clpMatrix()->transposeTimes(model_,-1.0,
01852 updates,spareColumn2,spareColumn1);
01853 double * weight;
01854 double * other = alternateWeights_->denseVector();
01855 int numberColumns = model_->numberColumns();
01856
01857 number = updates->getNumElements();
01858 index = updates->getIndices();
01859 updateBy = updates->denseVector();
01860 weight = weights_+numberColumns;
01861
01862
01863
01864
01865 model_->factorization()->updateColumnTranspose(spareRow2,
01866 alternateWeights_);
01867
01868 model_->clpMatrix()->subsetTransposeTimes(model_,alternateWeights_,
01869 spareColumn1,
01870 spareColumn2);
01871 for (j=0;j<number;j++) {
01872 int iSequence = index[j];
01873 double thisWeight = weight[iSequence];
01874
01875 double pivot = -updateBy[j];
01876 updateBy[j]=0.0;
01877 double modification = other[iSequence];
01878 double pivotSquared = pivot * pivot;
01879
01880 thisWeight += pivotSquared * devex_ + pivot * modification;
01881 if (thisWeight<TRY_NORM) {
01882 if (mode_==1) {
01883
01884 thisWeight = max(TRY_NORM,ADD_ONE+pivotSquared);
01885 } else {
01886
01887 thisWeight = referenceIn*pivotSquared;
01888 if (reference(iSequence+numberColumns))
01889 thisWeight += 1.0;
01890 thisWeight = max(thisWeight,TRY_NORM);
01891 }
01892 }
01893 weight[iSequence] = thisWeight;
01894 }
01895
01896
01897 weight = weights_;
01898
01899 number = spareColumn1->getNumElements();
01900 index = spareColumn1->getIndices();
01901 updateBy = spareColumn1->denseVector();
01902
01903 double * updateBy2 = spareColumn2->denseVector();
01904 for (j=0;j<number;j++) {
01905 int iSequence = index[j];
01906 double thisWeight = weight[iSequence];
01907 double pivot = updateBy[j];
01908 updateBy[j]=0.0;
01909 double modification = updateBy2[j];
01910 updateBy2[j]=0.0;
01911 double pivotSquared = pivot * pivot;
01912
01913 thisWeight += pivotSquared * devex_ + pivot * modification;
01914 if (thisWeight<TRY_NORM) {
01915 if (mode_==1) {
01916
01917 thisWeight = max(TRY_NORM,ADD_ONE+pivotSquared);
01918 } else {
01919
01920 thisWeight = referenceIn*pivotSquared;
01921 if (reference(iSequence))
01922 thisWeight += 1.0;
01923 thisWeight = max(thisWeight,TRY_NORM);
01924 }
01925 }
01926 weight[iSequence] = thisWeight;
01927 }
01928
01929 if (sequenceOut>=0)
01930 weights_[sequenceOut]=outgoingWeight;
01931 alternateWeights_->clear();
01932 spareColumn2->setNumElements(0);
01933
01934 #ifdef SOME_DEBUG_1
01935
01936 int iCheck=229;
01937
01938 int numberRows = model_->numberRows();
01939
01940 for (iCheck=0;iCheck<numberRows+numberColumns;iCheck++) {
01941 if (model_->getStatus(iCheck)!=ClpSimplex::basic&&
01942 !model_->getStatus(iCheck)!=ClpSimplex::isFixed)
01943 checkAccuracy(iCheck,1.0e-1,updates,spareRow2);
01944 }
01945 #endif
01946 updates->setNumElements(0);
01947 spareColumn1->setNumElements(0);
01948 }
01949
01950 int
01951 ClpPrimalColumnSteepest::pivotColumnOldMethod(CoinIndexedVector * updates,
01952 CoinIndexedVector * spareRow1,
01953 CoinIndexedVector * spareRow2,
01954 CoinIndexedVector * spareColumn1,
01955 CoinIndexedVector * spareColumn2)
01956 {
01957 assert(model_);
01958 int iSection,j;
01959 int number=0;
01960 int * index;
01961 double * updateBy;
01962 double * reducedCost;
01963
01964 double dj = model_->dualIn();
01965 double tolerance=model_->currentDualTolerance();
01966
01967
01968 double error = min(1.0e-3,model_->largestDualError());
01969
01970 tolerance = tolerance + error;
01971 int pivotRow = model_->pivotRow();
01972 int anyUpdates;
01973 double * infeas = infeasible_->denseVector();
01974
01975
01976 int switchType;
01977 if (mode_==4)
01978 switchType = 5-numberSwitched_;
01979 else if (mode_>=10)
01980 switchType=3;
01981 else
01982 switchType = mode_;
01983
01984
01985
01986
01987
01988
01989
01990
01991 if (updates->getNumElements()) {
01992
01993 anyUpdates=2;
01994
01995 if (pivotRow>=0)
01996 updates->add(pivotRow,-dj);
01997 } else if (pivotRow>=0) {
01998 if (fabs(dj)>1.0e-15) {
01999
02000 updates->insert(pivotRow,-dj);
02001 if (fabs(dj)>1.0e-6) {
02002
02003 anyUpdates=1;
02004 } else {
02005
02006 anyUpdates=2;
02007 }
02008 } else {
02009
02010 anyUpdates=-1;
02011 }
02012 } else if (pivotSequence_>=0){
02013
02014 anyUpdates=-1;
02015 } else {
02016
02017 anyUpdates=0;
02018 }
02019
02020 if (anyUpdates>0) {
02021 model_->factorization()->updateColumnTranspose(spareRow2,updates);
02022
02023
02024 model_->clpMatrix()->transposeTimes(model_,-1.0,
02025 updates,spareColumn2,spareColumn1);
02026
02027 for (iSection=0;iSection<2;iSection++) {
02028
02029 reducedCost=model_->djRegion(iSection);
02030 int addSequence;
02031
02032 if (!iSection) {
02033 number = updates->getNumElements();
02034 index = updates->getIndices();
02035 updateBy = updates->denseVector();
02036 addSequence = model_->numberColumns();
02037 } else {
02038 number = spareColumn1->getNumElements();
02039 index = spareColumn1->getIndices();
02040 updateBy = spareColumn1->denseVector();
02041 addSequence = 0;
02042 }
02043 if (!model_->nonLinearCost()->lookBothWays()) {
02044
02045 for (j=0;j<number;j++) {
02046 int iSequence = index[j];
02047 double value = reducedCost[iSequence];
02048 value -= updateBy[iSequence];
02049 reducedCost[iSequence] = value;
02050 ClpSimplex::Status status = model_->getStatus(iSequence+addSequence);
02051
02052 switch(status) {
02053
02054 case ClpSimplex::basic:
02055 infeasible_->zero(iSequence+addSequence);
02056 case ClpSimplex::isFixed:
02057 break;
02058 case ClpSimplex::isFree:
02059 case ClpSimplex::superBasic:
02060 if (fabs(value)>FREE_ACCEPT*tolerance) {
02061
02062 value *= FREE_BIAS;
02063
02064 if (infeas[iSequence+addSequence])
02065 infeas[iSequence+addSequence] = value*value;
02066 else
02067 infeasible_->quickAdd(iSequence+addSequence,value*value);
02068 } else {
02069 infeasible_->zero(iSequence+addSequence);
02070 }
02071 break;
02072 case ClpSimplex::atUpperBound:
02073 if (value>tolerance) {
02074
02075 if (infeas[iSequence+addSequence])
02076 infeas[iSequence+addSequence] = value*value;
02077 else
02078 infeasible_->quickAdd(iSequence+addSequence,value*value);
02079 } else {
02080 infeasible_->zero(iSequence+addSequence);
02081 }
02082 break;
02083 case ClpSimplex::atLowerBound:
02084 if (value<-tolerance) {
02085
02086 if (infeas[iSequence+addSequence])
02087 infeas[iSequence+addSequence] = value*value;
02088 else
02089 infeasible_->quickAdd(iSequence+addSequence,value*value);
02090 } else {
02091 infeasible_->zero(iSequence+addSequence);
02092 }
02093 }
02094 }
02095 } else {
02096 ClpNonLinearCost * nonLinear = model_->nonLinearCost();
02097
02098 for (j=0;j<number;j++) {
02099 int iSequence = index[j];
02100 double value = reducedCost[iSequence];
02101 value -= updateBy[iSequence];
02102 reducedCost[iSequence] = value;
02103 ClpSimplex::Status status = model_->getStatus(iSequence+addSequence);
02104
02105 switch(status) {
02106
02107 case ClpSimplex::basic:
02108 infeasible_->zero(iSequence+addSequence);
02109 case ClpSimplex::isFixed:
02110 break;
02111 case ClpSimplex::isFree:
02112 case ClpSimplex::superBasic:
02113 if (fabs(value)>FREE_ACCEPT*tolerance) {
02114
02115 value *= FREE_BIAS;
02116
02117 if (infeas[iSequence+addSequence])
02118 infeas[iSequence+addSequence] = value*value;
02119 else
02120 infeasible_->quickAdd(iSequence+addSequence,value*value);
02121 } else {
02122 infeasible_->zero(iSequence+addSequence);
02123 }
02124 break;
02125 case ClpSimplex::atUpperBound:
02126 if (value>tolerance) {
02127
02128 if (infeas[iSequence+addSequence])
02129 infeas[iSequence+addSequence] = value*value;
02130 else
02131 infeasible_->quickAdd(iSequence+addSequence,value*value);
02132 } else {
02133
02134 value -= nonLinear->changeUpInCost(iSequence+addSequence);
02135 if (value>-tolerance) {
02136 infeasible_->zero(iSequence+addSequence);
02137 } else {
02138
02139 if (infeas[iSequence+addSequence])
02140 infeas[iSequence+addSequence] = value*value;
02141 else
02142 infeasible_->quickAdd(iSequence+addSequence,value*value);
02143 }
02144 }
02145 break;
02146 case ClpSimplex::atLowerBound:
02147 if (value<-tolerance) {
02148
02149 if (infeas[iSequence+addSequence])
02150 infeas[iSequence+addSequence] = value*value;
02151 else
02152 infeasible_->quickAdd(iSequence+addSequence,value*value);
02153 } else {
02154
02155 value -= nonLinear->changeDownInCost(iSequence+addSequence);
02156 if (value<tolerance) {
02157 infeasible_->zero(iSequence+addSequence);
02158 } else {
02159
02160 if (infeas[iSequence+addSequence])
02161 infeas[iSequence+addSequence] = value*value;
02162 else
02163 infeasible_->quickAdd(iSequence+addSequence,value*value);
02164 }
02165 }
02166 }
02167 }
02168 }
02169 }
02170 if (anyUpdates==2) {
02171
02172 updates->clear();
02173 spareColumn1->clear();
02174 }
02175 if (pivotRow>=0) {
02176
02177 int sequenceIn = model_->sequenceIn();
02178 infeasible_->zero(sequenceIn);
02179 }
02180 }
02181
02182 int sequenceOut = model_->sequenceOut();
02183 if (sequenceOut>=0) {
02184 ClpSimplex::Status status = model_->getStatus(sequenceOut);
02185 double value = model_->reducedCost(sequenceOut);
02186
02187 switch(status) {
02188
02189 case ClpSimplex::basic:
02190 case ClpSimplex::isFixed:
02191 break;
02192 case ClpSimplex::isFree:
02193 case ClpSimplex::superBasic:
02194 if (fabs(value)>FREE_ACCEPT*tolerance) {
02195
02196 value *= FREE_BIAS;
02197
02198 if (infeas[sequenceOut])
02199 infeas[sequenceOut] = value*value;
02200 else
02201 infeasible_->quickAdd(sequenceOut,value*value);
02202 } else {
02203 infeasible_->zero(sequenceOut);
02204 }
02205 break;
02206 case ClpSimplex::atUpperBound:
02207 if (value>tolerance) {
02208
02209 if (infeas[sequenceOut])
02210 infeas[sequenceOut] = value*value;
02211 else
02212 infeasible_->quickAdd(sequenceOut,value*value);
02213 } else {
02214 infeasible_->zero(sequenceOut);
02215 }
02216 break;
02217 case ClpSimplex::atLowerBound:
02218 if (value<-tolerance) {
02219
02220 if (infeas[sequenceOut])
02221 infeas[sequenceOut] = value*value;
02222 else
02223 infeasible_->quickAdd(sequenceOut,value*value);
02224 } else {
02225 infeasible_->zero(sequenceOut);
02226 }
02227 }
02228 }
02229
02230
02231 if (model_->algorithm()==2) {
02232 for (iSection=0;iSection<2;iSection++) {
02233
02234 reducedCost=model_->djRegion(iSection);
02235 int addSequence;
02236 int iSequence;
02237
02238 if (!iSection) {
02239 number = model_->numberRows();
02240 addSequence = model_->numberColumns();
02241 } else {
02242 number = model_->numberColumns();
02243 addSequence = 0;
02244 }
02245
02246 if (!model_->nonLinearCost()->lookBothWays()) {
02247 for (iSequence=0;iSequence<number;iSequence++) {
02248 double value = reducedCost[iSequence];
02249 ClpSimplex::Status status = model_->getStatus(iSequence+addSequence);
02250
02251 switch(status) {
02252
02253 case ClpSimplex::basic:
02254 infeasible_->zero(iSequence+addSequence);
02255 case ClpSimplex::isFixed:
02256 break;
02257 case ClpSimplex::isFree:
02258 case ClpSimplex::superBasic:
02259 if (fabs(value)>tolerance) {
02260
02261 value *= FREE_BIAS;
02262
02263 if (infeas[iSequence+addSequence])
02264 infeas[iSequence+addSequence] = value*value;
02265 else
02266 infeasible_->quickAdd(iSequence+addSequence,value*value);
02267 } else {
02268 infeasible_->zero(iSequence+addSequence);
02269 }
02270 break;
02271 case ClpSimplex::atUpperBound:
02272 if (value>tolerance) {
02273
02274 if (infeas[iSequence+addSequence])
02275 infeas[iSequence+addSequence] = value*value;
02276 else
02277 infeasible_->quickAdd(iSequence+addSequence,value*value);
02278 } else {
02279 infeasible_->zero(iSequence+addSequence);
02280 }
02281 break;
02282 case ClpSimplex::atLowerBound:
02283 if (value<-tolerance) {
02284
02285 if (infeas[iSequence+addSequence])
02286 infeas[iSequence+addSequence] = value*value;
02287 else
02288 infeasible_->quickAdd(iSequence+addSequence,value*value);
02289 } else {
02290 infeasible_->zero(iSequence+addSequence);
02291 }
02292 }
02293 }
02294 } else {
02295
02296 ClpNonLinearCost * nonLinear = model_->nonLinearCost();
02297 for (iSequence=0;iSequence<number;iSequence++) {
02298 double value = reducedCost[iSequence];
02299 ClpSimplex::Status status = model_->getStatus(iSequence+addSequence);
02300
02301 switch(status) {
02302
02303 case ClpSimplex::basic:
02304 infeasible_->zero(iSequence+addSequence);
02305 case ClpSimplex::isFixed:
02306 break;
02307 case ClpSimplex::isFree:
02308 case ClpSimplex::superBasic:
02309 if (fabs(value)>tolerance) {
02310
02311 value *= FREE_BIAS;
02312
02313 if (infeas[iSequence+addSequence])
02314 infeas[iSequence+addSequence] = value*value;
02315 else
02316 infeasible_->quickAdd(iSequence+addSequence,value*value);
02317 } else {
02318 infeasible_->zero(iSequence+addSequence);
02319 }
02320 break;
02321 case ClpSimplex::atUpperBound:
02322 if (value>tolerance) {
02323
02324 if (infeas[iSequence+addSequence])
02325 infeas[iSequence+addSequence] = value*value;
02326 else
02327 infeasible_->quickAdd(iSequence+addSequence,value*value);
02328 } else {
02329
02330 value -= nonLinear->changeUpInCost(iSequence+addSequence);
02331 if (value>-tolerance) {
02332 infeasible_->zero(iSequence+addSequence);
02333 } else {
02334
02335 if (infeas[iSequence+addSequence])
02336 infeas[iSequence+addSequence] = value*value;
02337 else
02338 infeasible_->quickAdd(iSequence+addSequence,value*value);
02339 }
02340 }
02341 break;
02342 case ClpSimplex::atLowerBound:
02343 if (value<-tolerance) {
02344
02345 if (infeas[iSequence+addSequence])
02346 infeas[iSequence+addSequence] = value*value;
02347 else
02348 infeasible_->quickAdd(iSequence+addSequence,value*value);
02349 } else {
02350
02351 value -= nonLinear->changeDownInCost(iSequence+addSequence);
02352 if (value<tolerance) {
02353 infeasible_->zero(iSequence+addSequence);
02354 } else {
02355
02356 if (infeas[iSequence+addSequence])
02357 infeas[iSequence+addSequence] = value*value;
02358 else
02359 infeasible_->quickAdd(iSequence+addSequence,value*value);
02360 }
02361 }
02362 }
02363 }
02364 }
02365 }
02366 }
02367
02368 int numberWanted=0;
02369 number = infeasible_->getNumElements();
02370 int numberColumns = model_->numberColumns();
02371 if (switchType==5) {
02372
02373 updates->clear();
02374 spareColumn1->clear();
02375 pivotSequence_=-1;
02376 pivotRow=-1;
02377
02378 int numberRows = model_->numberRows();
02379
02380
02381 double ratio = (double) sizeFactorization_/(double) numberRows;
02382
02383 if (ratio<0.1) {
02384 numberWanted = max(100,number/200);
02385 } else if (ratio<0.3) {
02386 numberWanted = max(500,number/40);
02387 } else if (ratio<0.5) {
02388 numberWanted = max(2000,number/10);
02389 numberWanted = max(numberWanted,numberColumns/30);
02390 } else {
02391 switchType=4;
02392
02393 numberSwitched_++;
02394
02395 delete [] weights_;
02396 weights_=NULL;
02397 saveWeights(model_,4);
02398 printf("switching to devex %d nel ratio %g\n",sizeFactorization_,ratio);
02399 updates->clear();
02400 }
02401 if (model_->numberIterations()%1000==0)
02402 printf("numels %d ratio %g wanted %d\n",sizeFactorization_,ratio,numberWanted);
02403 }
02404 if(switchType==4) {
02405
02406 int numberRows = model_->numberRows();
02407
02408 double ratio = (double) sizeFactorization_/(double) numberRows;
02409
02410 if (ratio<1.0) {
02411 numberWanted = max(2000,number/20);
02412 } else if (ratio<5.0) {
02413 numberWanted = max(2000,number/10);
02414 numberWanted = max(numberWanted,numberColumns/20);
02415 } else {
02416
02417 updates->clear();
02418 spareColumn1->clear();
02419 switchType=3;
02420
02421 pivotSequence_=-1;
02422 pivotRow=-1;
02423 numberSwitched_++;
02424
02425 delete [] weights_;
02426 weights_=NULL;
02427 saveWeights(model_,4);
02428 printf("switching to exact %d nel ratio %g\n",sizeFactorization_,ratio);
02429 updates->clear();
02430 }
02431 if (model_->numberIterations()%1000==0)
02432 printf("numels %d ratio %g wanted %d\n",sizeFactorization_,ratio,numberWanted);
02433 }
02434 if (switchType<4) {
02435 if (switchType<2 ) {
02436 numberWanted = number+1;
02437 } else if (switchType==2) {
02438 numberWanted = max(2000,number/8);
02439 } else {
02440 double ratio = (double) sizeFactorization_/(double) model_->numberRows();
02441 if (ratio<1.0) {
02442 numberWanted = max(2000,number/20);
02443 } else if (ratio<5.0) {
02444 numberWanted = max(2000,number/10);
02445 numberWanted = max(numberWanted,numberColumns/20);
02446 } else if (ratio<10.0) {
02447 numberWanted = max(2000,number/8);
02448 numberWanted = max(numberWanted,numberColumns/20);
02449 } else {
02450 ratio = number * (ratio/80.0);
02451 if (ratio>number) {
02452 numberWanted=number+1;
02453 } else {
02454 numberWanted = max(2000,(int) ratio);
02455 numberWanted = max(numberWanted,numberColumns/10);
02456 }
02457 }
02458 }
02459 }
02460
02461 pivotRow = pivotSequence_;
02462
02463 pivotSequence_=-1;
02464 if (pivotRow>=0) {
02465
02466 const int * pivotVariable = model_->pivotVariable();
02467 int sequenceIn = pivotVariable[pivotRow];
02468 infeasible_->zero(sequenceIn);
02469
02470 double referenceIn=0.0;
02471 if (switchType!=1&&reference(sequenceIn))
02472 referenceIn=1.0;
02473
02474 double outgoingWeight=0.0;
02475 if (sequenceOut>=0)
02476 outgoingWeight=weights_[sequenceOut];
02477
02478 if (anyUpdates!=1) {
02479 updates->setNumElements(0);
02480 spareColumn1->setNumElements(0);
02481
02482 dj = 1.0;
02483 updates->insert(pivotRow,-dj);
02484 model_->factorization()->updateColumnTranspose(spareRow2,updates);
02485
02486 model_->clpMatrix()->transposeTimes(model_,-1.0,
02487 updates,spareColumn2,spareColumn1);
02488 }
02489 double * weight;
02490 double * other = alternateWeights_->denseVector();
02491 int numberColumns = model_->numberColumns();
02492 double scaleFactor = -1.0/dj;
02493
02494 number = updates->getNumElements();
02495 index = updates->getIndices();
02496 updateBy = updates->denseVector();
02497 weight = weights_+numberColumns;
02498
02499 if (switchType<4) {
02500
02501
02502 model_->factorization()->updateColumnTranspose(spareRow2,
02503 alternateWeights_);
02504 for (j=0;j<number;j++) {
02505 int iSequence = index[j];
02506 double thisWeight = weight[iSequence];
02507
02508 double pivot = updateBy[iSequence]*scaleFactor;
02509 updateBy[iSequence]=0.0;
02510 double modification = other[iSequence];
02511 double pivotSquared = pivot * pivot;
02512
02513 thisWeight += pivotSquared * devex_ + pivot * modification;
02514 if (thisWeight<TRY_NORM) {
02515 if (switchType==1) {
02516
02517 thisWeight = max(TRY_NORM,ADD_ONE+pivotSquared);
02518 } else {
02519
02520 thisWeight = referenceIn*pivotSquared;
02521 if (reference(iSequence+numberColumns))
02522 thisWeight += 1.0;
02523 thisWeight = max(thisWeight,TRY_NORM);
02524 }
02525 }
02526 weight[iSequence] = thisWeight;
02527 }
02528 } else if (switchType==4) {
02529
02530 assert (devex_>0.0);
02531 for (j=0;j<number;j++) {
02532 int iSequence = index[j];
02533 double thisWeight = weight[iSequence];
02534
02535 double pivot = updateBy[iSequence]*scaleFactor;
02536 updateBy[iSequence]=0.0;
02537 double value = pivot * pivot*devex_;
02538 if (reference(iSequence+numberColumns))
02539 value += 1.0;
02540 weight[iSequence] = max(0.99*thisWeight,value);
02541 }
02542 }
02543
02544
02545 weight = weights_;
02546
02547 scaleFactor = -scaleFactor;
02548
02549 number = spareColumn1->getNumElements();
02550 index = spareColumn1->getIndices();
02551 updateBy = spareColumn1->denseVector();
02552 if (switchType<4) {
02553
02554
02555 model_->clpMatrix()->subsetTransposeTimes(model_,alternateWeights_,
02556 spareColumn1,
02557 spareColumn2);
02558 double * updateBy2 = spareColumn2->denseVector();
02559 for (j=0;j<number;j++) {
02560 int iSequence = index[j];
02561 double thisWeight = weight[iSequence];
02562 double pivot = updateBy[iSequence]*scaleFactor;
02563 updateBy[iSequence]=0.0;
02564 double modification = updateBy2[j];
02565 updateBy2[j]=0.0;
02566 double pivotSquared = pivot * pivot;
02567
02568 thisWeight += pivotSquared * devex_ + pivot * modification;
02569 if (thisWeight<TRY_NORM) {
02570 if (switchType==1) {
02571
02572 thisWeight = max(TRY_NORM,ADD_ONE+pivotSquared);
02573 } else {
02574
02575 thisWeight = referenceIn*pivotSquared;
02576 if (reference(iSequence))
02577 thisWeight += 1.0;
02578 thisWeight = max(thisWeight,TRY_NORM);
02579 }
02580 }
02581 weight[iSequence] = thisWeight;
02582 }
02583 } else if (switchType==4) {
02584
02585 for (j=0;j<number;j++) {
02586 int iSequence = index[j];
02587 double thisWeight = weight[iSequence];
02588
02589 double pivot = updateBy[iSequence]*scaleFactor;
02590 updateBy[iSequence]=0.0;
02591 double value = pivot * pivot*devex_;
02592 if (reference(iSequence))
02593 value += 1.0;
02594 weight[iSequence] = max(0.99*thisWeight,value);
02595 }
02596 }
02597
02598 if (sequenceOut>=0)
02599 weights_[sequenceOut]=outgoingWeight;
02600 alternateWeights_->clear();
02601 spareColumn2->setNumElements(0);
02602
02603 #ifdef SOME_DEBUG_1
02604
02605 int iCheck=229;
02606
02607 int numberRows = model_->numberRows();
02608
02609 for (iCheck=0;iCheck<numberRows+numberColumns;iCheck++) {
02610 if (model_->getStatus(iCheck)!=ClpSimplex::basic&&
02611 !model_->getStatus(iCheck)!=ClpSimplex::isFixed)
02612 checkAccuracy(iCheck,1.0e-1,updates,spareRow2);
02613 }
02614 #endif
02615 updates->setNumElements(0);
02616 spareColumn1->setNumElements(0);
02617 }
02618
02619
02620
02621
02622 double bestDj = 1.0e-30;
02623 int bestSequence=-1;
02624
02625 int i,iSequence;
02626 index = infeasible_->getIndices();
02627 number = infeasible_->getNumElements();
02628 if(model_->numberIterations()<model_->lastBadIteration()+200) {
02629
02630 double checkTolerance = 1.0e-8;
02631 if (!model_->factorization()->pivots())
02632 checkTolerance = 1.0e-6;
02633 if (model_->largestDualError()>checkTolerance)
02634 tolerance *= model_->largestDualError()/checkTolerance;
02635
02636 tolerance = min(1000.0,tolerance);
02637 }
02638 #ifdef CLP_DEBUG
02639 if (model_->numberDualInfeasibilities()==1)
02640 printf("** %g %g %g %x %x %d\n",tolerance,model_->dualTolerance(),
02641 model_->largestDualError(),model_,model_->messageHandler(),
02642 number);
02643 #endif
02644
02645 double saveOutInfeasibility=0.0;
02646 if (sequenceOut>=0) {
02647 saveOutInfeasibility = infeas[sequenceOut];
02648 infeas[sequenceOut]=0.0;
02649 }
02650 tolerance *= tolerance;
02651
02652 int iPass;
02653
02654 int start[4];
02655 start[1]=number;
02656 start[2]=0;
02657 double dstart = ((double) number) * CoinDrand48();
02658 start[0]=(int) dstart;
02659 start[3]=start[0];
02660
02661
02662 for (iPass=0;iPass<2;iPass++) {
02663 int end = start[2*iPass+1];
02664 if (switchType<5) {
02665 for (i=start[2*iPass];i<end;i++) {
02666 iSequence = index[i];
02667 double value = infeas[iSequence];
02668 if (value>tolerance) {
02669 double weight = weights_[iSequence];
02670
02671 if (value>bestDj*weight) {
02672
02673 if (!model_->flagged(iSequence)) {
02674 bestDj=value/weight;
02675 bestSequence = iSequence;
02676 } else {
02677
02678 numberWanted++;
02679 }
02680 }
02681 }
02682 numberWanted--;
02683 if (!numberWanted)
02684 break;
02685 }
02686 } else {
02687
02688 for (i=start[2*iPass];i<end;i++) {
02689 iSequence = index[i];
02690 double value = infeas[iSequence];
02691 if (value>tolerance) {
02692 if (value>bestDj) {
02693
02694 if (!model_->flagged(iSequence)) {
02695 bestDj=value;
02696 bestSequence = iSequence;
02697 } else {
02698
02699 numberWanted++;
02700 }
02701 }
02702 }
02703 numberWanted--;
02704 if (!numberWanted)
02705 break;
02706 }
02707 }
02708 if (!numberWanted)
02709 break;
02710 }
02711 if (sequenceOut>=0) {
02712 infeas[sequenceOut]=saveOutInfeasibility;
02713 }
02714
02715
02716
02717 #ifdef CLP_DEBUG
02718 if (bestSequence>=0) {
02719 if (model_->getStatus(bestSequence)==ClpSimplex::atLowerBound)
02720 assert(model_->reducedCost(bestSequence)<0.0);
02721 if (model_->getStatus(bestSequence)==ClpSimplex::atUpperBound)
02722 assert(model_->reducedCost(bestSequence)>0.0);
02723 }
02724 #endif
02725 return bestSequence;
02726 }
02727
02728
02729
02730
02731
02732
02733 void
02734 ClpPrimalColumnSteepest::saveWeights(ClpSimplex * model,int mode)
02735 {
02736 model_ = model;
02737 if (mode_==4) {
02738 if (mode==1&&!weights_)
02739 numberSwitched_=0;
02740 }
02741
02742
02743 int numberRows = model_->numberRows();
02744 int numberColumns = model_->numberColumns();
02745 const int * pivotVariable = model_->pivotVariable();
02746 bool doInfeasibilities=true;
02747 if (mode==1&&weights_) {
02748 if (pivotSequence_>=0) {
02749
02750 memcpy(alternateWeights_->getIndices(),pivotVariable,
02751 numberRows*sizeof(int));
02752
02753 pivotSequence_=pivotVariable[pivotSequence_];
02754 } else {
02755 alternateWeights_->clear();
02756 }
02757 state_=1;
02758 } else if (mode==2||mode==4||mode==5) {
02759
02760 if (!weights_||state_==-1||mode==5) {
02761
02762 if (mode_!=4||numberSwitched_||!model_->clpMatrix()->canDoPartialPricing()) {
02763
02764 delete [] weights_;
02765 delete alternateWeights_;
02766 weights_ = new double[numberRows+numberColumns];
02767 alternateWeights_ = new CoinIndexedVector();
02768
02769 alternateWeights_->reserve(numberRows+
02770 model_->factorization()->maximumPivots());
02771 initializeWeights();
02772
02773 delete [] savedWeights_;
02774 savedWeights_ = new double[numberRows+numberColumns];
02775 memcpy(savedWeights_,weights_,(numberRows+numberColumns)*
02776 sizeof(double));
02777 } else {
02778
02779
02780
02781 if (!infeasible_) {
02782 infeasible_ = new CoinIndexedVector();
02783 infeasible_->reserve(numberColumns+numberRows);
02784 }
02785 infeasible_->clear();
02786 int number = model_->numberRows() + model_->numberColumns();
02787 int iSequence;
02788 int numberLook=0;
02789 int * which = infeasible_->getIndices();
02790 for (iSequence=model_->numberColumns();iSequence<number;iSequence++) {
02791 ClpSimplex::Status status = model_->getStatus(iSequence);
02792 if (status!=ClpSimplex::isFixed)
02793 which[numberLook++]=iSequence;
02794 }
02795 infeasible_->setNumElements(numberLook);
02796 doInfeasibilities=false;
02797 }
02798 savedPivotSequence_=-2;
02799 savedSequenceOut_ = -2;
02800
02801 } else {
02802 if (mode!=4) {
02803
02804 memcpy(savedWeights_,weights_,(numberRows+numberColumns)*
02805 sizeof(double));
02806 savedPivotSequence_= pivotSequence_;
02807 savedSequenceOut_ = model_->sequenceOut();
02808 } else {
02809
02810 memcpy(weights_,savedWeights_,(numberRows+numberColumns)*
02811 sizeof(double));
02812
02813
02814
02815 pivotSequence_= -1;
02816 model_->setSequenceOut(-1);
02817 }
02818 }
02819 state_=0;
02820
02821 if (!infeasible_) {
02822 infeasible_ = new CoinIndexedVector();
02823 infeasible_->reserve(numberColumns+numberRows);
02824 }
02825 }
02826 if (mode>=2&&mode!=5) {
02827 if (mode!=3&&pivotSequence_>=0) {
02828
02829 int iRow;
02830
02831 double * temp = new double[numberRows+numberColumns];
02832 double * work = alternateWeights_->denseVector();
02833 int * oldPivotOrder = alternateWeights_->getIndices();
02834 for (iRow=0;iRow<numberRows;iRow++) {
02835 int iPivot=oldPivotOrder[iRow];
02836 temp[iPivot]=work[iRow];
02837 }
02838 int number=0;
02839 int found=-1;
02840 int * which = oldPivotOrder;
02841
02842 for (iRow=0;iRow<numberRows;iRow++) {
02843 int iPivot=pivotVariable[iRow];
02844 if (iPivot==pivotSequence_)
02845 found=iRow;
02846 work[iRow]=temp[iPivot];
02847 if (work[iRow])
02848 which[number++]=iRow;
02849 }
02850 alternateWeights_->setNumElements(number);
02851 #ifdef CLP_DEBUG
02852
02853 assert(found>=0);
02854 #endif
02855 pivotSequence_ = found;
02856 delete [] temp;
02857 }
02858
02859 if (!model->factorization()->pivots())
02860 sizeFactorization_ = model_->factorization()->numberElements();
02861 if(!doInfeasibilities)
02862 return;
02863 infeasible_->clear();
02864 double tolerance=model_->currentDualTolerance();
02865 int number = model_->numberRows() + model_->numberColumns();
02866 int iSequence;
02867
02868 double * reducedCost = model_->djRegion();
02869
02870 if (!model_->nonLinearCost()->lookBothWays()) {
02871 for (iSequence=0;iSequence<number;iSequence++) {
02872 double value = reducedCost[iSequence];
02873 ClpSimplex::Status status = model_->getStatus(iSequence);
02874
02875 switch(status) {
02876
02877 case ClpSimplex::basic:
02878 case ClpSimplex::isFixed:
02879 break;
02880 case ClpSimplex::isFree:
02881 case ClpSimplex::superBasic:
02882 if (fabs(value)>FREE_ACCEPT*tolerance) {
02883
02884 value *= FREE_BIAS;
02885
02886 infeasible_->quickAdd(iSequence,value*value);
02887 }
02888 break;
02889 case ClpSimplex::atUpperBound:
02890 if (value>tolerance) {
02891 infeasible_->quickAdd(iSequence,value*value);
02892 }
02893 break;
02894 case ClpSimplex::atLowerBound:
02895 if (value<-tolerance) {
02896 infeasible_->quickAdd(iSequence,value*value);
02897 }
02898 }
02899 }
02900 } else {
02901 ClpNonLinearCost * nonLinear = model_->nonLinearCost();
02902
02903 for (iSequence=0;iSequence<number;iSequence++) {
02904 double value = reducedCost[iSequence];
02905 ClpSimplex::Status status = model_->getStatus(iSequence);
02906
02907 switch(status) {
02908
02909 case ClpSimplex::basic:
02910 case ClpSimplex::isFixed:
02911 break;
02912 case ClpSimplex::isFree:
02913 case ClpSimplex::superBasic:
02914 if (fabs(value)>FREE_ACCEPT*tolerance) {
02915
02916 value *= FREE_BIAS;
02917
02918 infeasible_->quickAdd(iSequence,value*value);
02919 }
02920 break;
02921 case ClpSimplex::atUpperBound:
02922 if (value>tolerance) {
02923 infeasible_->quickAdd(iSequence,value*value);
02924 } else {
02925
02926 value -= nonLinear->changeUpInCost(iSequence);
02927 if (value<-tolerance) {
02928
02929 infeasible_->quickAdd(iSequence,value*value);
02930 }
02931 }
02932 break;
02933 case ClpSimplex::atLowerBound:
02934 if (value<-tolerance) {
02935 infeasible_->quickAdd(iSequence,value*value);
02936 } else {
02937
02938 value -= nonLinear->changeDownInCost(iSequence);
02939 if (value>tolerance) {
02940
02941 infeasible_->quickAdd(iSequence,value*value);
02942 }
02943 }
02944 }
02945 }
02946 }
02947 }
02948 }
02949
02950 void
02951 ClpPrimalColumnSteepest::unrollWeights()
02952 {
02953 if (mode_==4&&!numberSwitched_)
02954 return;
02955 double * saved = alternateWeights_->denseVector();
02956 int number = alternateWeights_->getNumElements();
02957 int * which = alternateWeights_->getIndices();
02958 int i;
02959 for (i=0;i<number;i++) {
02960 int iRow = which[i];
02961 weights_[iRow]=saved[iRow];
02962 saved[iRow]=0.0;
02963 }
02964 alternateWeights_->setNumElements(0);
02965 }
02966
02967
02968
02969
02970 ClpPrimalColumnPivot * ClpPrimalColumnSteepest::clone(bool CopyData) const
02971 {
02972 if (CopyData) {
02973 return new ClpPrimalColumnSteepest(*this);
02974 } else {
02975 return new ClpPrimalColumnSteepest();
02976 }
02977 }
02978 void
02979 ClpPrimalColumnSteepest::updateWeights(CoinIndexedVector * input)
02980 {
02981
02982 int switchType = mode_;
02983 if (mode_==4&&numberSwitched_)
02984 switchType=3;
02985 else if (mode_==4)
02986 return;
02987 int number=input->getNumElements();
02988 int * which = input->getIndices();
02989 double * work = input->denseVector();
02990 int newNumber = 0;
02991 int * newWhich = alternateWeights_->getIndices();
02992 double * newWork = alternateWeights_->denseVector();
02993 int i;
02994 int sequenceIn = model_->sequenceIn();
02995 int sequenceOut = model_->sequenceOut();
02996 const int * pivotVariable = model_->pivotVariable();
02997
02998 int pivotRow = model_->pivotRow();
02999 pivotSequence_ = pivotRow;
03000
03001 devex_ =0.0;
03002
03003 if (!input->packedMode()) {
03004 if (pivotRow>=0) {
03005 if (switchType==1) {
03006 for (i=0;i<number;i++) {
03007 int iRow = which[i];
03008 devex_ += work[iRow]*work[iRow];
03009 newWork[iRow] = -2.0*work[iRow];
03010 }
03011 newWork[pivotRow] = -2.0*max(devex_,0.0);
03012 devex_+=ADD_ONE;
03013 weights_[sequenceOut]=1.0+ADD_ONE;
03014 memcpy(newWhich,which,number*sizeof(int));
03015 alternateWeights_->setNumElements(number);
03016 } else {
03017 if (mode_!=4||numberSwitched_>1) {
03018 for (i=0;i<number;i++) {
03019 int iRow = which[i];
03020 int iPivot = pivotVariable[iRow];
03021 if (reference(iPivot)) {
03022 devex_ += work[iRow]*work[iRow];
03023 newWork[iRow] = -2.0*work[iRow];
03024 newWhich[newNumber++]=iRow;
03025 }
03026 }
03027 if (!newWork[pivotRow]&&devex_>0.0)
03028 newWhich[newNumber++]=pivotRow;
03029 newWork[pivotRow] = -2.0*max(devex_,0.0);
03030 } else {
03031 for (i=0;i<number;i++) {
03032 int iRow = which[i];
03033 int iPivot = pivotVariable[iRow];
03034 if (reference(iPivot))
03035 devex_ += work[iRow]*work[iRow];
03036 }
03037 }
03038 if (reference(sequenceIn)) {
03039 devex_+=1.0;
03040 } else {
03041 }
03042 if (reference(sequenceOut)) {
03043 weights_[sequenceOut]=1.0+1.0;
03044 } else {
03045 weights_[sequenceOut]=1.0;
03046 }
03047 alternateWeights_->setNumElements(newNumber);
03048 }
03049 } else {
03050 if (switchType==1) {
03051 for (i=0;i<number;i++) {
03052 int iRow = which[i];
03053 devex_ += work[iRow]*work[iRow];
03054 }
03055 devex_ += ADD_ONE;
03056 } else {
03057 for (i=0;i<number;i++) {
03058 int iRow = which[i];
03059 int iPivot = pivotVariable[iRow];
03060 if (reference(iPivot)) {
03061 devex_ += work[iRow]*work[iRow];
03062 }
03063 }
03064 if (reference(sequenceIn))
03065 devex_+=1.0;
03066 }
03067 }
03068 } else {
03069
03070 if (pivotRow>=0) {
03071 if (switchType==1) {
03072 for (i=0;i<number;i++) {
03073 int iRow = which[i];
03074 devex_ += work[i]*work[i];
03075 newWork[iRow] = -2.0*work[i];
03076 }
03077 newWork[pivotRow] = -2.0*max(devex_,0.0);
03078 devex_+=ADD_ONE;
03079 weights_[sequenceOut]=1.0+ADD_ONE;
03080 memcpy(newWhich,which,number*sizeof(int));
03081 alternateWeights_->setNumElements(number);
03082 } else {
03083 if (mode_!=4||numberSwitched_>1) {
03084 for (i=0;i<number;i++) {
03085 int iRow = which[i];
03086 int iPivot = pivotVariable[iRow];
03087 if (reference(iPivot)) {
03088 devex_ += work[i]*work[i];
03089 newWork[iRow] = -2.0*work[i];
03090 newWhich[newNumber++]=iRow;
03091 }
03092 }
03093 if (!newWork[pivotRow]&&devex_>0.0)
03094 newWhich[newNumber++]=pivotRow;
03095 newWork[pivotRow] = -2.0*max(devex_,0.0);
03096 } else {
03097 for (i=0;i<number;i++) {
03098 int iRow = which[i];
03099 int iPivot = pivotVariable[iRow];
03100 if (reference(iPivot))
03101 devex_ += work[i]*work[i];
03102 }
03103 }
03104 if (reference(sequenceIn)) {
03105 devex_+=1.0;
03106 } else {
03107 }
03108 if (reference(sequenceOut)) {
03109 weights_[sequenceOut]=1.0+1.0;
03110 } else {
03111 weights_[sequenceOut]=1.0;
03112 }
03113 alternateWeights_->setNumElements(newNumber);
03114 }
03115 } else {
03116 if (switchType==1) {
03117 for (i=0;i<number;i++) {
03118 devex_ += work[i]*work[i];
03119 }
03120 devex_ += ADD_ONE;
03121 } else {
03122 for (i=0;i<number;i++) {
03123 int iRow = which[i];
03124 int iPivot = pivotVariable[iRow];
03125 if (reference(iPivot)) {
03126 devex_ += work[i]*work[i];
03127 }
03128 }
03129 if (reference(sequenceIn))
03130 devex_+=1.0;
03131 }
03132 }
03133 }
03134 double oldDevex = weights_[sequenceIn];
03135 #ifdef CLP_DEBUG
03136 if ((model_->messageHandler()->logLevel()&32))
03137 printf("old weight %g, new %g\n",oldDevex,devex_);
03138 #endif
03139 double check = max(devex_,oldDevex)+0.1;
03140 weights_[sequenceIn] = devex_;
03141 double testValue=0.1;
03142 if (mode_==4&&numberSwitched_==1)
03143 testValue = 0.5;
03144 if ( fabs ( devex_ - oldDevex ) > testValue * check ) {
03145 #ifdef CLP_DEBUG
03146 if ((model_->messageHandler()->logLevel()&48)==16)
03147 printf("old weight %g, new %g\n",oldDevex,devex_);
03148 #endif
03149
03150 testValue=0.99;
03151 if (mode_==1)
03152 testValue=1.01e1;
03153 else if (mode_==4&&numberSwitched_==1)
03154 testValue=0.9;
03155 double difference = fabs(devex_-oldDevex);
03156 if ( difference > testValue * check ) {
03157
03158 model_->messageHandler()->message(CLP_INITIALIZE_STEEP,
03159 *model_->messagesPointer())
03160 <<oldDevex<<devex_
03161 <<CoinMessageEol;
03162 initializeWeights();
03163 }
03164 }
03165 if (pivotRow>=0) {
03166
03167 weights_[model_->sequenceOut()]=devex_/(model_->alpha()*model_->alpha());
03168 }
03169 }
03170
03171 void
03172 ClpPrimalColumnSteepest::checkAccuracy(int sequence,
03173 double relativeTolerance,
03174 CoinIndexedVector * rowArray1,
03175 CoinIndexedVector * rowArray2)
03176 {
03177 if (mode_==4&&!numberSwitched_)
03178 return;
03179 model_->unpack(rowArray1,sequence);
03180 model_->factorization()->updateColumn(rowArray2,rowArray1);
03181 int number=rowArray1->getNumElements();
03182 int * which = rowArray1->getIndices();
03183 double * work = rowArray1->denseVector();
03184 const int * pivotVariable = model_->pivotVariable();
03185
03186 double devex =0.0;
03187 int i;
03188
03189 if (mode_==1) {
03190 for (i=0;i<number;i++) {
03191 int iRow = which[i];
03192 devex += work[iRow]*work[iRow];
03193 work[iRow]=0.0;
03194 }
03195 devex += ADD_ONE;
03196 } else {
03197 for (i=0;i<number;i++) {
03198 int iRow = which[i];
03199 int iPivot = pivotVariable[iRow];
03200 if (reference(iPivot)) {
03201 devex += work[iRow]*work[iRow];
03202 }
03203 work[iRow]=0.0;
03204 }
03205 if (reference(sequence))
03206 devex+=1.0;
03207 }
03208
03209 double oldDevex = weights_[sequence];
03210 double check = max(devex,oldDevex);;
03211 if ( fabs ( devex - oldDevex ) > relativeTolerance * check ) {
03212 printf("check %d old weight %g, new %g\n",sequence,oldDevex,devex);
03213
03214 weights_[sequence]=devex;
03215 }
03216 rowArray1->setNumElements(0);
03217 }
03218
03219
03220 void
03221 ClpPrimalColumnSteepest::initializeWeights()
03222 {
03223 int numberRows = model_->numberRows();
03224 int numberColumns = model_->numberColumns();
03225 int number = numberRows + numberColumns;
03226 int iSequence;
03227 if (mode_!=1) {
03228
03229
03230 if (!reference_) {
03231 int nWords = (number+31)>>5;
03232 reference_ = new unsigned int[nWords];
03233
03234 memset(reference_,0,nWords*sizeof(int));
03235 }
03236
03237 for (iSequence=0;iSequence<number;iSequence++) {
03238 weights_[iSequence]=1.0;
03239 if (model_->getStatus(iSequence)==ClpSimplex::basic) {
03240 setReference(iSequence,false);
03241 } else {
03242 setReference(iSequence,true);
03243 }
03244 }
03245 } else {
03246 CoinIndexedVector * temp = new CoinIndexedVector();
03247 temp->reserve(numberRows+
03248 model_->factorization()->maximumPivots());
03249 double * array = alternateWeights_->denseVector();
03250 int * which = alternateWeights_->getIndices();
03251
03252 for (iSequence=0;iSequence<number;iSequence++) {
03253 weights_[iSequence]=1.0+ADD_ONE;
03254 if (model_->getStatus(iSequence)!=ClpSimplex::basic&&
03255 model_->getStatus(iSequence)!=ClpSimplex::isFixed) {
03256 model_->unpack(alternateWeights_,iSequence);
03257 double value=ADD_ONE;
03258 model_->factorization()->updateColumn(temp,alternateWeights_);
03259 int number = alternateWeights_->getNumElements(); int j;
03260 for (j=0;j<number;j++) {
03261 int iRow=which[j];
03262 value+=array[iRow]*array[iRow];
03263 array[iRow]=0.0;
03264 }
03265 alternateWeights_->setNumElements(0);
03266 weights_[iSequence] = value;
03267 }
03268 }
03269 delete temp;
03270 }
03271 }
03272
03273 void
03274 ClpPrimalColumnSteepest::clearArrays()
03275 {
03276 delete [] weights_;
03277 weights_=NULL;
03278 delete infeasible_;
03279 infeasible_ = NULL;
03280 delete alternateWeights_;
03281 alternateWeights_ = NULL;
03282 delete [] savedWeights_;
03283 savedWeights_ = NULL;
03284 delete [] reference_;
03285 reference_ = NULL;
03286 pivotSequence_=-1;
03287 state_ = -1;
03288 savedPivotSequence_ = -1;
03289 savedSequenceOut_ = -1;
03290 devex_ = 0.0;
03291 }
03292
03293 bool
03294 ClpPrimalColumnSteepest::looksOptimal() const
03295 {
03296
03297 double tolerance=model_->currentDualTolerance();
03298
03299
03300 double error = min(1.0e-3,model_->largestDualError());
03301
03302 tolerance = tolerance + error;
03303 if(model_->numberIterations()<model_->lastBadIteration()+200) {
03304
03305 double checkTolerance = 1.0e-8;
03306 if (!model_->factorization()->pivots())
03307 checkTolerance = 1.0e-6;
03308 if (model_->largestDualError()>checkTolerance)
03309 tolerance *= model_->largestDualError()/checkTolerance;
03310
03311 tolerance = min(1000.0,tolerance);
03312 }
03313 int number = model_->numberRows() + model_->numberColumns();
03314 int iSequence;
03315
03316 double * reducedCost = model_->djRegion();
03317 int numberInfeasible=0;
03318 if (!model_->nonLinearCost()->lookBothWays()) {
03319 for (iSequence=0;iSequence<number;iSequence++) {
03320 double value = reducedCost[iSequence];
03321 ClpSimplex::Status status = model_->getStatus(iSequence);
03322
03323 switch(status) {
03324
03325 case ClpSimplex::basic:
03326 case ClpSimplex::isFixed:
03327 break;
03328 case ClpSimplex::isFree:
03329 case ClpSimplex::superBasic:
03330 if (fabs(value)>FREE_ACCEPT*tolerance)
03331 numberInfeasible++;
03332 break;
03333 case ClpSimplex::atUpperBound:
03334 if (value>tolerance)
03335 numberInfeasible++;
03336 break;
03337 case ClpSimplex::atLowerBound:
03338 if (value<-tolerance)
03339 numberInfeasible++;
03340 }
03341 }
03342 } else {
03343 ClpNonLinearCost * nonLinear = model_->nonLinearCost();
03344
03345 for (iSequence=0;iSequence<number;iSequence++) {
03346 double value = reducedCost[iSequence];
03347 ClpSimplex::Status status = model_->getStatus(iSequence);
03348
03349 switch(status) {
03350
03351 case ClpSimplex::basic:
03352 case ClpSimplex::isFixed:
03353 break;
03354 case ClpSimplex::isFree:
03355 case ClpSimplex::superBasic:
03356 if (fabs(value)>FREE_ACCEPT*tolerance)
03357 numberInfeasible++;
03358 break;
03359 case ClpSimplex::atUpperBound:
03360 if (value>tolerance) {
03361 numberInfeasible++;
03362 } else {
03363
03364 value -= nonLinear->changeUpInCost(iSequence);
03365 if (value<-tolerance)
03366 numberInfeasible++;
03367 }
03368 break;
03369 case ClpSimplex::atLowerBound:
03370 if (value<-tolerance) {
03371 numberInfeasible++;
03372 } else {
03373
03374 value -= nonLinear->changeDownInCost(iSequence);
03375 if (value>tolerance)
03376 numberInfeasible++;
03377 }
03378 }
03379 }
03380 }
03381 return numberInfeasible==0;
03382 }
03383
03384
03385
03386 int
03387 ClpPrimalColumnSteepest::numberSprintColumns(int & numberIterations) const
03388 {
03389 numberIterations=0;
03390 int numberAdd=0;
03391 if (!numberSwitched_&&mode_>=10) {
03392 numberIterations = min(2000,model_->numberRows()/5);
03393 numberIterations = max(numberIterations,model_->factorizationFrequency());
03394 numberIterations = max(numberIterations,500);
03395 if (mode_==10) {
03396 numberAdd=max(300,model_->numberColumns()/10);
03397 numberAdd=max(numberAdd,model_->numberRows()/5);
03398
03399
03400 numberAdd = min(numberAdd,model_->numberColumns());
03401 } else {
03402 abort();
03403 }
03404 }
03405 return numberAdd;
03406 }
03407
03408 void
03409 ClpPrimalColumnSteepest::switchOffSprint()
03410 {
03411 numberSwitched_=10;
03412 }
03413
03414 int
03415 ClpPrimalColumnSteepest::partialPricing(CoinIndexedVector * updates,
03416 CoinIndexedVector * spareRow2,
03417 int numberWanted)
03418 {
03419 int number=0;
03420 int * index;
03421 double * updateBy;
03422 double * reducedCost;
03423 double saveTolerance = model_->currentDualTolerance();
03424 double tolerance=model_->currentDualTolerance();
03425
03426
03427 double error = min(1.0e-3,model_->largestDualError());
03428
03429 tolerance = tolerance + error;
03430 if(model_->numberIterations()<model_->lastBadIteration()+200) {
03431
03432 double checkTolerance = 1.0e-8;
03433 if (!model_->factorization()->pivots())
03434 checkTolerance = 1.0e-6;
03435 if (model_->largestDualError()>checkTolerance)
03436 tolerance *= model_->largestDualError()/checkTolerance;
03437
03438 tolerance = min(1000.0,tolerance);
03439 }
03440 if (model_->factorization()->pivots()&&model_->numberPrimalInfeasibilities())
03441 tolerance = max(tolerance,1.0e-10*model_->infeasibilityCost());
03442
03443 model_->setCurrentDualTolerance(tolerance);
03444 model_->factorization()->updateColumnTranspose(spareRow2,updates);
03445 int numberColumns = model_->numberColumns();
03446
03447
03448 reducedCost=model_->djRegion(0);
03449 int addSequence;
03450
03451 number = updates->getNumElements();
03452 index = updates->getIndices();
03453 updateBy = updates->denseVector();
03454 addSequence = numberColumns;
03455 int j;
03456 double * duals = model_->dualRowSolution();
03457 for (j=0;j<number;j++) {
03458 int iSequence = index[j];
03459 double value = duals[iSequence];
03460 value -= updateBy[j];
03461 updateBy[j]=0.0;
03462 duals[iSequence] = value;
03463 }
03464 double bestDj = tolerance;
03465 int bestSequence=-1;
03466
03467 const double * cost = model_->costRegion(1);
03468
03469 int iPassR=0,iPassC=0;
03470
03471
03472
03473 int startR[4];
03474 const int * which = infeasible_->getIndices();
03475 int nSlacks = infeasible_->getNumElements();
03476 startR[1]=nSlacks;
03477 startR[2]=0;
03478 double randomR = CoinDrand48();
03479 double dstart = ((double) nSlacks) * randomR;
03480 startR[0]=(int) dstart;
03481 startR[3]=startR[0];
03482 int startC[4];
03483 startC[1]=numberColumns;
03484 startC[2]=0;
03485 double randomC = CoinDrand48();
03486 dstart = ((double) numberColumns) * randomC;
03487 startC[0]=(int) dstart;
03488 startC[3]=startC[0];
03489 reducedCost = model_->djRegion(1);
03490 int sequenceOut = model_->sequenceOut();
03491 double * duals2 = duals-numberColumns;
03492 int chunk = min(1024,(numberColumns+nSlacks)/32);
03493 if (model_->numberIterations()%1000==0) {
03494 printf("%d wanted, nSlacks %d, chunk %d\n",numberWanted,nSlacks,chunk);
03495 int i;
03496 for (i=0;i<4;i++)
03497 printf("start R %d C %d ",startR[i],startC[i]);
03498 printf("\n");
03499 }
03500 chunk = max(chunk,256);
03501 bool finishedR=false,finishedC=false;
03502 bool doingR = randomR>randomC;
03503 doingR=false;
03504 while (!finishedR||!finishedC) {
03505 if (finishedR)
03506 doingR=false;
03507 if (doingR) {
03508 int saveSequence = bestSequence;
03509 int start = startR[iPassR];
03510 int end = min(startR[iPassR+1],start+chunk/2);
03511 int jSequence;
03512 for (jSequence=start;jSequence<end;jSequence++) {
03513 int iSequence=which[jSequence];
03514 if (iSequence!=sequenceOut) {
03515 double value;
03516 ClpSimplex::Status status = model_->getStatus(iSequence);
03517
03518 switch(status) {
03519
03520 case ClpSimplex::basic:
03521 case ClpSimplex::isFixed:
03522 break;
03523 case ClpSimplex::isFree:
03524 case ClpSimplex::superBasic:
03525 value = fabs(cost[iSequence]+duals2[iSequence]);
03526 if (value>FREE_ACCEPT*tolerance) {
03527 numberWanted--;
03528
03529 value *= FREE_BIAS;
03530 if (value>bestDj) {
03531
03532 if (!model_->flagged(iSequence)) {
03533 bestDj=value;
03534 bestSequence = iSequence;
03535 } else {
03536
03537 numberWanted++;
03538 }
03539 }
03540 }
03541 break;
03542 case ClpSimplex::atUpperBound:
03543 value = cost[iSequence]+duals2[iSequence];
03544 if (value>tolerance) {
03545 numberWanted--;
03546 if (value>bestDj) {
03547
03548 if (!model_->flagged(iSequence)) {
03549 bestDj=value;
03550 bestSequence = iSequence;
03551 } else {
03552
03553 numberWanted++;
03554 }
03555 }
03556 }
03557 break;
03558 case ClpSimplex::atLowerBound:
03559 value = -(cost[iSequence]+duals2[iSequence]);
03560 if (value>tolerance) {
03561 numberWanted--;
03562 if (value>bestDj) {
03563
03564 if (!model_->flagged(iSequence)) {
03565 bestDj=value;
03566 bestSequence = iSequence;
03567 } else {
03568
03569 numberWanted++;
03570 }
03571 }
03572 }
03573 break;
03574 }
03575 }
03576 if (!numberWanted)
03577 break;
03578 }
03579 if (saveSequence!=bestSequence) {
03580
03581 reducedCost[bestSequence] = cost[bestSequence] +duals[bestSequence-numberColumns];
03582 bestDj=reducedCost[bestSequence];
03583 }
03584 if (!numberWanted)
03585 break;
03586 doingR=false;
03587
03588 startR[iPassR]=jSequence;
03589 if (jSequence>=startR[iPassR+1]) {
03590 if (iPassR)
03591 finishedR=true;
03592 else
03593 iPassR=2;
03594 }
03595 }
03596 if (finishedC)
03597 doingR=true;
03598 if (!doingR) {
03599 int saveSequence = bestSequence;
03600
03601 int start = startC[iPassC];
03602 int end = min(startC[iPassC+1],start+chunk);;
03603 model_->clpMatrix()->partialPricing(model_,start,end,bestSequence,numberWanted);
03604 if (saveSequence!=bestSequence) {
03605
03606 bestDj=reducedCost[bestSequence];
03607 }
03608 if (!numberWanted)
03609 break;
03610 doingR=true;
03611
03612 int iSequence = end;
03613 startC[iPassC]=iSequence;
03614 if (iSequence>=startC[iPassC+1]) {
03615 if (iPassC)
03616 finishedC=true;
03617 else
03618 iPassC=2;
03619 }
03620 }
03621 }
03622 updates->setNumElements(0);
03623
03624
03625 model_->setCurrentDualTolerance(saveTolerance);
03626 #ifndef NDEBUG
03627 if (bestSequence>=0) {
03628 if (model_->getStatus(bestSequence)==ClpSimplex::atLowerBound)
03629 assert(model_->reducedCost(bestSequence)<0.0);
03630 if (model_->getStatus(bestSequence)==ClpSimplex::atUpperBound)
03631 assert(model_->reducedCost(bestSequence)>0.0);
03632 }
03633 #endif
03634 return bestSequence;
03635 }