00001
00002
00003 #if defined(_MSC_VER)
00004
00005 # pragma warning(disable:4786)
00006 #endif
00007 #include <cstdlib>
00008 #include <cstdio>
00009 #include <cmath>
00010 #include <cfloat>
00011 #include <cassert>
00012 #include <iostream>
00013
00014 #include "CoinHelperFunctions.hpp"
00015 #include "CoinPackedVector.hpp"
00016 #include "CoinPackedMatrix.hpp"
00017 #include "CoinIndexedVector.hpp"
00018 #include "OsiRowCutDebugger.hpp"
00019 #include "CoinFactorization.hpp"
00020 #include "CoinWarmStartBasis.hpp"
00021 #include "CglGomory.hpp"
00022 #include "CoinFinite.hpp"
00023
00024
00025
00026 void CglGomory::generateCuts(const OsiSolverInterface & si,
00027 OsiCuts & cs ) const
00028 {
00029
00030 int numberColumns=si.getNumCols();
00031
00032
00033 char * intVar = new char[numberColumns];
00034 int i;
00035 CoinWarmStart * warmstart = si.getWarmStart();
00036 const CoinWarmStartBasis* warm =
00037 dynamic_cast<const CoinWarmStartBasis*>(warmstart);
00038 const double * colUpper = si.getColUpper();
00039 const double * colLower = si.getColLower();
00040 for (i=0;i<numberColumns;i++) {
00041 if (si.isInteger(i)) {
00042 if (colUpper[i]>colLower[i]+0.5) {
00043 if (fabs(colUpper[i]-1.0)<1.0e-12&&fabs(colLower[i])<1.0e-12) {
00044 intVar[i]=1;
00045 } else if (colLower[i]>=0.0) {
00046 intVar[i] = 2;
00047 } else {
00048
00049 intVar[i] = 0;
00050 }
00051 } else {
00052 intVar[i] = 0;
00053 }
00054 } else {
00055 intVar[i]=0;
00056 }
00057 }
00058 #ifdef CGL_DEBUG
00059 const OsiRowCutDebugger * debugger = si.getRowCutDebugger();
00060 if (debugger&&!debugger->onOptimalPath(si))
00061 debugger = NULL;
00062 #else
00063 const OsiRowCutDebugger * debugger = NULL;
00064 #endif
00065
00066 generateCuts(debugger, cs, *si.getMatrixByCol(),
00067 si.getObjCoefficients(), si.getColSolution(),
00068 si.getColLower(), si.getColUpper(),
00069 si.getRowLower(), si.getRowUpper(),
00070 intVar,warm);
00071
00072 delete warmstart;
00073 delete [] intVar;
00074 }
00075
00076
00077 inline double above_integer(double value)
00078 {
00079 double value2=floor(value);
00080 double value3=floor(value+0.5);
00081 if (fabs(value3-value)<1.0e-7*(fabs(value3)+1.0))
00082 return 0.0;
00083 return value-value2;
00084 }
00085
00086
00087
00088
00089 static int gcd(int a, int b)
00090 {
00091 int remainder = -1;
00092 #if CGL_DEBUG>1
00093 printf("gcd of %d and %d\n",a,b);
00094 int nLoop=0;
00095 #endif
00096
00097 if(a > b) {
00098
00099 int temp = a;
00100 a = b;
00101 b = temp;
00102 }
00103
00104 if (!a) {
00105 if (b) {
00106 return b;
00107 } else {
00108 printf("**** gcd given two zeros!!\n");
00109 abort();
00110 }
00111 }
00112 while (remainder) {
00113
00114 #if CGL_DEBUG>1
00115 nLoop++;
00116 if (nLoop>50) {
00117 abort();
00118 return -1;
00119 }
00120 #endif
00121 remainder = b % a;
00122 b = a;
00123 a = remainder;
00124 }
00125 #if CGL_DEBUG>1
00126 printf("=> %d\n",b);
00127 #endif
00128 return b;
00129 }
00130
00131
00132
00133
00134 typedef struct {
00135 int numerator;
00136 int denominator;
00137 } Rational;
00138 inline Rational nearestRational(double value, int maxDenominator)
00139 {
00140 Rational tryThis;
00141 Rational tryA;
00142 Rational tryB;
00143 double integerPart;
00144
00145 #if CGL_DEBUG>1
00146 printf("Rational of %g is ",value);
00147 #endif
00148 int nLoop=0;
00149
00150 tryA.numerator=0;
00151 tryA.denominator=1;
00152 tryB.numerator=1;
00153 tryB.denominator=0;
00154
00155 if (fabs(value)<1.0e-10)
00156 return tryA;
00157 integerPart = floor(value);
00158 value -= integerPart;
00159 tryThis.numerator = tryB.numerator* (int ) integerPart + tryA.numerator;
00160 tryThis.denominator = tryB.denominator* (int ) integerPart + tryA.denominator;
00161 tryA = tryB;
00162 tryB = tryThis;
00163
00164 while (value>1.0e-10 && tryB.denominator <=maxDenominator) {
00165 nLoop++;
00166 if (nLoop>50) {
00167 Rational bad;
00168 bad.numerator=-1;
00169 bad.denominator=-1;
00170 #if CGL_DEBUG>1
00171 printf(" *** bad rational\n");
00172 #endif
00173 return bad;
00174 }
00175 value = 1.0/value;
00176 integerPart = floor(value+1.0e-10);
00177 value -= integerPart;
00178 tryThis.numerator = tryB.numerator* (int ) integerPart + tryA.numerator;
00179 tryThis.denominator = tryB.denominator* (int ) integerPart + tryA.denominator;
00180 tryA = tryB;
00181 tryB = tryThis;
00182 }
00183 if (tryB.denominator <= maxDenominator) {
00184 #if CGL_DEBUG>1
00185 printf("%d/%d\n",tryB.numerator,tryB.denominator);
00186 #endif
00187 return tryB;
00188 } else {
00189 #if CGL_DEBUG>1
00190 printf("%d/%d\n",tryA.numerator,tryA.denominator);
00191 #endif
00192 return tryA;
00193 }
00194 }
00195
00196
00197 int
00198 CglGomory::generateCuts( const OsiRowCutDebugger * debugger,
00199 OsiCuts & cs,
00200 const CoinPackedMatrix & columnCopy,
00201 const double * objective, const double * colsol,
00202 const double * colLower, const double * colUpper,
00203 const double * rowLower, const double * rowUpper,
00204 const char * intVar,
00205 const CoinWarmStartBasis* warm) const
00206 {
00207 int numberRows=columnCopy.getNumRows();
00208 int numberColumns=columnCopy.getNumCols();
00209
00210
00211
00212 CoinFactorization factorization;
00213
00214
00215
00216 factorization.increasingRows(2);
00217 int status=-100;
00218
00219 int * rowIsBasic = new int[numberRows];
00220 int * columnIsBasic = new int[numberColumns];
00221 int i;
00222 int numberBasic=0;
00223 for (i=0;i<numberRows;i++) {
00224 if (warm->getArtifStatus(i) == CoinWarmStartBasis::basic) {
00225 rowIsBasic[i]=1;
00226 numberBasic++;
00227 } else {
00228 rowIsBasic[i]=-1;
00229 }
00230 }
00231 for (i=0;i<numberColumns;i++) {
00232 if (warm->getStructStatus(i) == CoinWarmStartBasis::basic) {
00233 columnIsBasic[i]=1;
00234 numberBasic++;
00235 } else {
00236 columnIsBasic[i]=-1;
00237 }
00238 }
00239
00240 while (status<-98) {
00241 status=factorization.factorize(columnCopy,
00242 rowIsBasic, columnIsBasic);
00243 if (status==-99) factorization.areaFactor(factorization.areaFactor() * 2.0);
00244 }
00245 if (status) {
00246 std::cout<<"Bad factorization of basis - status "<<status<<std::endl;
00247 return -1;
00248 }
00249
00250
00251 double bounds[2]={-DBL_MAX,0.0};
00252 int iColumn,iRow;
00253
00254
00255 CoinPackedMatrix rowCopy = columnCopy;
00256 rowCopy.reverseOrdering();
00257 const int * column = rowCopy.getIndices();
00258 const int * rowStart = rowCopy.getVectorStarts();
00259 const int * rowLength = rowCopy.getVectorLengths();
00260 const double * rowElements = rowCopy.getElements();
00261 const int * row = columnCopy.getIndices();
00262 const int * columnStart = columnCopy.getVectorStarts();
00263 const int * columnLength = columnCopy.getVectorLengths();
00264 const double * columnElements = columnCopy.getElements();
00265
00266
00267 double tolerance = 1.0e-7;
00268 bool * swap= new bool [numberColumns];
00269 for (iColumn=0;iColumn<numberColumns;iColumn++) {
00270 if (columnIsBasic[iColumn]<0&&
00271 colUpper[iColumn]-colsol[iColumn]<=tolerance) {
00272 swap[iColumn]=true;
00273 } else {
00274 swap[iColumn]=false;
00275 }
00276 }
00277
00278
00279 double * rowActivity = new double [numberRows];
00280 CoinFillN(rowActivity,numberRows,0.0);
00281 for (iColumn=0;iColumn<numberColumns;iColumn++) {
00282 double value = colsol[iColumn];
00283 int k;
00284 for (k=columnStart[iColumn];k<columnStart[iColumn]+columnLength[iColumn];k++) {
00285 iRow = row[k];
00286 rowActivity[iRow] += columnElements[k]*value;
00287 }
00288 }
00289
00290
00291
00292
00293
00294
00295
00296 int * rowType = new int[numberRows];
00297 for (iRow=0;iRow<numberRows;iRow++) {
00298 if (rowIsBasic[iRow]<0&&rowUpper[iRow]>rowLower[iRow]+1.0e-7) {
00299 int type=0;
00300 double rhs=0.0;
00301 if (rowActivity[iRow]>=rowUpper[iRow]-1.0e-7) {
00302 type=1;
00303 rhs=rowUpper[iRow];
00304 } else if (rowActivity[iRow]<=rowLower[iRow]+1.0e-7) {
00305 type=2;
00306 rhs=rowLower[iRow];
00307 } else {
00308
00309 rowType[iRow]=type;
00310 #ifdef CGL_DEBUG
00311 assert (min(rowUpper[iRow]-rowActivity[iRow],
00312 rowActivity[iRow]-rowUpper[iRow])<1.0e-7);
00313 abort();
00314 #else
00315 continue;
00316 #endif
00317 }
00318 if (above_integer(rhs)<1.0e-10) {
00319
00320 bool allInteger=true;
00321 int k;
00322 for (k=rowStart[iRow];
00323 k<rowStart[iRow]+rowLength[iRow];k++) {
00324 int iColumn=column[k];
00325 if (!intVar[iColumn]||above_integer(rowElements[k])>1.0e-10) {
00326
00327 allInteger=false;
00328 break;
00329 }
00330 }
00331 if (allInteger) {
00332 type |= 4;
00333 }
00334 }
00335 rowType[iRow]=type;
00336 } else {
00337
00338 rowType[iRow]=0;
00339 }
00340 }
00341
00342
00343
00344 CoinIndexedVector work;
00345 CoinIndexedVector array;
00346
00347 work.reserve(numberRows);
00348 array.reserve(numberRows);
00349 int * arrayRows = array.getIndices();
00350 double * arrayElements = array.denseVector();
00351
00352
00353 int numberAdded=0;
00354
00355 CoinIndexedVector cutVector;
00356 cutVector.reserve(numberColumns+1);
00357 int * cutIndex = cutVector.getIndices();
00358 double * cutElement = cutVector.denseVector();
00359
00360 double * packed = new double[numberColumns+1];
00361
00362 for (iColumn=0;iColumn<numberColumns;iColumn++) {
00363 double reducedValue=above_integer(colsol[iColumn]);;
00364
00365 int iBasic=columnIsBasic[iColumn];
00366 double ratio=reducedValue/(1.0-reducedValue);
00367 if (iBasic>=0) {
00368
00369 int j;
00370 #ifdef CGL_DEBUG
00371 {
00372
00373 array.setVector(columnLength[iColumn],row+columnStart[iColumn],
00374 columnElements+columnStart[iColumn]);
00375
00376 factorization.updateColumn ( &work, &array );
00377 int nn=0;
00378 int numberInArray=array.getNumElements();
00379 for (j=0;j<numberInArray;j++) {
00380 int indexValue=arrayRows[j];
00381 double value=arrayElements[indexValue];
00382 if (fabs(value)>1.0e-6) {
00383 assert (fabs(value-1.0)<1.0e-7);
00384 assert (indexValue==iBasic);
00385 nn++;
00386 }
00387 }
00388 assert (nn==1);
00389 }
00390 #endif
00391 if(intVar[iColumn]&&reducedValue<1.0-away_&&reducedValue>away_) {
00392 #ifdef CGL_DEBUG
00393 cutVector.checkClear();
00394 #endif
00395
00396 double one =1.0;
00397 array.setVector(1,&iBasic,&one);
00398 int numberNonInteger=0;
00399
00400
00401 factorization.updateColumnTranspose ( &work, &array );
00402 int numberInArray=array.getNumElements();
00403
00404 {
00405 double value=0.0;
00406 int k;
00407
00408 for (k=columnStart[iColumn];
00409 k<columnStart[iColumn]+columnLength[iColumn];k++) {
00410 iRow = row[k];
00411 value += columnElements[k]*arrayElements[iRow];
00412 }
00413
00414 #ifdef CGL_DEBUG
00415 assert (fabs(value-1.0) < 1.0e-7);
00416 #endif
00417 }
00418
00419
00420
00421 double rhs=0.0;
00422 int number=0;
00423
00424 for (j=0;j<numberColumns;j++) {
00425 double value=0.0;
00426 if (columnIsBasic[j]<0&&
00427 colUpper[j]>colLower[j]+1.0e-8) {
00428 int k;
00429
00430 for (k=columnStart[j];k<columnStart[j]+columnLength[j];k++) {
00431 iRow = row[k];
00432 value += columnElements[k]*arrayElements[iRow];
00433 }
00434
00435 if (fabs(value)<1.0e-16) {
00436
00437 continue;
00438 } else {
00439 #if CGL_DEBUG>1
00440 if (iColumn==314) printf("for basic %d, column %d has alpha %g, colsol %g\n",
00441 iColumn,j,value,colsol[j]);
00442 #endif
00443
00444 if (swap[j]) {
00445
00446
00447 value = - value;
00448 } else {
00449
00450 }
00451 #if CGL_DEBUG>1
00452 if (iColumn==348) printf("%d value %g reduced %g int %d rhs %g swap %d\n",
00453 j,value,reducedValue,intVar[j],rhs,swap[j]);
00454 #endif
00455 double coefficient;
00456 if (intVar[j]) {
00457
00458 coefficient = above_integer(value);
00459 if (coefficient > reducedValue) {
00460 coefficient = ratio * (1.0-coefficient);
00461 }
00462 } else {
00463
00464 numberNonInteger++;
00465 if (value > 0.0) {
00466 coefficient = value;
00467 } else {
00468
00469 coefficient = -ratio*value;
00470 }
00471 }
00472 if (swap[j]) {
00473
00474 coefficient = - coefficient;
00475 rhs += colUpper[j]*coefficient;
00476 } else {
00477 rhs += colLower[j]*coefficient;
00478 }
00479 if (fabs(coefficient)>= COIN_INDEXED_TINY_ELEMENT) {
00480 cutElement[j] = coefficient;
00481 cutIndex[number++]=j;
00482
00483 if (number>limit_)
00484 break;
00485 }
00486 }
00487 } else {
00488
00489 continue;
00490 }
00491 }
00492 cutVector.setNumElements(number);
00493
00494 if (number>limit_) {
00495 cutVector.clear();
00496 continue;
00497 }
00498
00499
00500 rhs += reducedValue;
00501 double violation = reducedValue;
00502 #ifdef CGL_DEBUG
00503 std::cout<<"cut has violation of "<<violation
00504 <<" value "<<colsol[iColumn]<<std::endl;
00505 #endif
00506
00507 for (j=0;j<numberInArray;j++) {
00508 iRow=arrayRows[j];
00509 double value = arrayElements[iRow];
00510 int type=rowType[iRow];
00511 if (type&&fabs(value)>=1.0e-16) {
00512 if ((type&1)==0) {
00513
00514 value = - value;
00515 }
00516 double coefficient;
00517 if ((type&4)!=0) {
00518
00519 coefficient = above_integer(value);
00520 if (coefficient > reducedValue) {
00521 coefficient = ratio * (1.0-coefficient);
00522 }
00523 } else {
00524 numberNonInteger++;
00525
00526 if (value > 0.0) {
00527 coefficient = value;
00528 } else {
00529 coefficient = -ratio*value;
00530 }
00531 }
00532 if ((type&1)!=0) {
00533
00534 rhs -= coefficient*rowUpper[iRow];
00535 } else {
00536
00537 coefficient = - coefficient;
00538 rhs -= coefficient*rowLower[iRow];
00539 }
00540 int k;
00541 for (k=rowStart[iRow];
00542 k<rowStart[iRow]+rowLength[iRow];k++) {
00543 int jColumn=column[k];
00544 double value=rowElements[k];
00545 cutVector.add(jColumn,-coefficient*value);
00546 }
00547 }
00548 }
00549
00550
00551
00552 double sum=0.0;
00553 rhs = - rhs;
00554 int n = cutVector.getNumElements();
00555 number=0;
00556 for (j=0;j<n;j++) {
00557 int jColumn =cutIndex[j];
00558 double value=-cutElement[jColumn];
00559 cutElement[jColumn]=0.0;
00560 if (fabs(value)>1.0e-13) {
00561 sum+=value*colsol[jColumn];
00562 packed[number]=value;
00563 cutIndex[number++]=jColumn;
00564 }
00565 }
00566
00567 cutVector.setNumElements(0);
00568 if (sum >rhs+0.9*away_&&
00569 fabs((sum-rhs)-violation)<1.0e-6) {
00570
00571 #ifdef CGL_DEBUG
00572 #if CGL_DEBUG<=1
00573 if (number<=-10) {
00574 #endif
00575 for (j=0;j<number;j++) {
00576 std::cout<<" ["<<cutIndex[j]<<","<<packed[j]<<"]";
00577 }
00578 std::cout<<" <= "<<rhs<<std::endl;
00579 #if CGL_DEBUG<=1
00580 }
00581 #endif
00582 #endif
00583 if (!numberNonInteger&&number) {
00584 #ifdef CGL_DEBUG
00585 assert (sizeof(Rational)==sizeof(double));
00586 #endif
00587 Rational * cleaned = (Rational *) cutElement;
00588 int * xInt = (int *) cutElement;
00589
00590
00591 cutIndex[number]=numberColumns+1;
00592 packed[number]=rhs;
00593 int numberNonSmall=0;
00594 int lcm = 1;
00595
00596 for (j=0;j<number+1;j++) {
00597 double value=above_integer(fabs(packed[j]));
00598 if (fabs(value)<1.0e-4) {
00599
00600 continue;
00601 } else {
00602 numberNonSmall++;
00603 }
00604
00605 cleaned[j]=nearestRational(value,100000);
00606 if (cleaned[j].denominator<0) {
00607
00608 lcm=-1;
00609 break;
00610 }
00611 int thisGcd = gcd(lcm,cleaned[j].denominator);
00612
00613 lcm /= thisGcd;
00614 lcm *= cleaned[j].denominator;
00615 }
00616 if (lcm>0&&numberNonSmall) {
00617 double multiplier = lcm;
00618 int nOverflow = 0;
00619 for (j=0; j<number+1;j++) {
00620 double value = fabs(packed[j]);
00621 double dxInt = value*multiplier;
00622 xInt[j]= (int) (dxInt+0.5);
00623 #if CGL_DEBUG>1
00624 printf("%g => %g \n",value,dxInt);
00625 #endif
00626 if (dxInt>1.0e9||fabs(dxInt-xInt[j])> 1.0e-8) {
00627 nOverflow++;
00628 break;
00629 }
00630 }
00631
00632 if (nOverflow){
00633 #ifdef CGL_DEBUG
00634 printf("Gomory Scaling: Warning: Overflow detected \n");
00635 #endif
00636 numberNonInteger=-1;
00637 } else {
00638
00639
00640 j=0;
00641 while (!xInt[j])
00642 j++;
00643 int thisGcd = gcd(xInt[j],xInt[j+1]);
00644 j++;
00645 for (;j<number+1;j++) {
00646 if (xInt[j])
00647 thisGcd = gcd(thisGcd,xInt[j]);
00648 }
00649 #if 0
00650
00651 for (j=0;j<number+1;j++) {
00652 double old = lcm*packed[j];
00653 int newOne;
00654 if (old>0.0)
00655 newOne=xInt[j]/thisGcd;
00656 else
00657 newOne=-xInt[j]/thisGcd;
00658 if (fabs(((double) newOne)-old)>
00659 1.0e-10*(fabs(newOne)+1.0)) {
00660
00661 printf("Fix this test 456 - just skip\n");
00662 abort();
00663 }
00664 }
00665 #endif
00666 #if CGL_DEBUG>1
00667 printf("The gcd of xInt is %i\n",thisGcd);
00668 #endif
00669
00670
00671 double minMultiplier=1.0e100;
00672 double maxMultiplier=0.0;
00673 for (j=0; j<number+1;j++) {
00674 double old=packed[j];
00675 if (old>0.0) {
00676 packed[j]=xInt[j]/thisGcd;
00677 } else {
00678 packed[j]=-xInt[j]/thisGcd;
00679 }
00680 #if CGL_DEBUG>1
00681 printf("%g => %g \n",old,packed[j]);
00682 #endif
00683 if (packed[j]) {
00684 if (fabs(packed[j])>maxMultiplier*fabs(old))
00685 maxMultiplier = packed[j]/old;
00686 if (fabs(packed[j])<minMultiplier*fabs(old))
00687 minMultiplier = packed[j]/old;
00688 }
00689 }
00690 rhs = packed[number];
00691 double ratio=maxMultiplier/minMultiplier;
00692 #ifdef CGL_DEBUG
00693 printf("min, max multipliers - %g, %g\n",
00694 minMultiplier,maxMultiplier);
00695 #endif
00696 assert(ratio>0.9999&&ratio<1.0001);
00697 }
00698 }
00699
00700 CoinFillN(cutElement,number+1,0.0);
00701 } else {
00702
00703 rhs += 1.0e-8;
00704
00705 if (number>=20) {
00706 rhs += 1.0e-7*((double) (number/20));
00707 }
00708 }
00709
00710
00711 #define TINY_ELEMENT 1.0e-7
00712 {
00713 int i,number2=number;
00714 number=0;
00715 double largest=0.0;
00716 double smallest=1.0e30;
00717 for (i=0;i<number2;i++) {
00718 double value=fabs(packed[i]);
00719 if (value<TINY_ELEMENT) {
00720 int iColumn = cutIndex[i];
00721 if (colUpper[iColumn]-colLower[iColumn]<10.0) {
00722
00723 if (packed[i]>0.0)
00724 rhs -= value*colLower[iColumn];
00725 else
00726 rhs += value*colUpper[iColumn];
00727 } else {
00728
00729 number=limit_+1;
00730 numberNonInteger=1;
00731 break;
00732 }
00733 } else {
00734 largest=max(largest,value);
00735 smallest=min(smallest,value);
00736 cutIndex[number]=cutIndex[i];
00737 packed[number++]=packed[i];
00738 }
00739 }
00740 if (largest>1.0e9*smallest) {
00741 number=limit_+1;
00742 numberNonInteger=1;
00743 }
00744 }
00745 if (number<limit_||!numberNonInteger) {
00746 bounds[1]=rhs;
00747 if (number>50&&numberNonInteger)
00748 bounds[1] += 1.0e-6;
00749 {
00750 OsiRowCut rc;
00751 rc.setRow(number,cutIndex,packed);
00752 rc.setLb(bounds[0]);
00753 rc.setUb(bounds[1]);
00754 cs.insert(rc);
00755 #ifdef CGL_DEBUG
00756 if (!number)
00757 std::cout<<"******* Empty cut - infeasible"<<std::endl;
00758 if (debugger)
00759 assert(!debugger->invalidCut(rc));
00760 #endif
00761 }
00762 numberAdded++;
00763 } else {
00764 #ifdef CGL_DEBUG
00765 std::cout<<"cut has "<<number<<" entries - skipped"
00766 <<std::endl;
00767 if (!number)
00768 std::cout<<"******* Empty cut - infeasible"<<std::endl;
00769 #endif
00770 }
00771 } else {
00772
00773 #ifdef CGL_DEBUG
00774 std::cout<<"first violation "<<violation<<" now "
00775 <<sum-rhs<<" why?, rhs= "<<rhs<<std::endl;
00776
00777 for (j=0;j<number;j++) {
00778 int jColumn =cutIndex[j];
00779 double value=packed[j];
00780 std::cout<<"("<<jColumn<<","<<value<<","<<colsol[jColumn]
00781 <<") ";
00782 }
00783 std::cout<<std::endl;
00784 abort();
00785 #endif
00786 }
00787 }
00788 } else {
00789
00790 #if CGL_DEBUG>1
00791 {
00792
00793 array.setVector(columnLength[iColumn],row+columnStart[iColumn],
00794 columnElements+columnStart[iColumn]);
00795
00796 factorization.updateColumn ( &work, &array );
00797 int numberInArray=array.getNumElements();
00798 printf("non-basic %d\n",iColumn);
00799 for (j=0;j<numberInArray;j++) {
00800 int indexValue=arrayRows[j];
00801 double value=arrayElements[indexValue];
00802 if (fabs(value)>1.0e-6) {
00803 printf("%d %g\n",indexValue,value);
00804 }
00805 }
00806 }
00807 #endif
00808 }
00809 }
00810
00811 delete [] rowActivity;
00812 delete [] swap;
00813 delete [] rowType;
00814 delete [] packed;
00815 delete [] rowIsBasic;
00816 delete [] columnIsBasic;
00817 return numberAdded;
00818 }
00819
00820 void CglGomory::setLimit(int limit)
00821 {
00822 if (limit>0)
00823 limit_=limit;
00824 }
00825 int CglGomory::getLimit() const
00826 {
00827 return limit_;
00828 }
00829
00830
00831 void CglGomory::setAway(double value)
00832 {
00833 if (value>0.0&&value<=0.5)
00834 away_=value;
00835 }
00836 double CglGomory::getAway() const
00837 {
00838 return away_;
00839 }
00840
00841
00842
00843
00844 CglGomory::CglGomory ()
00845 :
00846 CglCutGenerator(),
00847 away_(0.05),
00848 limit_(50)
00849 {
00850
00851 }
00852
00853
00854
00855
00856 CglGomory::CglGomory (const CglGomory & source) :
00857 CglCutGenerator(source),
00858 away_(source.away_),
00859 limit_(source.limit_)
00860 {
00861 }
00862
00863
00864
00865
00866 CglGomory::~CglGomory ()
00867 {
00868 }
00869
00870
00871
00872
00873 CglGomory &
00874 CglGomory::operator=(const CglGomory& rhs)
00875 {
00876 if (this != &rhs) {
00877 CglCutGenerator::operator=(rhs);
00878 away_=rhs.away_;
00879 limit_=rhs.limit_;
00880 }
00881 return *this;
00882 }