00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #include "CouennePrecisions.hpp"
00012 #include "CouenneSolverInterface.hpp"
00013
00014 #define COIN_DEVELOP 4
00015
00016
00017
00018 int CouenneSolverInterface::tightenBoundsCLP_Light (int lightweight) {
00019
00020
00021
00022 int
00023 numberRows = getNumRows(),
00024 numberColumns = getNumCols();
00025
00026 const double * columnUpper = getColUpper();
00027 const double * columnLower = getColLower();
00028 const double * rowUpper = getRowUpper();
00029 const double * rowLower = getRowLower();
00030
00031
00032 const double * element = getMatrixByCol()->getElements();
00033 const int * row = getMatrixByCol()->getIndices();
00034 const CoinBigIndex * columnStart = getMatrixByCol()->getVectorStarts();
00035 const int * columnLength = getMatrixByCol()->getVectorLengths();
00036
00037 double * down = new double [numberRows];
00038
00039 int * first = new int[numberRows];
00040 CoinZeroN(first,numberRows);
00041 CoinZeroN(down,numberRows);
00042 double * sum = new double [numberRows];
00043 CoinZeroN(sum,numberRows);
00044 int numberTightened=0;
00045
00046 for (int iColumn=0;iColumn<numberColumns;iColumn++) {
00047 CoinBigIndex start = columnStart[iColumn];
00048 CoinBigIndex end = start + columnLength[iColumn];
00049 double lower = columnLower[iColumn];
00050 double upper = columnUpper[iColumn];
00051 if (lower==upper) {
00052 for (CoinBigIndex j=start;j<end;j++) {
00053 int iRow = row[j];
00054 double value = element[j];
00055 down[iRow] += value*lower;
00056 sum[iRow] += fabs(value*lower);
00057 }
00058 } else {
00059 for (CoinBigIndex j=start;j<end;j++) {
00060 int iRow = row[j];
00061 int n=first[iRow];
00062 if (n==0&&element[j])
00063 first[iRow]=-iColumn-1;
00064 else if (n<0)
00065 first[iRow]=2;
00066 }
00067 }
00068 }
00069
00070 double tolerance = 1.0e-6;
00071
00072 const char * integerInformation = modelPtr_ -> integerInformation ();
00073
00074 for (int iRow=0;iRow<numberRows;iRow++) {
00075
00076 int iColumn = first[iRow];
00077
00078 if (iColumn<0) {
00079
00080 iColumn = -iColumn-1;
00081
00082 double lowerRow = rowLower[iRow];
00083 if (lowerRow>-1.0e20)
00084 lowerRow -= down[iRow];
00085 double upperRow = rowUpper[iRow];
00086 if (upperRow<1.0e20)
00087 upperRow -= down[iRow];
00088 double lower = columnLower[iColumn];
00089 double upper = columnUpper[iColumn];
00090 double value=0.0;
00091 for (CoinBigIndex j = columnStart[iColumn];
00092 j<columnStart[iColumn]+columnLength[iColumn];j++) {
00093 if (iRow==row[j]) {
00094 value=element[j];
00095 break;
00096 }
00097 }
00098
00099 assert (value);
00100
00101
00102
00103 double
00104 newLower = -COIN_DBL_MAX,
00105 newUpper = COIN_DBL_MAX;
00106
00107 if (value > 0.0) {
00108 if (lowerRow > -1.0e20) newLower = lowerRow / value;
00109 if (upperRow < 1.0e20) newUpper = upperRow / value;
00110 } else {
00111 if (upperRow < 1.0e20) newLower = upperRow / value;
00112 if (lowerRow > -1.0e20) newUpper = lowerRow / value;
00113 }
00114
00115 double tolerance2 = 1.0e-6 + 1.0e-8 * sum [iRow];
00116
00117 if (integerInformation && integerInformation[iColumn]) {
00118
00119 newLower = (newLower-floor(newLower)<tolerance2) ?
00120 floor (newLower) :
00121 ceil (newLower);
00122
00123 newUpper = (ceil(newUpper)-newUpper<tolerance2) ?
00124 ceil (newUpper) :
00125 floor (newUpper);
00126 }
00127
00128 if (newLower>lower+10.0*tolerance2||
00129 newUpper<upper-10.0*tolerance2) {
00130 numberTightened++;
00131 newLower = CoinMax(lower,newLower);
00132 newUpper = CoinMin(upper,newUpper);
00133 if (newLower>newUpper+tolerance) {
00134
00135 numberTightened=-1;
00136 break;
00137 }
00138 setColLower(iColumn,newLower);
00139 setColUpper(iColumn,CoinMax(newLower,newUpper));
00140 }
00141 }
00142 }
00143
00144 delete [] first;
00145 delete [] down;
00146 delete [] sum;
00147 return numberTightened;
00148 }