00001 // Copyright (C) 2000, International Business Machines 00002 // Corporation and others. All Rights Reserved. 00003 #ifndef OsiCuts_H 00004 #define OsiCuts_H 00005 00006 #if defined(_MSC_VER) 00007 // Turn off compiler warning about long names 00008 # pragma warning(disable:4786) 00009 #endif 00010 00011 #include <cmath> 00012 #include <cfloat> 00013 #include "OsiCollections.hpp" 00014 #include "OsiRowCut.hpp" 00015 #include "OsiColCut.hpp" 00016 00019 class OsiCuts { 00020 friend void OsiCutsUnitTest(); 00021 00022 public: 00030 class iterator { 00031 friend class OsiCuts; 00032 public: 00033 iterator(OsiCuts& cuts); 00034 iterator(const iterator & src); 00035 iterator & operator=( const iterator& rhs); 00036 ~iterator (); 00037 OsiCut* operator*() const { return cutP_; } 00038 iterator operator++(); 00039 00040 iterator operator++(int) 00041 { 00042 iterator temp = *this; 00043 ++*this; 00044 return temp; 00045 } 00046 00047 bool operator==(const iterator& it) const { 00048 return (colCutIndex_+rowCutIndex_)==(it.colCutIndex_+it.rowCutIndex_); 00049 } 00050 00051 bool operator!=(const iterator& it) const { 00052 return !((*this)==it); 00053 } 00054 00055 bool operator<(const iterator& it) const { 00056 return (colCutIndex_+rowCutIndex_)<(it.colCutIndex_+it.rowCutIndex_); 00057 } 00058 00059 private: 00060 iterator(); 00061 // *THINK* : how to inline these without sticking the code here (ugly...) 00062 iterator begin(); 00063 iterator end(); 00064 OsiCuts& cuts_; 00065 int rowCutIndex_; 00066 int colCutIndex_; 00067 OsiCut * cutP_; 00068 }; 00069 00074 class const_iterator { 00075 friend class OsiCuts; 00076 public: 00077 const_iterator(const OsiCuts& cuts); 00078 const_iterator(const const_iterator & src); 00079 const_iterator & operator=( const const_iterator& rhs); 00080 ~const_iterator (); 00081 const OsiCut* operator*() const { return cutP_; } 00082 00083 const_iterator operator++(); 00084 00085 const_iterator operator++(int) 00086 { 00087 const_iterator temp = *this; 00088 ++*this; 00089 return temp; 00090 } 00091 00092 bool operator==(const const_iterator& it) const { 00093 return (colCutIndex_+rowCutIndex_)==(it.colCutIndex_+it.rowCutIndex_); 00094 } 00095 00096 bool operator!=(const const_iterator& it) const { 00097 return !((*this)==it); 00098 } 00099 00100 bool operator<(const const_iterator& it) const { 00101 return (colCutIndex_+rowCutIndex_)<(it.colCutIndex_+it.rowCutIndex_); 00102 } 00103 private: 00104 inline const_iterator(); 00105 // *THINK* : how to inline these without sticking the code here (ugly...) 00106 const_iterator begin(); 00107 const_iterator end(); 00108 const OsiCuts * cutsPtr_; 00109 int rowCutIndex_; 00110 int colCutIndex_; 00111 const OsiCut * cutP_; 00112 }; 00114 00115 //------------------------------------------------------------------- 00116 // 00117 // Cuts class definition begins here: 00118 // 00119 //------------------------------------------------------------------- 00120 00123 00124 inline void insert( const OsiRowCut & rc ); 00126 inline void insert( const OsiColCut & cc ); 00127 00134 00135 inline void insert( OsiRowCut * & rcPtr ); 00137 inline void insert( OsiColCut * & ccPtr ); 00138 #if 0 00139 inline void insert( OsiCut * & cPtr ); 00140 #endif 00141 00142 00143 00146 00147 inline int sizeRowCuts() const; 00149 inline int sizeColCuts() const; 00151 inline int sizeCuts() const; 00153 00156 00157 inline void printCuts() const; 00159 00162 00163 inline OsiRowCut * rowCutPtr(int i); 00165 inline const OsiRowCut * rowCutPtr(int i) const; 00167 inline OsiColCut * colCutPtr(int i); 00169 inline const OsiColCut * colCutPtr(int i) const; 00170 00172 inline OsiRowCut & rowCut(int i); 00174 inline const OsiRowCut & rowCut(int i) const; 00176 inline OsiColCut & colCut(int i); 00178 inline const OsiColCut & colCut(int i) const; 00179 00181 inline const OsiCut * mostEffectiveCutPtr() const; 00183 inline OsiCut * mostEffectiveCutPtr(); 00185 00188 00189 inline void eraseRowCut(int i); 00191 inline void eraseColCut(int i); 00193 00196 00197 inline void sort(); 00199 00200 00211 00212 inline iterator begin() { iterator it(*this); it.begin(); return it; } 00214 inline const_iterator begin() const { const_iterator it(*this); it.begin(); return it; } 00216 inline iterator end() { iterator it(*this); it.end(); return it; } 00218 inline const_iterator end() const { const_iterator it(*this); it.end(); return it; } 00220 00221 00224 00225 OsiCuts (); 00226 00228 OsiCuts ( const OsiCuts &); 00229 00231 OsiCuts & operator=( const OsiCuts& rhs); 00232 00234 virtual ~OsiCuts (); 00236 00237 private: 00238 //*@name Function operator for sorting cuts by efectiveness */ 00240 class OsiCutCompare 00241 { 00242 public: 00244 inline bool operator()(const OsiCut * c1P,const OsiCut * c2P) 00245 { return c1P->effectiveness() > c2P->effectiveness(); } 00246 }; 00248 00251 00252 void gutsOfCopy( const OsiCuts & source ); 00254 void gutsOfDestructor(); 00256 00259 00260 OsiVectorRowCutPtr rowCutPtrs_; 00262 OsiVectorColCutPtr colCutPtrs_; 00264 00265 }; 00266 00267 00268 //------------------------------------------------------------------- 00269 // insert cuts into collection 00270 //------------------------------------------------------------------- 00271 void OsiCuts::insert( const OsiRowCut & rc ) 00272 { 00273 OsiRowCut * newCutPtr = rc.clone(); 00274 //assert(dynamic_cast<OsiRowCut*>(newCutPtr) != NULL ); 00275 rowCutPtrs_.push_back(static_cast<OsiRowCut*>(newCutPtr)); 00276 } 00277 void OsiCuts::insert( const OsiColCut & cc ) 00278 { 00279 OsiColCut * newCutPtr = cc.clone(); 00280 //assert(dynamic_cast<OsiColCut*>(newCutPtr) != NULL ); 00281 colCutPtrs_.push_back(static_cast<OsiColCut*>(newCutPtr)); 00282 } 00283 00284 void OsiCuts::insert( OsiRowCut* & rcPtr ) 00285 { 00286 rowCutPtrs_.push_back(rcPtr); 00287 rcPtr = NULL; 00288 } 00289 void OsiCuts::insert( OsiColCut* &ccPtr ) 00290 { 00291 colCutPtrs_.push_back(ccPtr); 00292 ccPtr = NULL; 00293 } 00294 #if 0 00295 void OsiCuts::insert( OsiCut* & cPtr ) 00296 { 00297 OsiRowCut * rcPtr = dynamic_cast<OsiRowCut*>(cPtr); 00298 if ( rcPtr != NULL ) { 00299 insert( rcPtr ); 00300 cPtr = rcPtr; 00301 } 00302 else { 00303 OsiColCut * ccPtr = dynamic_cast<OsiColCut*>(cPtr); 00304 assert( ccPtr != NULL ); 00305 insert( ccPtr ); 00306 cPtr = ccPtr; 00307 } 00308 } 00309 #endif 00310 00311 //------------------------------------------------------------------- 00312 // sort 00313 //------------------------------------------------------------------- 00314 void OsiCuts::sort() 00315 { 00316 std::sort(colCutPtrs_.begin(),colCutPtrs_.end(),OsiCutCompare()); 00317 std::sort(rowCutPtrs_.begin(),rowCutPtrs_.end(),OsiCutCompare()); 00318 } 00319 00320 00321 //------------------------------------------------------------------- 00322 // Get number of in collections 00323 //------------------------------------------------------------------- 00324 int OsiCuts::sizeRowCuts() const { return rowCutPtrs_.size(); } 00325 int OsiCuts::sizeColCuts() const { return colCutPtrs_.size(); } 00326 int OsiCuts::sizeCuts() const { return sizeRowCuts()+sizeColCuts(); } 00327 00328 //---------------------------------------------------------------- 00329 // Get i'th cut from the collection 00330 //---------------------------------------------------------------- 00331 const OsiRowCut * OsiCuts::rowCutPtr(int i) const { return rowCutPtrs_[i]; } 00332 const OsiColCut * OsiCuts::colCutPtr(int i) const { return colCutPtrs_[i]; } 00333 OsiRowCut * OsiCuts::rowCutPtr(int i) { return rowCutPtrs_[i]; } 00334 OsiColCut * OsiCuts::colCutPtr(int i) { return colCutPtrs_[i]; } 00335 00336 const OsiRowCut & OsiCuts::rowCut(int i) const { return *rowCutPtr(i); } 00337 const OsiColCut & OsiCuts::colCut(int i) const { return *colCutPtr(i); } 00338 OsiRowCut & OsiCuts::rowCut(int i) { return *rowCutPtr(i); } 00339 OsiColCut & OsiCuts::colCut(int i) { return *colCutPtr(i); } 00340 00341 //---------------------------------------------------------------- 00342 // Get most effective cut from collection 00343 //---------------------------------------------------------------- 00344 const OsiCut * OsiCuts::mostEffectiveCutPtr() const 00345 { 00346 const_iterator b=begin(); 00347 const_iterator e=end(); 00348 return *(std::min_element(b,e,OsiCutCompare())); 00349 } 00350 OsiCut * OsiCuts::mostEffectiveCutPtr() 00351 { 00352 iterator b=begin(); 00353 iterator e=end(); 00354 //return *(std::min_element(b,e,OsiCutCompare())); 00355 OsiCut * retVal = NULL; 00356 double maxEff = DBL_MIN; 00357 for ( OsiCuts::iterator it=b; it!=e; ++it ) { 00358 if (maxEff < (*it)->effectiveness() ) { 00359 maxEff = (*it)->effectiveness(); 00360 retVal = *it; 00361 } 00362 } 00363 return retVal; 00364 } 00365 00366 //---------------------------------------------------------------- 00367 // Print all cuts 00368 //---------------------------------------------------------------- 00369 void 00370 OsiCuts::printCuts() const 00371 { 00372 // do all column cuts first 00373 int i; 00374 int numberColCuts=sizeColCuts(); 00375 for (i=0;i<numberColCuts;i++) { 00376 const OsiColCut * cut = colCutPtr(i); 00377 cut->print(); 00378 } 00379 int numberRowCuts=sizeRowCuts(); 00380 for (i=0;i<numberRowCuts;i++) { 00381 const OsiRowCut * cut = rowCutPtr(i); 00382 cut->print(); 00383 } 00384 } 00385 00386 //---------------------------------------------------------------- 00387 // Erase i'th cut from the collection 00388 //---------------------------------------------------------------- 00389 void OsiCuts::eraseRowCut(int i) 00390 { 00391 delete rowCutPtrs_[i]; 00392 rowCutPtrs_.erase( rowCutPtrs_.begin()+i ); 00393 } 00394 void OsiCuts::eraseColCut(int i) 00395 { 00396 delete colCutPtrs_[i]; 00397 colCutPtrs_.erase( colCutPtrs_.begin()+i ); 00398 } 00399 00400 //############################################################################# 00406 void 00407 OsiCutsUnitTest(); 00408 00409 #endif