eoPop.h

00001 // -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*-
00002 
00003 //-----------------------------------------------------------------------------
00004 // eoPop.h 
00005 // (c) GeNeura Team, 1998
00006 /* 
00007     This library is free software; you can redistribute it and/or
00008     modify it under the terms of the GNU Lesser General Public
00009     License as published by the Free Software Foundation; either
00010     version 2 of the License, or (at your option) any later version.
00011 
00012     This library is distributed in the hope that it will be useful,
00013     but WITHOUT ANY WARRANTY; without even the implied warranty of
00014     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015     Lesser General Public License for more details.
00016 
00017     You should have received a copy of the GNU Lesser General Public
00018     License along with this library; if not, write to the Free Software
00019     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00020 
00021     Contact: todos@geneura.ugr.es, http://geneura.ugr.es
00022  */
00023 //-----------------------------------------------------------------------------
00024 
00025 #ifndef _EOPOP_H
00026 #define _EOPOP_H
00027 
00028 #include <algorithm>
00029 #include <iostream>
00030 #include <iterator> // needed for GCC 3.2
00031 #include <vector>
00032 
00033 // EO includes
00034 #include <eoOp.h> // for eoInit
00035 #include <eoPersistent.h>
00036 #include <eoInit.h>
00037 #include <utils/rnd_generators.h>  // for shuffle method
00038 
00053 template<class EOT>
00054 class eoPop: public std::vector<EOT>, public eoObject, public eoPersistent 
00055 {
00056 
00057  public:
00058      
00059      using std::vector<EOT>::size;
00060      using std::vector<EOT>::resize;
00061      using std::vector<EOT>::operator[];
00062      using std::vector<EOT>::begin;
00063      using std::vector<EOT>::end;
00064      
00065      typedef typename EOT::Fitness Fitness;
00068         eoPop()   : std::vector<EOT>(), eoObject(), eoPersistent() {};
00069         
00075     eoPop( unsigned _popSize, eoInit<EOT>& _chromInit )
00076       :std::vector<EOT>() 
00077     {
00078         resize(_popSize);
00079           for ( unsigned i = 0; i < _popSize; i++ )
00080       {
00081                 _chromInit(operator[](i));
00082           }
00083         };
00084 
00091     void append( unsigned _newPopSize, eoInit<EOT>& _chromInit )
00092     {
00093       unsigned oldSize = size();
00094       if (_newPopSize < oldSize)
00095         {
00096           throw std::runtime_error("New size smaller than old size in pop.append");
00097           return;
00098         }
00099       if (_newPopSize == oldSize)
00100         return;
00101       resize(_newPopSize);         // adjust the size
00102       for ( unsigned i = oldSize; i < _newPopSize; i++ )
00103         {
00104           _chromInit(operator[](i));
00105         }
00106     };
00107   
00108   
00113   eoPop( std::istream& _is ) :std::vector<EOT>() {
00114     readFrom( _is );
00115   }
00116   
00118         virtual ~eoPop() {};
00119 
00120 
00122       struct Ref { const EOT* operator()(const EOT& eot) { return &eot;}};
00124       struct Cmp {
00125           bool operator()(const EOT* a, const EOT* b) const
00126             { return b->operator<(*a); }
00127       };
00128 
00133   void sort(void)
00134   {
00135       std::sort(begin(), end(), std::greater<EOT>());
00136   }
00137 
00139   void sort(std::vector<const EOT*>& result) const
00140   {
00141       result.resize(size());
00142 
00143       std::transform(begin(), end(), result.begin(), Ref());
00144 
00145       std::sort(result.begin(), result.end(), Cmp());
00146   }
00147 
00152   void shuffle(void)
00153   {
00154     UF_random_generator<unsigned int> gen;
00155       std::random_shuffle(begin(), end(), gen);
00156   }
00157 
00159   void shuffle(std::vector<const EOT*>& result) const
00160   {
00161       result.resize(size());
00162 
00163       std::transform(begin(), end(), result.begin(), Ref());
00164 
00165       UF_random_generator<unsigned int> gen;
00166       std::random_shuffle(result.begin(), result.end(), gen);
00167   }
00168 
00170   typename eoPop<EOT>::iterator it_best_element() 
00171   {
00172     typename eoPop<EOT>::iterator it = std::max_element(begin(), end());
00173     return it;
00174   }
00175 
00177   const EOT & best_element() const
00178   {
00179     typename eoPop<EOT>::const_iterator it = std::max_element(begin(), end());
00180     return (*it);
00181   }
00182 
00184   const EOT & worse_element() const
00185   {
00186     typename eoPop<EOT>::const_iterator it = std::min_element(begin(), end());
00187     return (*it);
00188   }
00189 
00191   typename eoPop<EOT>::iterator it_worse_element()
00192   {
00193     typename eoPop<EOT>::iterator it = std::min_element(begin(), end());
00194     return it;
00195   }
00196 
00201   typename eoPop<EOT>::iterator nth_element(int nth)
00202   {
00203       typename eoPop<EOT>::iterator it = begin() + nth;
00204       std::nth_element(begin(), it, end(), std::greater<EOT>());
00205       return it;
00206   }
00207 
00208   struct GetFitness { Fitness operator()(const EOT& _eo) const { return _eo.fitness(); } };
00209   
00211   Fitness nth_element_fitness(int which) const
00212   { // probably not the fastest way to do this, but what the heck
00213       
00214       std::vector<Fitness> fitness(size());
00215       std::transform(begin(), end(), fitness.begin(), GetFitness());
00216 
00217       typename std::vector<Fitness>::iterator it = fitness.begin() + which;
00218       std::nth_element(fitness.begin(), it, fitness.end(), std::greater<Fitness>());
00219       return *it;
00220   }
00221 
00225   void nth_element(int which, std::vector<const EOT*>& result) const
00226   {
00227 
00228       result.resize(size());
00229       std::transform(begin(), end(), result.begin(), Ref());
00230   
00231       typename std::vector<const EOT*>::iterator it  = result.begin() + which;
00232 
00233       std::nth_element(result.begin(), it, result.end(), Cmp());
00234   }
00235 
00237   void swap(eoPop<EOT>& other)
00238   {
00239       std::swap(static_cast<std::vector<EOT>& >(*this), static_cast<std::vector<EOT>& >(other));
00240   }
00241   
00247   virtual void sortedPrintOn(std::ostream& _os) const 
00248   {
00249     std::vector<const EOT*> result;
00250     sort(result);
00251     _os << size() << '\n';
00252     for (unsigned i = 0; i < size(); ++i)
00253       {
00254         _os << *result[i] << std::endl;
00255       }
00256   }
00257 
00262   virtual void printOn(std::ostream& _os) const 
00263   {
00264         _os << size() << '\n';
00265         std::copy( begin(), end(), std::ostream_iterator<EOT>( _os, "\n") );
00266   }
00267 
00274   virtual void readFrom(std::istream& _is) 
00275   {
00276     size_t sz;
00277     _is >> sz;
00278 
00279     resize(sz);
00280 
00281     for (size_t i = 0; i < sz; ++i) {  
00282         operator[](i).readFrom( _is );
00283     }
00284   }
00285 
00289   virtual std::string className() const {return "eoPop";};
00291 
00292   virtual void invalidate()
00293   {
00294     for (unsigned i=0; i<size(); i++)
00295       this->operator[](i).invalidate();
00296   }
00297 
00298 
00299  protected:
00300 
00301 };
00302 
00303 #endif
00304 

Generated on Thu Oct 19 05:06:37 2006 for EO by  doxygen 1.3.9.1