EvolvingObjects
|
00001 00025 //----------------------------------------------------------------------------- 00026 00027 #ifndef _eoSurviveAndDie_h 00028 #define _eoSurviveAndDie_h 00029 00030 00031 //----------------------------------------------------------------------------- 00032 #include <eoPop.h> 00033 #include <eoFunctor.h> 00034 #include <eoMerge.h> 00035 #include <eoReduce.h> 00036 #include <utils/eoHowMany.h> 00037 //----------------------------------------------------------------------------- 00038 00057 template <class EOT> 00058 class eoSurviveAndDie : public eoBF<eoPop<EOT> &, eoPop<EOT> &, void> 00059 { 00060 public: 00061 eoSurviveAndDie(double _survive, double _die, bool _interpret_as_rate = true): 00062 howmanySurvive(_survive, _interpret_as_rate), 00063 howmanyDie(_die, _interpret_as_rate) 00064 {} 00065 00066 protected: 00067 eoHowMany howmanySurvive; 00068 eoHowMany howmanyDie; 00069 00070 }; 00071 00077 template <class EOT> 00078 class eoDeterministicSurviveAndDie : public eoSurviveAndDie<EOT> 00079 { 00080 public: 00081 00082 using eoSurviveAndDie< EOT >::howmanyDie; 00083 using eoSurviveAndDie< EOT >::howmanySurvive; 00084 00086 eoDeterministicSurviveAndDie(double _survive, double _die, bool _interpret_as_rate = true) 00087 : eoSurviveAndDie< EOT >(_survive, _die, _interpret_as_rate) 00088 {} 00089 00090 00091 void operator()(eoPop<EOT> & _pop, eoPop<EOT> & _luckyGuys) 00092 { 00093 unsigned pSize = _pop.size(); 00094 unsigned nbSurvive = howmanySurvive(pSize); 00095 // first, save the best into _luckyGuys 00096 if (nbSurvive) 00097 { 00098 _pop.nth_element(nbSurvive); 00099 // copy best 00100 _luckyGuys.resize(nbSurvive); 00101 std::copy(_pop.begin(), _pop.begin()+nbSurvive, _luckyGuys.begin()); 00102 // erase them from pop 00103 _pop.erase(_pop.begin(), _pop.begin()+nbSurvive); 00104 } 00105 unsigned nbRemaining = _pop.size(); 00106 00107 // carefull, we can have a rate of 1 if we want to kill all remaining 00108 unsigned nbDie = std::min(howmanyDie(pSize), pSize-nbSurvive); 00109 if (nbDie > nbRemaining) 00110 throw std::logic_error("eoDeterministicSurviveAndDie: Too many to kill!\n"); 00111 00112 if (!nbDie) 00113 { 00114 return; 00115 } 00116 // else 00117 // kill the worse nbDie 00118 _pop.nth_element(nbRemaining-nbDie); 00119 _pop.resize(nbRemaining-nbDie); 00120 } 00121 00122 }; 00123 00136 template <class EOT> 00137 class eoDeterministicSaDReplacement : public eoReplacement<EOT> 00138 { 00139 public: 00141 eoDeterministicSaDReplacement(eoReduce<EOT>& _reduceGlobal, 00142 double _surviveParents, double _dieParents=0, 00143 double _surviveOffspring=0, double _dieOffspring=0, 00144 bool _interpret_as_rate = true ) : 00145 reduceGlobal(_reduceGlobal), 00146 sAdParents(_surviveParents, _dieParents, _interpret_as_rate), 00147 sAdOffspring(_surviveOffspring, _dieOffspring, _interpret_as_rate) 00148 {} 00149 00151 eoDeterministicSaDReplacement( 00152 double _surviveParents, double _dieParents=0, 00153 double _surviveOffspring=0, double _dieOffspring=0, 00154 bool _interpret_as_rate = true ) : 00155 reduceGlobal(truncate), 00156 sAdParents(_surviveParents, _dieParents, _interpret_as_rate), 00157 sAdOffspring(_surviveOffspring, _dieOffspring, _interpret_as_rate) 00158 {} 00159 00160 void operator()(eoPop<EOT>& _parents, eoPop<EOT>& _offspring) 00161 { 00162 unsigned pSize = _parents.size(); // target number of individuals 00163 00164 eoPop<EOT> luckyParents; // to hold the absolute survivors 00165 sAdParents(_parents, luckyParents); 00166 00167 eoPop<EOT> luckyOffspring; // to hold the absolute survivors 00168 sAdOffspring(_offspring, luckyOffspring); 00169 00170 unsigned survivorSize = luckyOffspring.size() + luckyParents.size(); 00171 if (survivorSize > pSize) 00172 throw std::logic_error("eoGeneralReplacement: More survivors than parents!\n"); 00173 00174 plus(_parents, _offspring); // all that remain in _offspring 00175 00176 reduceGlobal(_offspring, pSize - survivorSize); 00177 plus(luckyParents, _offspring); 00178 plus(luckyOffspring, _offspring); 00179 00180 _parents.swap(_offspring); 00181 00182 } 00183 00184 private : 00185 eoReduce<EOT>& reduceGlobal; 00186 eoDeterministicSurviveAndDie<EOT> sAdParents; 00187 eoDeterministicSurviveAndDie<EOT> sAdOffspring; 00188 // plus helper (could be replaced by operator+= ???) 00189 eoPlus<EOT> plus; 00190 // the default reduce: deterministic truncation 00191 eoTruncate<EOT> truncate; 00192 }; 00193 00194 00197 #endif