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 OsiCuts_H 00006 #define OsiCuts_H 00007 00008 #include "CoinPragma.hpp" 00009 00010 #include <cmath> 00011 #include <cfloat> 00012 #include "OsiCollections.hpp" 00013 #include "OsiRowCut.hpp" 00014 #include "OsiColCut.hpp" 00015 #include "CoinFloatEqual.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 typedef std::bidirectional_iterator_tag iterator_category; 00078 typedef OsiCut* value_type; 00079 typedef size_t difference_type; 00080 typedef OsiCut ** pointer; 00081 typedef OsiCut *& reference; 00082 00083 public: 00084 const_iterator(const OsiCuts& cuts); 00085 const_iterator(const const_iterator & src); 00086 const_iterator & operator=( const const_iterator& rhs); 00087 ~const_iterator (); 00088 const OsiCut* operator*() const { return cutP_; } 00089 00090 const_iterator operator++(); 00091 00092 const_iterator operator++(int) 00093 { 00094 const_iterator temp = *this; 00095 ++*this; 00096 return temp; 00097 } 00098 00099 bool operator==(const const_iterator& it) const { 00100 return (colCutIndex_+rowCutIndex_)==(it.colCutIndex_+it.rowCutIndex_); 00101 } 00102 00103 bool operator!=(const const_iterator& it) const { 00104 return !((*this)==it); 00105 } 00106 00107 bool operator<(const const_iterator& it) const { 00108 return (colCutIndex_+rowCutIndex_)<(it.colCutIndex_+it.rowCutIndex_); 00109 } 00110 private: 00111 inline const_iterator(); 00112 // *THINK* : how to inline these without sticking the code here (ugly...) 00113 const_iterator begin(); 00114 const_iterator end(); 00115 const OsiCuts * cutsPtr_; 00116 int rowCutIndex_; 00117 int colCutIndex_; 00118 const OsiCut * cutP_; 00119 }; 00121 00122 //------------------------------------------------------------------- 00123 // 00124 // Cuts class definition begins here: 00125 // 00126 //------------------------------------------------------------------- 00127 00131 inline void insert( const OsiRowCut & rc ); 00134 void insertIfNotDuplicate( OsiRowCut & rc , CoinAbsFltEq treatAsSame=CoinAbsFltEq(1.0e-12) ); 00137 void insertIfNotDuplicate( OsiRowCut & rc , CoinRelFltEq treatAsSame ); 00139 inline void insert( const OsiColCut & cc ); 00140 00146 inline void insert( OsiRowCut * & rcPtr ); 00152 inline void insert( OsiColCut * & ccPtr ); 00153 #if 0 00154 inline void insert( OsiCut * & cPtr ); 00155 #endif 00156 00158 inline void insert(const OsiCuts & cs); 00159 00161 00164 00165 inline int sizeRowCuts() const; 00167 inline int sizeColCuts() const; 00169 inline int sizeCuts() const; 00171 00174 00175 inline void printCuts() const; 00177 00180 00181 inline OsiRowCut * rowCutPtr(int i); 00183 inline const OsiRowCut * rowCutPtr(int i) const; 00185 inline OsiColCut * colCutPtr(int i); 00187 inline const OsiColCut * colCutPtr(int i) const; 00188 00190 inline OsiRowCut & rowCut(int i); 00192 inline const OsiRowCut & rowCut(int i) const; 00194 inline OsiColCut & colCut(int i); 00196 inline const OsiColCut & colCut(int i) const; 00197 00199 inline const OsiCut * mostEffectiveCutPtr() const; 00201 inline OsiCut * mostEffectiveCutPtr(); 00203 00206 00207 inline void eraseRowCut(int i); 00209 inline void eraseColCut(int i); 00211 inline OsiRowCut * rowCutPtrAndZap(int i); 00218 inline void dumpCuts() ; 00226 inline void eraseAndDumpCuts(const std::vector<int> to_erase) ; 00228 00231 00232 inline void sort(); 00234 00235 00246 00247 inline iterator begin() { iterator it(*this); it.begin(); return it; } 00249 inline const_iterator begin() const { const_iterator it(*this); it.begin(); return it; } 00251 inline iterator end() { iterator it(*this); it.end(); return it; } 00253 inline const_iterator end() const { const_iterator it(*this); it.end(); return it; } 00255 00256 00259 00260 OsiCuts (); 00261 00263 OsiCuts ( const OsiCuts &); 00264 00266 OsiCuts & operator=( const OsiCuts& rhs); 00267 00269 virtual ~OsiCuts (); 00271 00272 private: 00273 //*@name Function operator for sorting cuts by efectiveness */ 00275 class OsiCutCompare 00276 { 00277 public: 00279 inline bool operator()(const OsiCut * c1P,const OsiCut * c2P) 00280 { return c1P->effectiveness() > c2P->effectiveness(); } 00281 }; 00283 00286 00287 void gutsOfCopy( const OsiCuts & source ); 00289 void gutsOfDestructor(); 00291 00294 00295 OsiVectorRowCutPtr rowCutPtrs_; 00297 OsiVectorColCutPtr colCutPtrs_; 00299 00300 }; 00301 00302 00303 //------------------------------------------------------------------- 00304 // insert cuts into collection 00305 //------------------------------------------------------------------- 00306 void OsiCuts::insert( const OsiRowCut & rc ) 00307 { 00308 OsiRowCut * newCutPtr = rc.clone(); 00309 //assert(dynamic_cast<OsiRowCut*>(newCutPtr) != NULL ); 00310 rowCutPtrs_.push_back(static_cast<OsiRowCut*>(newCutPtr)); 00311 } 00312 void OsiCuts::insert( const OsiColCut & cc ) 00313 { 00314 OsiColCut * newCutPtr = cc.clone(); 00315 //assert(dynamic_cast<OsiColCut*>(newCutPtr) != NULL ); 00316 colCutPtrs_.push_back(static_cast<OsiColCut*>(newCutPtr)); 00317 } 00318 00319 void OsiCuts::insert( OsiRowCut* & rcPtr ) 00320 { 00321 rowCutPtrs_.push_back(rcPtr); 00322 rcPtr = NULL; 00323 } 00324 void OsiCuts::insert( OsiColCut* &ccPtr ) 00325 { 00326 colCutPtrs_.push_back(ccPtr); 00327 ccPtr = NULL; 00328 } 00329 #if 0 00330 void OsiCuts::insert( OsiCut* & cPtr ) 00331 { 00332 OsiRowCut * rcPtr = dynamic_cast<OsiRowCut*>(cPtr); 00333 if ( rcPtr != NULL ) { 00334 insert( rcPtr ); 00335 cPtr = rcPtr; 00336 } 00337 else { 00338 OsiColCut * ccPtr = dynamic_cast<OsiColCut*>(cPtr); 00339 assert( ccPtr != NULL ); 00340 insert( ccPtr ); 00341 cPtr = ccPtr; 00342 } 00343 } 00344 #endif 00345 00346 // LANNEZ SEBASTIEN added Thu May 25 01:22:51 EDT 2006 00347 void OsiCuts::insert(const OsiCuts & cs) 00348 { 00349 for (OsiCuts::const_iterator it = cs.begin (); it != cs.end (); it++) 00350 { 00351 const OsiRowCut * rCut = dynamic_cast <const OsiRowCut * >(*it); 00352 const OsiColCut * cCut = dynamic_cast <const OsiColCut * >(*it); 00353 assert (rCut || cCut); 00354 if (rCut) 00355 insert (*rCut); 00356 else 00357 insert (*cCut); 00358 } 00359 } 00360 00361 //------------------------------------------------------------------- 00362 // sort 00363 //------------------------------------------------------------------- 00364 void OsiCuts::sort() 00365 { 00366 std::sort(colCutPtrs_.begin(),colCutPtrs_.end(),OsiCutCompare()); 00367 std::sort(rowCutPtrs_.begin(),rowCutPtrs_.end(),OsiCutCompare()); 00368 } 00369 00370 00371 //------------------------------------------------------------------- 00372 // Get number of in collections 00373 //------------------------------------------------------------------- 00374 int OsiCuts::sizeRowCuts() const { 00375 return static_cast<int>(rowCutPtrs_.size()); } 00376 int OsiCuts::sizeColCuts() const { 00377 return static_cast<int>(colCutPtrs_.size()); } 00378 int OsiCuts::sizeCuts() const { 00379 return static_cast<int>(sizeRowCuts()+sizeColCuts()); } 00380 00381 //---------------------------------------------------------------- 00382 // Get i'th cut from the collection 00383 //---------------------------------------------------------------- 00384 const OsiRowCut * OsiCuts::rowCutPtr(int i) const { return rowCutPtrs_[i]; } 00385 const OsiColCut * OsiCuts::colCutPtr(int i) const { return colCutPtrs_[i]; } 00386 OsiRowCut * OsiCuts::rowCutPtr(int i) { return rowCutPtrs_[i]; } 00387 OsiColCut * OsiCuts::colCutPtr(int i) { return colCutPtrs_[i]; } 00388 00389 const OsiRowCut & OsiCuts::rowCut(int i) const { return *rowCutPtr(i); } 00390 const OsiColCut & OsiCuts::colCut(int i) const { return *colCutPtr(i); } 00391 OsiRowCut & OsiCuts::rowCut(int i) { return *rowCutPtr(i); } 00392 OsiColCut & OsiCuts::colCut(int i) { return *colCutPtr(i); } 00393 00394 //---------------------------------------------------------------- 00395 // Get most effective cut from collection 00396 //---------------------------------------------------------------- 00397 const OsiCut * OsiCuts::mostEffectiveCutPtr() const 00398 { 00399 const_iterator b=begin(); 00400 const_iterator e=end(); 00401 return *(std::min_element(b,e,OsiCutCompare())); 00402 } 00403 OsiCut * OsiCuts::mostEffectiveCutPtr() 00404 { 00405 iterator b=begin(); 00406 iterator e=end(); 00407 //return *(std::min_element(b,e,OsiCutCompare())); 00408 OsiCut * retVal = NULL; 00409 double maxEff = COIN_DBL_MIN; 00410 for ( OsiCuts::iterator it=b; it!=e; ++it ) { 00411 if (maxEff < (*it)->effectiveness() ) { 00412 maxEff = (*it)->effectiveness(); 00413 retVal = *it; 00414 } 00415 } 00416 return retVal; 00417 } 00418 00419 //---------------------------------------------------------------- 00420 // Print all cuts 00421 //---------------------------------------------------------------- 00422 void 00423 OsiCuts::printCuts() const 00424 { 00425 // do all column cuts first 00426 int i; 00427 int numberColCuts=sizeColCuts(); 00428 for (i=0;i<numberColCuts;i++) { 00429 const OsiColCut * cut = colCutPtr(i); 00430 cut->print(); 00431 } 00432 int numberRowCuts=sizeRowCuts(); 00433 for (i=0;i<numberRowCuts;i++) { 00434 const OsiRowCut * cut = rowCutPtr(i); 00435 cut->print(); 00436 } 00437 } 00438 00439 //---------------------------------------------------------------- 00440 // Erase i'th cut from the collection 00441 //---------------------------------------------------------------- 00442 void OsiCuts::eraseRowCut(int i) 00443 { 00444 delete rowCutPtrs_[i]; 00445 rowCutPtrs_.erase( rowCutPtrs_.begin()+i ); 00446 } 00447 void OsiCuts::eraseColCut(int i) 00448 { 00449 delete colCutPtrs_[i]; 00450 colCutPtrs_.erase( colCutPtrs_.begin()+i ); 00451 } 00453 OsiRowCut * 00454 OsiCuts::rowCutPtrAndZap(int i) 00455 { 00456 OsiRowCut * cut = rowCutPtrs_[i]; 00457 rowCutPtrs_[i]=NULL; 00458 rowCutPtrs_.erase( rowCutPtrs_.begin()+i ); 00459 return cut; 00460 } 00461 void OsiCuts::dumpCuts() 00462 { 00463 rowCutPtrs_.clear() ; 00464 } 00465 void OsiCuts::eraseAndDumpCuts(const std::vector<int> to_erase) 00466 { 00467 for (unsigned i=0; i<to_erase.size(); i++) { 00468 delete rowCutPtrs_[to_erase[i]]; 00469 } 00470 rowCutPtrs_.clear(); 00471 } 00472 00473 00474 #endif