Osi trunk
|
00001 // Copyright (C) 2000, International Business Machines 00002 // Corporation and others. All Rights Reserved. 00003 // This code is licensed under the terms of the Eclipse Public License (EPL). 00004 00005 #ifndef OsiColCut_H 00006 #define OsiColCut_H 00007 00008 #include <string> 00009 00010 #include "CoinPackedVector.hpp" 00011 00012 #include "OsiCollections.hpp" 00013 #include "OsiCut.hpp" 00014 00023 class OsiColCut : public OsiCut { 00024 friend void OsiColCutUnitTest(const OsiSolverInterface * baseSiP, 00025 const std::string & mpsDir); 00026 00027 public: 00028 00029 //---------------------------------------------------------------- 00030 00033 00034 inline void setLbs( 00035 int nElements, 00036 const int * colIndices, 00037 const double * lbElements ); 00038 00040 inline void setLbs( const CoinPackedVector & lbs ); 00041 00043 inline void setUbs( 00044 int nElements, 00045 const int * colIndices, 00046 const double * ubElements ); 00047 00049 inline void setUbs( const CoinPackedVector & ubs ); 00051 00052 //---------------------------------------------------------------- 00053 00056 00057 inline const CoinPackedVector & lbs() const; 00059 inline const CoinPackedVector & ubs() const; 00061 00064 #if __GNUC__ != 2 00065 using OsiCut::operator== ; 00066 #endif 00067 00070 inline virtual bool operator==(const OsiColCut& rhs) const; 00071 00072 #if __GNUC__ != 2 00073 using OsiCut::operator!= ; 00074 #endif 00075 00076 inline virtual bool operator!=(const OsiColCut& rhs) const; 00078 00079 00080 //---------------------------------------------------------------- 00081 00091 inline virtual bool consistent() const; 00092 00100 inline virtual bool consistent(const OsiSolverInterface& im) const; 00101 00110 inline virtual bool infeasible(const OsiSolverInterface &im) const; 00115 virtual double violated(const double * solution) const; 00117 00118 //---------------------------------------------------------------- 00119 00122 00123 OsiColCut & operator=( const OsiColCut& rhs); 00124 00126 OsiColCut ( const OsiColCut &); 00127 00129 OsiColCut (); 00130 00132 virtual OsiColCut * clone() const; 00133 00135 virtual ~OsiColCut (); 00137 00140 00141 virtual void print() const; 00143 00144 private: 00145 00148 00149 CoinPackedVector lbs_; 00151 CoinPackedVector ubs_; 00153 00154 }; 00155 00156 00157 00158 //------------------------------------------------------------------- 00159 // Set lower & upper bound vectors 00160 //------------------------------------------------------------------- 00161 void OsiColCut::setLbs( 00162 int size, 00163 const int * colIndices, 00164 const double * lbElements ) 00165 { 00166 lbs_.setVector(size,colIndices,lbElements); 00167 } 00168 // 00169 void OsiColCut::setUbs( 00170 int size, 00171 const int * colIndices, 00172 const double * ubElements ) 00173 { 00174 ubs_.setVector(size,colIndices,ubElements); 00175 } 00176 // 00177 void OsiColCut::setLbs( const CoinPackedVector & lbs ) 00178 { 00179 lbs_ = lbs; 00180 } 00181 // 00182 void OsiColCut::setUbs( const CoinPackedVector & ubs ) 00183 { 00184 ubs_ = ubs; 00185 } 00186 00187 //------------------------------------------------------------------- 00188 // Get Column Lower Bounds and Column Upper Bounds 00189 //------------------------------------------------------------------- 00190 const CoinPackedVector & OsiColCut::lbs() const 00191 { 00192 return lbs_; 00193 } 00194 // 00195 const CoinPackedVector & OsiColCut::ubs() const 00196 { 00197 return ubs_; 00198 } 00199 00200 //---------------------------------------------------------------- 00201 // == operator 00202 //------------------------------------------------------------------- 00203 bool 00204 OsiColCut::operator==( 00205 const OsiColCut& rhs) const 00206 { 00207 if ( this->OsiCut::operator!=(rhs) ) 00208 return false; 00209 if ( lbs() != rhs.lbs() ) 00210 return false; 00211 if ( ubs() != rhs.ubs() ) 00212 return false; 00213 return true; 00214 } 00215 // 00216 bool 00217 OsiColCut::operator!=( 00218 const OsiColCut& rhs) const 00219 { 00220 return !( (*this)==rhs ); 00221 } 00222 00223 //---------------------------------------------------------------- 00224 // consistent & infeasible 00225 //------------------------------------------------------------------- 00226 bool OsiColCut::consistent() const 00227 { 00228 const CoinPackedVector & lb = lbs(); 00229 const CoinPackedVector & ub = ubs(); 00230 // Test for consistent cut. 00231 // Are packed vectors consistent? 00232 lb.duplicateIndex("consistent", "OsiColCut"); 00233 ub.duplicateIndex("consistent", "OsiColCut"); 00234 if ( lb.getMinIndex() < 0 ) return false; 00235 if ( ub.getMinIndex() < 0 ) return false; 00236 return true; 00237 } 00238 // 00239 bool OsiColCut::consistent(const OsiSolverInterface& im) const 00240 { 00241 const CoinPackedVector & lb = lbs(); 00242 const CoinPackedVector & ub = ubs(); 00243 00244 // Test for consistent cut. 00245 if ( lb.getMaxIndex() >= im.getNumCols() ) return false; 00246 if ( ub.getMaxIndex() >= im.getNumCols() ) return false; 00247 00248 return true; 00249 } 00250 00251 #if 0 00252 bool OsiColCut::feasible(const OsiSolverInterface &im) const 00253 { 00254 const double * oldColLb = im.getColLower(); 00255 const double * oldColUb = im.getColUpper(); 00256 const CoinPackedVector & cutLbs = lbs(); 00257 const CoinPackedVector & cutUbs = ubs(); 00258 int i; 00259 00260 for ( i=0; i<cutLbs.size(); i++ ) { 00261 int colIndx = cutLbs.indices()[i]; 00262 double newLb; 00263 if ( cutLbs.elements()[i] > oldColLb[colIndx] ) 00264 newLb = cutLbs.elements()[i]; 00265 else 00266 newLb = oldColLb[colIndx]; 00267 00268 double newUb = oldColUb[colIndx]; 00269 if ( cutUbs.indexExists(colIndx) ) 00270 if ( cutUbs[colIndx] < newUb ) newUb = cutUbs[colIndx]; 00271 if ( newLb > newUb ) 00272 return false; 00273 } 00274 00275 for ( i=0; i<cutUbs.size(); i++ ) { 00276 int colIndx = cutUbs.indices()[i]; 00277 double newUb = cutUbs.elements()[i] < oldColUb[colIndx] ? cutUbs.elements()[i] : oldColUb[colIndx]; 00278 double newLb = oldColLb[colIndx]; 00279 if ( cutLbs.indexExists(colIndx) ) 00280 if ( cutLbs[colIndx] > newLb ) newLb = cutLbs[colIndx]; 00281 if ( newUb < newLb ) 00282 return false; 00283 } 00284 00285 return true; 00286 } 00287 #endif 00288 00289 00290 bool OsiColCut::infeasible(const OsiSolverInterface &im) const 00291 { 00292 const double * oldColLb = im.getColLower(); 00293 const double * oldColUb = im.getColUpper(); 00294 const CoinPackedVector & cutLbs = lbs(); 00295 const CoinPackedVector & cutUbs = ubs(); 00296 int i; 00297 00298 for ( i=0; i<cutLbs.getNumElements(); i++ ) { 00299 int colIndx = cutLbs.getIndices()[i]; 00300 double newLb= cutLbs.getElements()[i] > oldColLb[colIndx] ? 00301 cutLbs.getElements()[i] : oldColLb[colIndx]; 00302 00303 double newUb = oldColUb[colIndx]; 00304 if ( cutUbs.isExistingIndex(colIndx) ) 00305 if ( cutUbs[colIndx] < newUb ) newUb = cutUbs[colIndx]; 00306 if ( newLb > newUb ) 00307 return true; 00308 } 00309 00310 for ( i=0; i<cutUbs.getNumElements(); i++ ) { 00311 int colIndx = cutUbs.getIndices()[i]; 00312 double newUb = cutUbs.getElements()[i] < oldColUb[colIndx] ? 00313 cutUbs.getElements()[i] : oldColUb[colIndx]; 00314 double newLb = oldColLb[colIndx]; 00315 if ( cutLbs.isExistingIndex(colIndx) ) 00316 if ( cutLbs[colIndx] > newLb ) newLb = cutLbs[colIndx]; 00317 if ( newUb < newLb ) 00318 return true; 00319 } 00320 00321 return false; 00322 } 00323 00324 //############################################################################# 00330 void 00331 OsiColCutUnitTest(const OsiSolverInterface * baseSiP, 00332 const std::string & mpsDir); 00333 00334 #endif