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

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

Generated on Thu Oct 8 03:02:57 2009 by  doxygen 1.4.7