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