00001
00002
00003
00004
00005 #include <cstdio>
00006
00007 #include "CoinPragma.hpp"
00008 #include "CoinIndexedVector.hpp"
00009 #include "CoinHelperFunctions.hpp"
00010
00011 #include "ClpSimplex.hpp"
00012 #include "ClpFactorization.hpp"
00013
00014 #include "ClpNetworkMatrix.hpp"
00015 #include "ClpPlusMinusOneMatrix.hpp"
00016 #include "ClpMessage.hpp"
00017 #include <iostream>
00018
00019
00020
00021
00022
00023
00024
00025
00026 ClpNetworkMatrix::ClpNetworkMatrix ()
00027 : ClpMatrixBase()
00028 {
00029 setType(11);
00030 elements_ = NULL;
00031 starts_ = NULL;
00032 lengths_=NULL;
00033 indices_=NULL;
00034 numberRows_=0;
00035 numberColumns_=0;
00036 trueNetwork_=false;
00037 }
00038
00039
00040 ClpNetworkMatrix::ClpNetworkMatrix(int numberColumns, const int * head,
00041 const int * tail)
00042 : ClpMatrixBase()
00043 {
00044 setType(11);
00045 elements_ = NULL;
00046 starts_ = NULL;
00047 lengths_=NULL;
00048 indices_=new int[2*numberColumns];;
00049 numberRows_=-1;
00050 numberColumns_=numberColumns;
00051 trueNetwork_=true;
00052 int iColumn;
00053 CoinBigIndex j=0;
00054 for (iColumn=0;iColumn<numberColumns_;iColumn++, j+=2) {
00055 int iRow = head[iColumn];
00056 numberRows_ = max(numberRows_,iRow);
00057 indices_[j]=iRow;
00058 iRow = tail[iColumn];
00059 numberRows_ = max(numberRows_,iRow);
00060 indices_[j+1]=iRow;
00061 }
00062 numberRows_++;
00063 }
00064
00065
00066
00067 ClpNetworkMatrix::ClpNetworkMatrix (const ClpNetworkMatrix & rhs)
00068 : ClpMatrixBase(rhs)
00069 {
00070 elements_ = NULL;
00071 starts_ = NULL;
00072 lengths_=NULL;
00073 indices_=NULL;
00074 numberRows_=rhs.numberRows_;
00075 numberColumns_=rhs.numberColumns_;
00076 trueNetwork_=rhs.trueNetwork_;
00077 if (numberColumns_) {
00078 indices_ = new int [ 2*numberColumns_];
00079 memcpy(indices_,rhs.indices_,2*numberColumns_*sizeof(int));
00080 }
00081 }
00082
00083 ClpNetworkMatrix::ClpNetworkMatrix (const CoinPackedMatrix & rhs)
00084 : ClpMatrixBase()
00085 {
00086 setType(11);
00087 elements_ = NULL;
00088 starts_ = NULL;
00089 lengths_=NULL;
00090 indices_=NULL;
00091 int iColumn;
00092 assert (rhs.isColOrdered());
00093
00094 const int * row = rhs.getIndices();
00095 const CoinBigIndex * columnStart = rhs.getVectorStarts();
00096 const int * columnLength = rhs.getVectorLengths();
00097 const double * elementByColumn = rhs.getElements();
00098 numberColumns_ = rhs.getNumCols();
00099 int goodNetwork=1;
00100 numberRows_=-1;
00101 indices_ = new int[2*numberColumns_];
00102 CoinBigIndex j=0;
00103 for (iColumn=0;iColumn<numberColumns_;iColumn++, j+=2) {
00104 CoinBigIndex k=columnStart[iColumn];
00105 int iRow;
00106 switch (columnLength[iColumn]) {
00107 case 0:
00108 goodNetwork=-1;
00109 indices_[j]=-1;
00110 indices_[j+1]=-1;
00111 break;
00112
00113 case 1:
00114 goodNetwork=-1;
00115 if (fabs(elementByColumn[k]-1.0)<1.0e-10) {
00116 indices_[j] = -1;
00117 iRow = row[k];
00118 numberRows_ = max(numberRows_,iRow);
00119 indices_[j+1]=iRow;
00120 } else if (fabs(elementByColumn[k]+1.0)<1.0e-10) {
00121 indices_[j+1] = -1;
00122 iRow = row[k];
00123 numberRows_ = max(numberRows_,iRow);
00124 indices_[j]=iRow;
00125 } else {
00126 goodNetwork = 0;
00127 }
00128 break;
00129
00130 case 2:
00131 if (fabs(elementByColumn[k]-1.0)<1.0e-10) {
00132 if (fabs(elementByColumn[k+1]+1.0)<1.0e-10) {
00133 iRow = row[k];
00134 numberRows_ = max(numberRows_,iRow);
00135 indices_[j+1]=iRow;
00136 iRow = row[k+1];
00137 numberRows_ = max(numberRows_,iRow);
00138 indices_[j] = iRow;
00139 } else {
00140 goodNetwork = 0;
00141 }
00142 } else if (fabs(elementByColumn[k]+1.0)<1.0e-10) {
00143 if (fabs(elementByColumn[k+1]-1.0)<1.0e-10) {
00144 iRow = row[k];
00145 numberRows_ = max(numberRows_,iRow);
00146 indices_[j]=iRow;
00147 iRow = row[k+1];
00148 numberRows_ = max(numberRows_,iRow);
00149 indices_[j+1] = iRow;
00150 } else {
00151 goodNetwork = 0;
00152 }
00153 } else {
00154 goodNetwork = 0;
00155 }
00156 break;
00157
00158 default:
00159 goodNetwork = 0;
00160 break;
00161 }
00162 if (!goodNetwork)
00163 break;
00164 }
00165 if (!goodNetwork) {
00166 delete [] indices_;
00167
00168 printf("Not a network - can test if indices_ null\n");
00169 indices_=NULL;
00170 numberRows_=0;
00171 numberColumns_=0;
00172 } else {
00173 numberRows_ ++;
00174 trueNetwork_ = goodNetwork>0;
00175 }
00176 }
00177
00178
00179
00180
00181 ClpNetworkMatrix::~ClpNetworkMatrix ()
00182 {
00183 delete [] elements_;
00184 delete [] starts_;
00185 delete [] lengths_;
00186 delete [] indices_;
00187 }
00188
00189
00190
00191
00192 ClpNetworkMatrix &
00193 ClpNetworkMatrix::operator=(const ClpNetworkMatrix& rhs)
00194 {
00195 if (this != &rhs) {
00196 ClpMatrixBase::operator=(rhs);
00197 delete [] elements_;
00198 delete [] starts_;
00199 delete [] lengths_;
00200 delete [] indices_;
00201 elements_ = NULL;
00202 starts_ = NULL;
00203 lengths_=NULL;
00204 indices_=NULL;
00205 numberRows_=rhs.numberRows_;
00206 numberColumns_=rhs.numberColumns_;
00207 trueNetwork_=rhs.trueNetwork_;
00208 if (numberColumns_) {
00209 indices_ = new int [ 2*numberColumns_];
00210 memcpy(indices_,rhs.indices_,2*numberColumns_*sizeof(int));
00211 }
00212 }
00213 return *this;
00214 }
00215
00216
00217
00218 ClpMatrixBase * ClpNetworkMatrix::clone() const
00219 {
00220 return new ClpNetworkMatrix(*this);
00221 }
00222
00223
00224 ClpMatrixBase *
00225 ClpNetworkMatrix::reverseOrderedCopy() const
00226 {
00227
00228 int * tempP = new int [numberRows_];
00229 int * tempN = new int [numberRows_];
00230 memset(tempP,0,numberRows_*sizeof(int));
00231 memset(tempN,0,numberRows_*sizeof(int));
00232 CoinBigIndex j=0;
00233 int i;
00234 for (i=0;i<numberColumns_;i++,j+=2) {
00235 int iRow = indices_[j];
00236 tempN[iRow]++;
00237 iRow = indices_[j+1];
00238 tempP[iRow]++;
00239 }
00240 int * newIndices = new int [2*numberColumns_];
00241 int * newP = new int [numberRows_+1];
00242 int * newN = new int[numberRows_];
00243 int iRow;
00244 j=0;
00245
00246 for (iRow=0;iRow<numberRows_;iRow++) {
00247 newP[iRow]=j;
00248 j += tempP[iRow];
00249 tempP[iRow]=newP[iRow];
00250 newN[iRow] = j;
00251 j += tempN[iRow];
00252 tempN[iRow]=newN[iRow];
00253 }
00254 newP[numberRows_]=j;
00255 j=0;
00256 for (i=0;i<numberColumns_;i++,j+=2) {
00257 int iRow = indices_[j];
00258 int put = tempN[iRow];
00259 newIndices[put++] = i;
00260 tempN[iRow] = put;
00261 iRow = indices_[j+1];
00262 put = tempP[iRow];
00263 newIndices[put++] = i;
00264 tempP[iRow] = put;
00265 }
00266 delete [] tempP;
00267 delete [] tempN;
00268 ClpPlusMinusOneMatrix * newCopy = new ClpPlusMinusOneMatrix();
00269 newCopy->passInCopy(numberRows_, numberColumns_,
00270 false, newIndices, newP, newN);
00271 return newCopy;
00272 }
00273
00274 void
00275 ClpNetworkMatrix::times(double scalar,
00276 const double * x, double * y) const
00277 {
00278 int iColumn;
00279 CoinBigIndex j=0;
00280 if (trueNetwork_) {
00281 for (iColumn=0;iColumn<numberColumns_;iColumn++,j+=2) {
00282 double value = scalar*x[iColumn];
00283 if (value) {
00284 int iRowM = indices_[j];
00285 int iRowP = indices_[j+1];
00286 y[iRowM] -= value;
00287 y[iRowP] += value;
00288 }
00289 }
00290 } else {
00291
00292 for (iColumn=0;iColumn<numberColumns_;iColumn++,j+=2) {
00293 double value = scalar*x[iColumn];
00294 if (value) {
00295 int iRowM = indices_[j];
00296 int iRowP = indices_[j+1];
00297 if (iRowM>=0)
00298 y[iRowM] -= value;
00299 if (iRowP>=0)
00300 y[iRowP] += value;
00301 }
00302 }
00303 }
00304 }
00305 void
00306 ClpNetworkMatrix::transposeTimes(double scalar,
00307 const double * x, double * y) const
00308 {
00309 int iColumn;
00310 CoinBigIndex j=0;
00311 if (trueNetwork_) {
00312 for (iColumn=0;iColumn<numberColumns_;iColumn++,j+=2) {
00313 double value = y[iColumn];
00314 int iRowM = indices_[j];
00315 int iRowP = indices_[j+1];
00316 value -= scalar*x[iRowM];
00317 value += scalar*x[iRowP];
00318 y[iColumn] = value;
00319 }
00320 } else {
00321
00322 for (iColumn=0;iColumn<numberColumns_;iColumn++,j+=2) {
00323 double value = y[iColumn];
00324 int iRowM = indices_[j];
00325 int iRowP = indices_[j+1];
00326 if (iRowM>=0)
00327 value -= scalar*x[iRowM];
00328 if (iRowP>=0)
00329 value += scalar*x[iRowP];
00330 y[iColumn] = value;
00331 }
00332 }
00333 }
00334 void
00335 ClpNetworkMatrix::times(double scalar,
00336 const double * x, double * y,
00337 const double * rowScale,
00338 const double * columnScale) const
00339 {
00340
00341 times(scalar, x, y);
00342 }
00343 void
00344 ClpNetworkMatrix::transposeTimes( double scalar,
00345 const double * x, double * y,
00346 const double * rowScale,
00347 const double * columnScale) const
00348 {
00349
00350 transposeTimes(scalar, x, y);
00351 }
00352
00353
00354 void
00355 ClpNetworkMatrix::transposeTimes(const ClpSimplex * model, double scalar,
00356 const CoinIndexedVector * rowArray,
00357 CoinIndexedVector * y,
00358 CoinIndexedVector * columnArray) const
00359 {
00360
00361 columnArray->clear();
00362 double * pi = rowArray->denseVector();
00363 int numberNonZero=0;
00364 int * index = columnArray->getIndices();
00365 double * array = columnArray->denseVector();
00366 int numberInRowArray = rowArray->getNumElements();
00367
00368 double zeroTolerance = model->factorization()->zeroTolerance();
00369 int numberRows = model->numberRows();
00370 ClpPlusMinusOneMatrix* rowCopy =
00371 dynamic_cast< ClpPlusMinusOneMatrix*>(model->rowCopy());
00372 bool packed = rowArray->packedMode();
00373 double factor = 0.3;
00374
00375 int numberColumns = model->numberColumns();
00376
00377
00378 if (numberColumns*sizeof(double)>1000000) {
00379 if (numberRows*10<numberColumns)
00380 factor=0.1;
00381 else if (numberRows*4<numberColumns)
00382 factor=0.15;
00383 else if (numberRows*2<numberColumns)
00384 factor=0.2;
00385
00386
00387 }
00388 if (numberInRowArray>factor*numberRows||!rowCopy) {
00389
00390 int iColumn;
00391 assert (!y->getNumElements());
00392 CoinBigIndex j=0;
00393 if (packed) {
00394
00395 assert(y->capacity()>=numberRows);
00396 double * piOld = pi;
00397 pi = y->denseVector();
00398 const int * whichRow = rowArray->getIndices();
00399 int i;
00400
00401 for (i=0;i<numberInRowArray;i++) {
00402 int iRow = whichRow[i];
00403 pi[iRow]=scalar*piOld[i];
00404 }
00405 if (trueNetwork_) {
00406 for (iColumn=0;iColumn<numberColumns_;iColumn++,j+=2) {
00407 double value = 0.0;
00408 int iRowM = indices_[j];
00409 int iRowP = indices_[j+1];
00410 value -= pi[iRowM];
00411 value += pi[iRowP];
00412 if (fabs(value)>zeroTolerance) {
00413 array[numberNonZero]=value;
00414 index[numberNonZero++]=iColumn;
00415 }
00416 }
00417 } else {
00418
00419 for (iColumn=0;iColumn<numberColumns_;iColumn++,j+=2) {
00420 double value = 0.0;
00421 int iRowM = indices_[j];
00422 int iRowP = indices_[j+1];
00423 if (iRowM>=0)
00424 value -= pi[iRowM];
00425 if (iRowP>=0)
00426 value += pi[iRowP];
00427 if (fabs(value)>zeroTolerance) {
00428 array[numberNonZero]=value;
00429 index[numberNonZero++]=iColumn;
00430 }
00431 }
00432 }
00433 for (i=0;i<numberInRowArray;i++) {
00434 int iRow = whichRow[i];
00435 pi[iRow]=0.0;
00436 }
00437 } else {
00438 if (trueNetwork_) {
00439 for (iColumn=0;iColumn<numberColumns_;iColumn++,j+=2) {
00440 double value = 0.0;
00441 int iRowM = indices_[j];
00442 int iRowP = indices_[j+1];
00443 value -= scalar*pi[iRowM];
00444 value += scalar*pi[iRowP];
00445 if (fabs(value)>zeroTolerance) {
00446 index[numberNonZero++]=iColumn;
00447 array[iColumn]=value;
00448 }
00449 }
00450 } else {
00451
00452 for (iColumn=0;iColumn<numberColumns_;iColumn++,j+=2) {
00453 double value = 0.0;
00454 int iRowM = indices_[j];
00455 int iRowP = indices_[j+1];
00456 if (iRowM>=0)
00457 value -= scalar*pi[iRowM];
00458 if (iRowP>=0)
00459 value += scalar*pi[iRowP];
00460 if (fabs(value)>zeroTolerance) {
00461 index[numberNonZero++]=iColumn;
00462 array[iColumn]=value;
00463 }
00464 }
00465 }
00466 }
00467 columnArray->setNumElements(numberNonZero);
00468 } else {
00469
00470 rowCopy->transposeTimesByRow(model, scalar, rowArray, y, columnArray);
00471 }
00472 }
00473
00474
00475
00476 void
00477 ClpNetworkMatrix::subsetTransposeTimes(const ClpSimplex * model,
00478 const CoinIndexedVector * rowArray,
00479 const CoinIndexedVector * y,
00480 CoinIndexedVector * columnArray) const
00481 {
00482 columnArray->clear();
00483 double * pi = rowArray->denseVector();
00484 double * array = columnArray->denseVector();
00485 int jColumn;
00486 int numberToDo = y->getNumElements();
00487 const int * which = y->getIndices();
00488 assert (!rowArray->packedMode());
00489 columnArray->setPacked();
00490 if (trueNetwork_) {
00491 for (jColumn=0;jColumn<numberToDo;jColumn++) {
00492 int iColumn = which[jColumn];
00493 double value = 0.0;
00494 CoinBigIndex j=iColumn<<1;
00495 int iRowM = indices_[j];
00496 int iRowP = indices_[j+1];
00497 value -= pi[iRowM];
00498 value += pi[iRowP];
00499 array[jColumn]=value;
00500 }
00501 } else {
00502
00503 for (jColumn=0;jColumn<numberToDo;jColumn++) {
00504 int iColumn = which[jColumn];
00505 double value = 0.0;
00506 CoinBigIndex j=iColumn<<1;
00507 int iRowM = indices_[j];
00508 int iRowP = indices_[j+1];
00509 if (iRowM>=0)
00510 value -= pi[iRowM];
00511 if (iRowP>=0)
00512 value += pi[iRowP];
00513 array[jColumn]=value;
00514 }
00515 }
00516 }
00517
00518
00519 CoinBigIndex
00520 ClpNetworkMatrix::numberInBasis(const int * columnIsBasic) const
00521 {
00522 int i;
00523 CoinBigIndex numberElements=0;
00524 if (trueNetwork_) {
00525 for (i=0;i<numberColumns_;i++) {
00526 if (columnIsBasic[i]>=0)
00527 numberElements ++;
00528 }
00529 numberElements *= 2;
00530 } else {
00531 for (i=0;i<numberColumns_;i++) {
00532 if (columnIsBasic[i]>=0) {
00533 CoinBigIndex j=i<<1;
00534 int iRowM = indices_[j];
00535 int iRowP = indices_[j+1];
00536 if (iRowM>=0)
00537 numberElements ++;
00538 if (iRowP>=0)
00539 numberElements ++;
00540 }
00541 }
00542 }
00543 return numberElements;
00544 }
00545
00546 CoinBigIndex
00547 ClpNetworkMatrix::fillBasis(const ClpSimplex * model,
00548 const int * columnIsBasic, int & numberBasic,
00549 int * indexRowU, int * indexColumnU,
00550 double * elementU) const
00551 {
00552 #ifdef CLPDEBUG
00553 const double * rowScale = model->rowScale();
00554 assert (!rowScale);
00555 #endif
00556 int i;
00557 CoinBigIndex numberElements=0;
00558 if (trueNetwork_) {
00559 for (i=0;i<numberColumns_;i++) {
00560 if (columnIsBasic[i]>=0) {
00561 CoinBigIndex j=i<<1;
00562 int iRowM = indices_[j];
00563 int iRowP = indices_[j+1];
00564 indexRowU[numberElements]=iRowM;
00565 indexColumnU[numberElements]=numberBasic;
00566 elementU[numberElements]=-1.0;
00567 indexRowU[numberElements+1]=iRowP;
00568 indexColumnU[numberElements+1]=numberBasic;
00569 elementU[numberElements+1]=1.0;
00570 numberElements+=2;
00571 numberBasic++;
00572 }
00573 }
00574 } else {
00575 for (i=0;i<numberColumns_;i++) {
00576 if (columnIsBasic[i]>=0) {
00577 CoinBigIndex j=i<<1;
00578 int iRowM = indices_[j];
00579 int iRowP = indices_[j+1];
00580 if (iRowM>=0) {
00581 indexRowU[numberElements]=iRowM;
00582 indexColumnU[numberElements]=numberBasic;
00583 elementU[numberElements++]=-1.0;
00584 }
00585 if (iRowP>=0) {
00586 indexRowU[numberElements]=iRowP;
00587 indexColumnU[numberElements]=numberBasic;
00588 elementU[numberElements++]=1.0;
00589 }
00590 numberBasic++;
00591 }
00592 }
00593 }
00594 return numberElements;
00595 }
00596
00597
00598 CoinBigIndex
00599 ClpNetworkMatrix::fillBasis(const ClpSimplex * model,
00600 const int * whichColumn,
00601 int numberBasic,
00602 int numberColumnBasic,
00603 int * indexRowU, int * indexColumnU,
00604 double * elementU) const
00605 {
00606 int i;
00607 CoinBigIndex numberElements=0;
00608 if (elementU!=NULL) {
00609 if (trueNetwork_) {
00610 for (i=0;i<numberColumnBasic;i++) {
00611 int iColumn = whichColumn[i];
00612 CoinBigIndex j=iColumn<<1;
00613 int iRowM = indices_[j];
00614 int iRowP = indices_[j+1];
00615 indexRowU[numberElements]=iRowM;
00616 indexColumnU[numberElements]=numberBasic;
00617 elementU[numberElements]=-1.0;
00618 indexRowU[numberElements+1]=iRowP;
00619 indexColumnU[numberElements+1]=numberBasic;
00620 elementU[numberElements+1]=1.0;
00621 numberElements+=2;
00622 numberBasic++;
00623 }
00624 } else {
00625 for (i=0;i<numberColumnBasic;i++) {
00626 int iColumn = whichColumn[i];
00627 CoinBigIndex j=iColumn<<1;
00628 int iRowM = indices_[j];
00629 int iRowP = indices_[j+1];
00630 if (iRowM>=0) {
00631 indexRowU[numberElements]=iRowM;
00632 indexColumnU[numberElements]=numberBasic;
00633 elementU[numberElements++]=-1.0;
00634 }
00635 if (iRowP>=0) {
00636 indexRowU[numberElements]=iRowP;
00637 indexColumnU[numberElements]=numberBasic;
00638 elementU[numberElements++]=1.0;
00639 }
00640 numberBasic++;
00641 }
00642 }
00643 } else {
00644 if (trueNetwork_) {
00645 numberElements = 2*numberColumnBasic;
00646 } else {
00647 for (i=0;i<numberColumnBasic;i++) {
00648 int iColumn = whichColumn[i];
00649 CoinBigIndex j=iColumn<<1;
00650 int iRowM = indices_[j];
00651 int iRowP = indices_[j+1];
00652 if (iRowM>=0)
00653 numberElements ++;
00654 if (iRowP>=0)
00655 numberElements ++;
00656 }
00657 }
00658 }
00659 return numberElements;
00660 }
00661
00662
00663 void
00664 ClpNetworkMatrix::unpack(const ClpSimplex * model,CoinIndexedVector * rowArray,
00665 int iColumn) const
00666 {
00667 CoinBigIndex j=iColumn<<1;
00668 int iRowM = indices_[j];
00669 int iRowP = indices_[j+1];
00670 if (iRowM>=0)
00671 rowArray->add(iRowM,-1.0);
00672 if (iRowP>=0)
00673 rowArray->add(iRowP,1.0);
00674 }
00675
00676
00677
00678
00679 void
00680 ClpNetworkMatrix::unpackPacked(ClpSimplex * model,
00681 CoinIndexedVector * rowArray,
00682 int iColumn) const
00683 {
00684 int * index = rowArray->getIndices();
00685 double * array = rowArray->denseVector();
00686 int number = 0;
00687 CoinBigIndex j=iColumn<<1;
00688 int iRowM = indices_[j];
00689 int iRowP = indices_[j+1];
00690 if (iRowM>=0) {
00691 array[number]=-1.0;
00692 index[number++]=iRowM;
00693 }
00694 if (iRowP>=0) {
00695 array[number]=1.0;
00696 index[number++]=iRowP;
00697 }
00698 rowArray->setNumElements(number);
00699 rowArray->setPackedMode(true);
00700 }
00701
00702
00703 void
00704 ClpNetworkMatrix::add(const ClpSimplex * model,CoinIndexedVector * rowArray,
00705 int iColumn, double multiplier) const
00706 {
00707 CoinBigIndex j=iColumn<<1;
00708 int iRowM = indices_[j];
00709 int iRowP = indices_[j+1];
00710 if (iRowM>=0)
00711 rowArray->quickAdd(iRowM,-multiplier);
00712 if (iRowP>=0)
00713 rowArray->quickAdd(iRowP,multiplier);
00714 }
00715
00716
00717 CoinPackedMatrix *
00718 ClpNetworkMatrix::getPackedMatrix() const
00719 {
00720 return new CoinPackedMatrix(true,numberRows_,numberColumns_,
00721 2*numberColumns_,
00722 getElements(),indices_,
00723 getVectorStarts(),getVectorLengths());
00724
00725 }
00726
00727
00728
00729
00730 const double *
00731 ClpNetworkMatrix::getElements() const
00732 {
00733 assert (trueNetwork_);
00734 if (!elements_) {
00735 elements_ = new double [2*numberColumns_];
00736 int i;
00737 for (i=0;i<2*numberColumns_;i+=2) {
00738 elements_[i]=-1.0;
00739 elements_[i+1]=1.0;
00740 }
00741 }
00742 return elements_;
00743 }
00744
00745 const CoinBigIndex *
00746 ClpNetworkMatrix::getVectorStarts() const
00747 {
00748 assert (trueNetwork_);
00749 if (!starts_) {
00750 starts_ = new int [numberColumns_+1];
00751 int i;
00752 for (i=0;i<numberColumns_+1;i++) {
00753 starts_[i]=i;
00754 }
00755 }
00756 return starts_;
00757 }
00758
00759 const int *
00760 ClpNetworkMatrix::getVectorLengths() const
00761 {
00762 assert (trueNetwork_);
00763 if (!lengths_) {
00764 lengths_ = new int [numberColumns_];
00765 int i;
00766 for (i=0;i<numberColumns_;i++) {
00767 lengths_[i]=2;
00768 }
00769 }
00770 return lengths_;
00771 }
00772
00773 void ClpNetworkMatrix::deleteCols(const int numDel, const int * indDel)
00774 {
00775 std::cerr<<"deleteCols not implemented in ClpNetworkMatrix"<<std::endl;
00776 abort();
00777 }
00778
00779 void ClpNetworkMatrix::deleteRows(const int numDel, const int * indDel)
00780 {
00781 std::cerr<<"deleteRows not implemented in ClpNetworkMatrix"<<std::endl;
00782 abort();
00783 }
00784
00785
00786
00787
00788 CoinBigIndex *
00789 ClpNetworkMatrix::dubiousWeights(const ClpSimplex * model,int * inputWeights) const
00790 {
00791 int numberRows = model->numberRows();
00792 int numberColumns =model->numberColumns();
00793 int number = numberRows+numberColumns;
00794 CoinBigIndex * weights = new CoinBigIndex[number];
00795 int i;
00796 for (i=0;i<numberColumns;i++) {
00797 CoinBigIndex j=i<<1;
00798 CoinBigIndex count=0;
00799 int iRowM = indices_[j];
00800 int iRowP = indices_[j+1];
00801 if (iRowM>=0) {
00802 count += inputWeights[iRowM];
00803 }
00804 if (iRowP>=0) {
00805 count += inputWeights[iRowP];
00806 }
00807 weights[i]=count;
00808 }
00809 for (i=0;i<numberRows;i++) {
00810 weights[i+numberColumns]=inputWeights[i];
00811 }
00812 return weights;
00813 }
00814
00815
00816
00817 void
00818 ClpNetworkMatrix::rangeOfElements(double & smallestNegative, double & largestNegative,
00819 double & smallestPositive, double & largestPositive)
00820 {
00821 smallestNegative=-1.0;
00822 largestNegative=-1.0;
00823 smallestPositive=1.0;
00824 largestPositive=1.0;
00825 }
00826
00827 bool
00828 ClpNetworkMatrix::canDoPartialPricing() const
00829 {
00830 return true;
00831 }
00832
00833 void
00834 ClpNetworkMatrix::partialPricing(ClpSimplex * model, int start, int end,
00835 int & bestSequence, int & numberWanted)
00836 {
00837 int j;
00838 double tolerance=model->currentDualTolerance();
00839 double * reducedCost = model->djRegion();
00840 const double * duals = model->dualRowSolution();
00841 const double * cost = model->costRegion();
00842 double bestDj;
00843 if (bestSequence>=0)
00844 bestDj = fabs(reducedCost[bestSequence]);
00845 else
00846 bestDj=tolerance;
00847 int sequenceOut = model->sequenceOut();
00848 int saveSequence = bestSequence;
00849 if (!trueNetwork_) {
00850
00851 int iSequence;
00852 for (iSequence=start;iSequence<end;iSequence++) {
00853 if (iSequence!=sequenceOut) {
00854 double value;
00855 int iRowM,iRowP;
00856 ClpSimplex::Status status = model->getStatus(iSequence);
00857
00858 switch(status) {
00859
00860 case ClpSimplex::basic:
00861 case ClpSimplex::isFixed:
00862 break;
00863 case ClpSimplex::isFree:
00864 case ClpSimplex::superBasic:
00865 value=cost[iSequence];
00866 j = iSequence<<1;
00867
00868 iRowM = indices_[j];
00869 iRowP = indices_[j+1];
00870 if (iRowM>=0)
00871 value += duals[iRowM];
00872 if (iRowP>=0)
00873 value -= duals[iRowP];
00874 value = fabs(value);
00875 if (value>FREE_ACCEPT*tolerance) {
00876 numberWanted--;
00877
00878 value *= FREE_BIAS;
00879 if (value>bestDj) {
00880
00881 if (!model->flagged(iSequence)) {
00882 bestDj=value;
00883 bestSequence = iSequence;
00884 } else {
00885
00886 numberWanted++;
00887 }
00888 }
00889 }
00890 break;
00891 case ClpSimplex::atUpperBound:
00892 value=cost[iSequence];
00893 j = iSequence<<1;
00894
00895 iRowM = indices_[j];
00896 iRowP = indices_[j+1];
00897 if (iRowM>=0)
00898 value += duals[iRowM];
00899 if (iRowP>=0)
00900 value -= duals[iRowP];
00901 if (value>tolerance) {
00902 numberWanted--;
00903 if (value>bestDj) {
00904
00905 if (!model->flagged(iSequence)) {
00906 bestDj=value;
00907 bestSequence = iSequence;
00908 } else {
00909
00910 numberWanted++;
00911 }
00912 }
00913 }
00914 break;
00915 case ClpSimplex::atLowerBound:
00916 value=cost[iSequence];
00917 j = iSequence<<1;
00918
00919 iRowM = indices_[j];
00920 iRowP = indices_[j+1];
00921 if (iRowM>=0)
00922 value += duals[iRowM];
00923 if (iRowP>=0)
00924 value -= duals[iRowP];
00925 value = -value;
00926 if (value>tolerance) {
00927 numberWanted--;
00928 if (value>bestDj) {
00929
00930 if (!model->flagged(iSequence)) {
00931 bestDj=value;
00932 bestSequence = iSequence;
00933 } else {
00934
00935 numberWanted++;
00936 }
00937 }
00938 }
00939 break;
00940 }
00941 }
00942 if (!numberWanted)
00943 break;
00944 }
00945 if (bestSequence!=saveSequence) {
00946
00947 double value=cost[bestSequence];
00948 j = bestSequence<<1;
00949
00950 int iRowM = indices_[j];
00951 int iRowP = indices_[j+1];
00952 if (iRowM>=0)
00953 value += duals[iRowM];
00954 if (iRowP>=0)
00955 value -= duals[iRowP];
00956 reducedCost[bestSequence] = value;
00957 }
00958 } else {
00959
00960 int iSequence;
00961 for (iSequence=start;iSequence<end;iSequence++) {
00962 if (iSequence!=sequenceOut) {
00963 double value;
00964 int iRowM,iRowP;
00965 ClpSimplex::Status status = model->getStatus(iSequence);
00966
00967 switch(status) {
00968
00969 case ClpSimplex::basic:
00970 case ClpSimplex::isFixed:
00971 break;
00972 case ClpSimplex::isFree:
00973 case ClpSimplex::superBasic:
00974 value=cost[iSequence];
00975 j = iSequence<<1;
00976 iRowM = indices_[j];
00977 iRowP = indices_[j+1];
00978 value += duals[iRowM];
00979 value -= duals[iRowP];
00980 value = fabs(value);
00981 if (value>FREE_ACCEPT*tolerance) {
00982 numberWanted--;
00983
00984 value *= FREE_BIAS;
00985 if (value>bestDj) {
00986
00987 if (!model->flagged(iSequence)) {
00988 bestDj=value;
00989 bestSequence = iSequence;
00990 } else {
00991
00992 numberWanted++;
00993 }
00994 }
00995 }
00996 break;
00997 case ClpSimplex::atUpperBound:
00998 value=cost[iSequence];
00999 j = iSequence<<1;
01000 iRowM = indices_[j];
01001 iRowP = indices_[j+1];
01002 value += duals[iRowM];
01003 value -= duals[iRowP];
01004 if (value>tolerance) {
01005 numberWanted--;
01006 if (value>bestDj) {
01007
01008 if (!model->flagged(iSequence)) {
01009 bestDj=value;
01010 bestSequence = iSequence;
01011 } else {
01012
01013 numberWanted++;
01014 }
01015 }
01016 }
01017 break;
01018 case ClpSimplex::atLowerBound:
01019 value=cost[iSequence];
01020 j = iSequence<<1;
01021 iRowM = indices_[j];
01022 iRowP = indices_[j+1];
01023 value += duals[iRowM];
01024 value -= duals[iRowP];
01025 value = -value;
01026 if (value>tolerance) {
01027 numberWanted--;
01028 if (value>bestDj) {
01029
01030 if (!model->flagged(iSequence)) {
01031 bestDj=value;
01032 bestSequence = iSequence;
01033 } else {
01034
01035 numberWanted++;
01036 }
01037 }
01038 }
01039 break;
01040 }
01041 }
01042 if (!numberWanted)
01043 break;
01044 }
01045 if (bestSequence!=saveSequence) {
01046
01047 double value=cost[bestSequence];
01048 j = bestSequence<<1;
01049 int iRowM = indices_[j];
01050 int iRowP = indices_[j+1];
01051 value += duals[iRowM];
01052 value -= duals[iRowP];
01053 reducedCost[bestSequence] = value;
01054 }
01055 }
01056 }