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

Go to the documentation of this file.
00001 /* $Id: CouenneLPtightenBoundsCLP-light.cpp 201 2009-07-07 10:28:24Z 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 Common Public License (CPL)
00009  */
00010 
00011 #include "CouennePrecisions.hpp"
00012 #include "CouenneSolverInterface.hpp"
00013 
00014 #define COIN_DEVELOP 4
00015 
00016 // Tighten bounds - lightweight. Returns -1 if infeasible, otherwise
00017 // number of variables tightened.
00018 int CouenneSolverInterface::tightenBoundsCLP_Light (int lightweight) {
00019 
00020   // Copied from OsiClpSolverInterface::tightenBounds
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   // Column copy of matrix
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       // convert rowLower and Upper to implied bounds on column
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           //printf("XXYY inf on bound\n");
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 }

Generated on Mon Aug 3 03:02:21 2009 by  doxygen 1.4.7