/home/coin/SVN-release/OS-2.1.0/Couenne/src/problem/CouenneLPtightenBoundsCLP.cpp

Go to the documentation of this file.
00001 /* $Id: CouenneLPtightenBoundsCLP.cpp 215 2009-07-08 15:43:38Z pbelotti $
00002  *
00003  * Name:    CouenneLPtightenBoundsCLP.cpp
00004  * Authors: Pietro Belotti, Carnegie Mellon University
00005  * Purpose: adaptation of OsiClpSolverInterface::tightenBounds()
00006  *
00007  * (C) Carnegie-Mellon University, 2009.
00008  * This file is licensed under the Common Public License (CPL)
00009  */
00010 
00011 #include "CouennePrecisions.hpp"
00012 #include "CouenneProblem.hpp"
00013 #include "CouenneCutGenerator.hpp"
00014 #include "exprVar.hpp"
00015 
00016 //#define COIN_DEVELOP 4
00017 
00018 // Tighten bounds. Returns -1 if infeasible, otherwise number of
00019 // variables tightened.
00020 template <class T> 
00021 int CouenneSolverInterface<T>::tightenBoundsCLP (int lightweight) {
00022 
00023   // Copied from OsiClpSolverInterface::tightenBounds
00024 
00025   int
00026     numberRows    = T::getNumRows(),
00027     numberColumns = T::getNumCols(),
00028     iRow, iColumn;
00029 
00030   const double * columnUpper = T::getColUpper();
00031   const double * columnLower = T::getColLower();
00032   const double * rowUpper = T::getRowUpper();
00033   const double * rowLower = T::getRowLower();
00034 
00035   // Column copy of matrix
00036   const double * element = T::getMatrixByCol()->getElements();
00037   const int * row = T::getMatrixByCol()->getIndices();
00038   const CoinBigIndex * columnStart = T::getMatrixByCol()->getVectorStarts();
00039   const int * columnLength = T::getMatrixByCol()->getVectorLengths();
00040   const double *objective = T::getObjCoefficients() ;
00041 
00042   double direction = T::getObjSense();
00043   double * down = new double [numberRows];
00044 
00045   if (lightweight)
00046     return tightenBoundsCLP_Light (lightweight);
00047 
00048   // NOT LIGHTWEIGHT /////////////////////////////////////////////////////
00049 
00050   double * up = new double [numberRows];
00051   double * sum = new double [numberRows];
00052   int * type = new int [numberRows];
00053   CoinZeroN(down,numberRows);
00054   CoinZeroN(up,numberRows);
00055   CoinZeroN(sum,numberRows);
00056   CoinZeroN(type,numberRows);
00057   double infinity = T::getInfinity();
00058 
00059   for (iColumn=0;iColumn<numberColumns;iColumn++) {
00060     CoinBigIndex start = columnStart[iColumn];
00061     CoinBigIndex end = start + columnLength[iColumn];
00062     double lower = columnLower[iColumn];
00063     double upper = columnUpper[iColumn];
00064     if (lower==upper) {
00065       for (CoinBigIndex j=start;j<end;j++) {
00066         int iRow = row[j];
00067         double value = element[j];
00068         sum[iRow]+=2.0*fabs(value*lower);
00069         if ((type[iRow]&1)==0)
00070           down[iRow] += value*lower;
00071         if ((type[iRow]&2)==0)
00072           up[iRow] += value*lower;
00073       }
00074     } else {
00075       for (CoinBigIndex j=start;j<end;j++) {
00076         int iRow = row[j];
00077         double value = element[j];
00078         if (value>0.0) {
00079           if ((type[iRow]&1)==0) {
00080             if (lower!=-infinity) {
00081               down[iRow] += value*lower;
00082               sum[iRow]+=fabs(value*lower);
00083             } else {
00084               type[iRow] |= 1;
00085             }
00086           }
00087           if ((type[iRow]&2)==0) {
00088             if (upper!=infinity) {
00089               up[iRow] += value*upper;
00090               sum[iRow]+=fabs(value*upper);
00091             } else {
00092               type[iRow] |= 2;
00093             }
00094           }
00095         } else {
00096           if ((type[iRow]&1)==0) {
00097             if (upper!=infinity) {
00098               down[iRow] += value*upper;
00099               sum[iRow]+=fabs(value*upper);
00100             } else {
00101               type[iRow] |= 1;
00102             }
00103           }
00104           if ((type[iRow]&2)==0) {
00105             if (lower!=-infinity) {
00106               up[iRow] += value*lower;
00107               sum[iRow]+=fabs(value*lower);
00108             } else {
00109               type[iRow] |= 2;
00110             }
00111           }
00112         }
00113       }
00114     }
00115   }
00116 
00117   int nTightened = 0;
00118   double tolerance = 1.0e-6;
00119 
00120   for (iRow=0;iRow<numberRows;iRow++) {
00121     if ((type[iRow]&1)!=0)
00122       down[iRow]=-infinity;
00123     if (down[iRow]>rowUpper[iRow]) {
00124       if (down[iRow]>rowUpper[iRow]+tolerance+1.0e-8*sum[iRow]) {
00125         // infeasible
00126 #ifdef COIN_DEVELOP
00127         printf("infeasible on row %d\n",iRow);
00128 #endif
00129         nTightened=-1;
00130         break;
00131       } else {
00132         down[iRow]=rowUpper[iRow];
00133       }
00134     }
00135     if ((type[iRow]&2)!=0)
00136       up[iRow]=infinity;
00137     if (up[iRow]<rowLower[iRow]) {
00138       if (up[iRow]<rowLower[iRow]-tolerance-1.0e-8*sum[iRow]) {
00139         // infeasible
00140 #ifdef COIN_DEVELOP
00141         printf("infeasible on row %d\n",iRow);
00142 #endif
00143         nTightened=-1;
00144         break;
00145       } else {
00146         up[iRow]=rowLower[iRow];
00147       }
00148     }
00149   }
00150 
00151   if (nTightened)
00152     numberColumns = 0; // so will skip
00153 
00154   for (iColumn=0;iColumn<numberColumns;iColumn++) {
00155     double lower = columnLower[iColumn];
00156     double upper = columnUpper[iColumn];
00157     double gap = upper-lower;
00158 
00159     if (!gap)
00160       continue;
00161 
00162     int canGo=0;
00163 
00164     CoinBigIndex
00165       start =         columnStart  [iColumn],
00166       end   = start + columnLength [iColumn];
00167 
00168     if (lower < -1.0e8 && upper > 1.0e8)
00169       continue; // Could do severe damage to accuracy
00170 
00171 
00172     // there was an ifInteger condition here. We do like tightened
00173     // bounds for continuous variables too, so we don't test for
00174     // integrality.
00175 
00176     std::vector <exprVar *> &vars = cutgen_ -> Problem () -> Variables ();
00177 
00178     {
00179       if (vars [iColumn] -> isInteger ()) {
00180 
00181         if (lower < ceil (lower - COUENNE_EPS) - COUENNE_EPS) {
00182 #ifdef COIN_DEVELOP
00183           printf("increasing lower bound on %d from %e to %e\n",iColumn,
00184                  lower,ceil(lower - COUENNE_EPS));
00185 #endif
00186           lower=ceil(lower - COUENNE_EPS);
00187           gap=upper-lower;
00188           T::setColLower(iColumn,lower);
00189         }
00190 
00191         if (upper > floor(upper + COUENNE_EPS) + COUENNE_EPS) {
00192 #ifdef COIN_DEVELOP
00193           printf("decreasing upper bound on %d from %e to %e\n",iColumn,
00194                  upper,floor(upper + COUENNE_EPS));
00195 #endif
00196           upper=floor(upper + COUENNE_EPS);
00197           gap=upper-lower;
00198           T::setColUpper(iColumn,upper);
00199         }
00200       }
00201 
00202       double newLower=lower;
00203       double newUpper=upper;
00204 
00205       for (CoinBigIndex j=start;j<end;j++) {
00206         int iRow = row[j];
00207         double value = element[j];
00208         if (value>0.0) {
00209           if ((type[iRow]&1)==0) {
00210             // has to be at most something
00211             if (down[iRow] + value*gap > rowUpper[iRow]+tolerance) {
00212               double newGap = (rowUpper[iRow]-down[iRow])/value;
00213               // adjust
00214               newGap += 1.0e-10*sum[iRow];
00215               if (vars [iColumn] -> isInteger ())
00216                 newGap = floor(newGap);
00217               if (lower+newGap<newUpper)
00218                 newUpper=lower+newGap;
00219             }
00220           }
00221           if (down[iRow]<rowLower[iRow])
00222             canGo |=1; // can't go down without affecting result
00223           if ((type[iRow]&2)==0) {
00224             // has to be at least something
00225             if (up[iRow] - value*gap < rowLower[iRow]-tolerance) {
00226               double newGap = (up[iRow]-rowLower[iRow])/value;
00227               // adjust
00228               newGap += 1.0e-10*sum[iRow];
00229               if (vars [iColumn] -> isInteger ())
00230                 newGap = floor(newGap);
00231               if (upper-newGap>newLower)
00232                 newLower=upper-newGap;
00233             }
00234           }
00235           if (up[iRow]>rowUpper[iRow])
00236             canGo |=2; // can't go up without affecting result
00237         } else {
00238           if ((type[iRow]&1)==0) {
00239             // has to be at least something
00240             if (down[iRow] - value*gap > rowUpper[iRow]+tolerance) {
00241               double newGap = -(rowUpper[iRow]-down[iRow])/value;
00242               // adjust
00243               newGap += 1.0e-10*sum[iRow];
00244               if (vars [iColumn] -> isInteger ())
00245                 newGap = floor(newGap);
00246               if (upper-newGap>newLower)
00247                 newLower=upper-newGap;
00248             }
00249           }
00250           if (up[iRow]>rowUpper[iRow])
00251             canGo |=1; // can't go down without affecting result
00252           if ((type[iRow]&2)==0) {
00253             // has to be at most something
00254             if (up[iRow] + value*gap < rowLower[iRow]-tolerance) {
00255               double newGap = -(up[iRow]-rowLower[iRow])/value;
00256               // adjust
00257               newGap += 1.0e-10*sum[iRow];
00258               if (vars [iColumn] -> isInteger ())
00259                 newGap = floor(newGap);
00260               if (lower+newGap<newUpper)
00261                 newUpper=lower+newGap;
00262             }
00263           }
00264           if (down[iRow]<rowLower[iRow])
00265             canGo |=2; // can't go up without affecting result
00266         }
00267       }
00268 
00269       if (newUpper<upper || newLower>lower) {
00270         nTightened++;
00271         if (newLower>newUpper) {
00272           // infeasible
00273 #if COIN_DEVELOP>1
00274           printf("infeasible on column %d\n",iColumn);
00275 #endif
00276           nTightened=-1;
00277           break;
00278         } else {
00279           T::setColLower(iColumn,newLower);
00280           T::setColUpper(iColumn,newUpper);
00281         }
00282         for (CoinBigIndex j=start;j<end;j++) {
00283           int iRow = row[j];
00284           double value = element[j];
00285           if (value>0.0) {
00286             if ((type[iRow]&1)==0) down [iRow] += value*(newLower-lower);
00287             if ((type[iRow]&2)==0) up   [iRow] += value*(newUpper-upper);
00288           } else {
00289             if ((type[iRow]&1)==0) down [iRow] += value*(newUpper-upper);
00290             if ((type[iRow]&2)==0) up   [iRow] += value*(newLower-lower);
00291           }
00292         }
00293       } else {
00294 
00295         if (canGo!=3) {
00296 
00297           double objValue = direction*objective[iColumn];
00298 
00299           if (objValue>=0.0&&(canGo&1)==0) {
00300 #if COIN_DEVELOP>2
00301             printf("dual fix down on column %d\n",iColumn);
00302 #endif
00303             nTightened++;
00304             T::setColUpper(iColumn,lower);
00305           } else if (objValue<=0.0 && (canGo&2)==0) {
00306 #if COIN_DEVELOP>2
00307             printf("dual fix up on column %d\n",iColumn);
00308 #endif
00309             nTightened++;
00310             T::setColLower(iColumn,upper);
00311           }
00312         }           
00313       }
00314     }
00315 
00316 //     else {
00317 
00318 //       // CONTINUOUS //////////////////////////////////////////
00319 
00320 //       // just do dual tests
00321 //       for (CoinBigIndex j=start;j<end;j++) {
00322 //      int iRow = row[j];
00323 //      double value = element[j];
00324 //      if (value>0.0) {
00325 //        if (down [iRow] < rowLower [iRow]) canGo |=1; // can't go down without affecting result
00326 //        if (up   [iRow] > rowUpper [iRow]) canGo |=2; // can't go up   without affecting result
00327 //      } else {
00328 //        if (up   [iRow] > rowUpper [iRow]) canGo |=1; // can't go down without affecting result
00329 //        if (down [iRow] < rowLower [iRow]) canGo |=2; // can't go up   without affecting result
00330 //      }
00331 //       }
00332 
00333 //       if (canGo!=3) {
00334 //      double objValue = direction*objective[iColumn];
00335 //      if (objValue>=0.0&&(canGo&1)==0) {
00336 // #if COIN_DEVELOP>2
00337 //        printf("dual fix down on continuous column %d lower %g\n",
00338 //               iColumn,lower);
00339 // #endif
00340 //        // Only if won't cause numerical problems
00341 //        if (lower>-1.0e10) {
00342 //          nTightened++;;
00343 //          setColUpper(iColumn,lower);
00344 //        }
00345 //      } else if (objValue<=0.0&&(canGo&2)==0) {
00346 // #if COIN_DEVELOP>2
00347 //        printf("dual fix up on continuous column %d upper %g\n",
00348 //               iColumn,upper);
00349 // #endif
00350 //        // Only if won't cause numerical problems
00351 //        if (upper<1.0e10) {
00352 //          nTightened++;;
00353 //          setColLower(iColumn,upper);
00354 //        }
00355 //      }
00356 //       }
00357 //     }
00358 
00359   }
00360 
00361   delete [] type;
00362   delete [] down;
00363   delete [] up;
00364   delete [] sum;
00365 
00366   return nTightened;
00367 }
00368   

Generated on Tue Mar 30 03:04:38 2010 by  doxygen 1.4.7