EvolvingObjects
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 Authors: 
00022     todos@geneura.ugr.es, http://geneura.ugr.es
00023     jmerelo
00024     gustavoromero
00025     mac
00026     maartenkeijzer
00027     kuepper
00028     okoenig
00029     evomarc
00030     Johann Dréo <johann.dreo@thalesgroup.com>
00031 */
00032 //-----------------------------------------------------------------------------
00033 
00034 #ifndef _EOPOP_H_
00035 #define _EOPOP_H_
00036 
00037 #include <algorithm>
00038 #include <iostream>
00039 #include <iterator> // needed for GCC 3.2
00040 #include <vector>
00041 #include <assert.h>
00042 
00043 // EO includes
00044 #include <eoOp.h> // for eoInit
00045 #include <eoPersistent.h>
00046 #include <eoInit.h>
00047 #include <utils/rnd_generators.h>  // for shuffle method
00048 
00064 template<class EOT>
00065 class eoPop: public std::vector<EOT>, public eoObject, public eoPersistent
00066 {
00067     public:
00068 
00069         using std::vector<EOT>::size;
00070         using std::vector<EOT>::resize;
00071         using std::vector<EOT>::operator[];
00072         using std::vector<EOT>::begin;
00073         using std::vector<EOT>::end;
00074 
00075         typedef typename EOT::Fitness Fitness;
00076 #if defined(__CUDACC__)
00077         typedef typename std::vector<EOT>::iterator iterator;
00078         typedef typename std::vector<EOT>::const_iterator const_iterator;
00079 #endif
00080 
00083         eoPop()   : std::vector<EOT>(), eoObject(), eoPersistent() {};
00084 
00090         eoPop( unsigned _popSize, eoInit<EOT>& _chromInit )
00091             : std::vector<EOT>()
00092         {
00093             resize(_popSize);
00094             for ( unsigned i = 0; i < _popSize; i++ )
00095             {
00096                 _chromInit(operator[](i));
00097             }
00098         }
00099 
00106         void append( unsigned _newPopSize, eoInit<EOT>& _chromInit )
00107         {
00108             unsigned oldSize = size();
00109             if (_newPopSize < oldSize)
00110             {
00111                 throw std::runtime_error("New size smaller than old size in pop.append");
00112                 return;
00113             }
00114             if (_newPopSize == oldSize)
00115                 return;
00116             resize(_newPopSize);         // adjust the size
00117             for ( unsigned i = oldSize; i < _newPopSize; i++ )
00118             {
00119                 _chromInit(operator[](i));
00120             }
00121         }
00122 
00123 
00128         eoPop( std::istream& _is ) :std::vector<EOT>() 
00129         {
00130             readFrom( _is );
00131         }
00132 
00133 
00135         virtual ~eoPop() {}
00136 
00137 
00139         struct Ref { const EOT* operator()(const EOT& eot) { return &eot;}};
00140 
00142         struct Cmp {
00143             bool operator()(const EOT* a, const EOT* b) const
00144             { return b->operator<(*a); }
00145         };
00146 
00148         struct Cmp2
00149         {
00150             bool operator()(const EOT & a,const EOT & b) const
00151             {
00152                 return b.operator<(a);
00153             }
00154         };
00155 
00156 
00161         void sort(void)
00162         {
00163             std::sort(begin(), end(), Cmp2());
00164         }
00165 
00166 
00168         void sort(std::vector<const EOT*>& result) const
00169         {
00170             result.resize(size());
00171 
00172             std::transform(begin(), end(), result.begin(), Ref());
00173 
00174             std::sort(result.begin(), result.end(), Cmp());
00175         }
00176 
00177 
00182         void shuffle(void)
00183         {
00184             UF_random_generator<unsigned int> gen;
00185             std::random_shuffle(begin(), end(), gen);
00186         }
00187 
00188 
00190         void shuffle(std::vector<const EOT*>& result) const
00191         {
00192             result.resize(size());
00193 
00194             std::transform(begin(), end(), result.begin(), Ref());
00195 
00196             UF_random_generator<unsigned int> gen;
00197             std::random_shuffle(result.begin(), result.end(), gen);
00198         }
00199 
00200 
00202 #if defined(__CUDACC__)
00203         eoPop<EOT>::iterator it_best_element()
00204         {
00205             eoPop<EOT>:: iterator it = std::max_element(begin(), end());
00206 #else
00207         typename eoPop<EOT>::iterator it_best_element()
00208         {
00209                 assert( this->size() > 0 );
00210                 typename eoPop<EOT>::iterator it = std::max_element(begin(), end());
00211 #endif
00212                 return it;
00213         }
00214 
00215 
00217         const EOT & best_element() const
00218         {
00219 #if defined(__CUDACC__)
00220             eoPop<EOT>::const_iterator it = std::max_element(begin(), end());
00221 #else
00222             typename eoPop<EOT>::const_iterator it = std::max_element(begin(), end());
00223 #endif
00224             return (*it);
00225         }
00226 
00227 
00229         const EOT & worse_element() const
00230         {
00231 #if defined(__CUDACC__)
00232             eoPop<EOT>::const_iterator it = std::min_element(begin(), end());
00233 #else
00234             assert( this->size() > 0 );
00235             typename eoPop<EOT>::const_iterator it = std::min_element(begin(), end());
00236 #endif
00237             return (*it);
00238         }
00239 
00240 
00242 #if defined(__CUDACC__)
00243         eoPop<EOT>::iterator it_worse_element()
00244         {
00245             eoPop<EOT>::iterator it = std::min_element(begin(), end());
00246 #else
00247         typename eoPop<EOT>::iterator it_worse_element()
00248         {
00249             assert( this->size() > 0 );
00250             typename eoPop<EOT>::iterator it = std::min_element(begin(), end());
00251 #endif
00252             return it;
00253         }
00254 
00255 
00260 #if defined(__CUDACC__)
00261         eoPop<EOT>::iterator nth_element(int nth)
00262         {
00263             eoPop<EOT>::iterator it = begin() + nth;
00264 #else
00265         typename eoPop<EOT>::iterator nth_element(int nth)
00266         {
00267             assert( this->size() > 0 );
00268             typename eoPop<EOT>::iterator it = begin() + nth;
00269 #endif
00270             std::nth_element(begin(), it, end(), std::greater<EOT>());
00271             return it;
00272         }
00273 
00274 
00275         struct GetFitness { Fitness operator()(const EOT& _eo) const { return _eo.fitness(); } };
00276 
00277 
00279         Fitness nth_element_fitness(int which) const
00280         { // probably not the fastest way to do this, but what the heck
00281 
00282             std::vector<Fitness> fitness(size());
00283             std::transform(begin(), end(), fitness.begin(), GetFitness());
00284 
00285             typename std::vector<Fitness>::iterator it = fitness.begin() + which;
00286             std::nth_element(fitness.begin(), it, fitness.end(), std::greater<Fitness>());
00287             return *it;
00288         }
00289 
00290 
00294         void nth_element(int which, std::vector<const EOT*>& result) const
00295         {
00296 
00297             assert( this->size() > 0 );
00298             result.resize(size());
00299             std::transform(begin(), end(), result.begin(), Ref());
00300 
00301             typename std::vector<const EOT*>::iterator it  = result.begin() + which;
00302 
00303             std::nth_element(result.begin(), it, result.end(), Cmp());
00304         }
00305 
00306 
00308         void swap(eoPop<EOT>& other)
00309         {
00310             std::swap(static_cast<std::vector<EOT>& >(*this), static_cast<std::vector<EOT>& >(other));
00311         }
00312 
00313 
00319         virtual void sortedPrintOn(std::ostream& _os) const
00320         {
00321             std::vector<const EOT*> result;
00322             sort(result);
00323             _os << size() << '\n';
00324             for (unsigned i = 0; i < size(); ++i)
00325             {
00326                 _os << *result[i] << std::endl;
00327             }
00328         }
00329 
00330 
00335         virtual void printOn(std::ostream& _os) const
00336         {
00337             _os << size() << '\n';
00338             std::copy( begin(), end(), std::ostream_iterator<EOT>( _os, "\n") );
00339         }
00340 
00341 
00348         virtual void readFrom(std::istream& _is)
00349         {
00350             size_t sz;
00351             _is >> sz;
00352 
00353             resize(sz);
00354 
00355             for (size_t i = 0; i < sz; ++i) {
00356                 operator[](i).readFrom( _is );
00357             }
00358         }
00359 
00360 
00364         virtual std::string className() const {return "eoPop";};
00366 
00367 
00370         virtual void invalidate()
00371         {
00372             for (unsigned i=0; i<size(); i++)
00373                 this->operator[](i).invalidate();
00374         }
00375 
00376 }; // class eoPop
00377 
00378 #endif // _EOPOP_H_
00379 
 All Classes Namespaces Files Functions Variables Typedefs Friends