EvolvingObjects
|
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