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

Go to the documentation of this file.
00001 /* $Id: CouenneLPtightenBoundsCLP-light.cpp 490 2011-01-14 16:07:12Z pbelotti $
00002  *
00003  * Name:    CouenneLPtightenBoundsCLP-light.cpp
00004  * Authors: Pietro Belotti, Carnegie Mellon University
00005  * Purpose: adaptation of OsiClpSolverInterface::tightenBounds() -- light version
00006  *
00007  * (C) Carnegie-Mellon University, 2009.
00008  * This file is licensed under the Eclipse Public License (EPL)
00009  */
00010 
00011 #include "CouennePrecisions.hpp"
00012 #include "CouenneProblem.hpp"
00013 #include "CouenneCutGenerator.hpp"
00014 #include "CouenneExprVar.hpp"
00015 
00016 namespace Couenne {
00017 
00018 // Tighten bounds - lightweight. Returns -1 if infeasible, otherwise
00019 // number of variables tightened.
00020 template <class T>
00021 int CouenneSolverInterface<T>::tightenBoundsCLP_Light (int lightweight) {
00022 
00023   // Copied from OsiClpSolverInterface::tightenBounds
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   // Column copy of matrix
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   //const double *objective = T::getObjCoefficients() ;
00040 
00041   //double direction = T::getObjSense();
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       // convert rowLower and Upper to implied bounds on column
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           //printf("XXYY inf on bound\n");
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 }

Generated on Thu Nov 10 03:05:45 2011 by  doxygen 1.4.7