Osi  trunk
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
OsiCuts.hpp
Go to the documentation of this file.
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
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines