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