- Main Page
- Namespaces
- Classes
- Files
- Directories

- Search for |

- File List
- File Members

# 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