# eoSurviveAndDie.h

    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
    00052 template <class EOT>
    00053 class eoSurviveAndDie : public eoBF<eoPop<EOT> &, eoPop<EOT> &, void>
    00054 {
    00055 public:
    00056     eoSurviveAndDie(double _survive, double _die, bool _interpret_as_rate = true):
    00057         howmanySurvive(_survive, _interpret_as_rate),
    00058         howmanyDie(_die, _interpret_as_rate)
    00059     {}
    00060
    00061 protected:
    00062     eoHowMany howmanySurvive;
    00063     eoHowMany howmanyDie;
    00064
    00065 };
    00066
    00072 template <class EOT>
    00073 class eoDeterministicSurviveAndDie : public eoSurviveAndDie<EOT>
    00074 {
    00075 public:
    00076
    00077     using eoSurviveAndDie< EOT >::howmanyDie;
    00078     using eoSurviveAndDie< EOT >::howmanySurvive;
    00079
    00081     eoDeterministicSurviveAndDie(double _survive, double _die, bool _interpret_as_rate = true)
    00082         : eoSurviveAndDie< EOT >(_survive, _die, _interpret_as_rate)
    00083     {}
    00084
    00085
    00086     void operator()(eoPop<EOT> & _pop, eoPop<EOT> & _luckyGuys)
    00087     {
    00088         unsigned pSize = _pop.size();
    00089         unsigned nbSurvive = howmanySurvive(pSize);
    00090         // first, save the best into _luckyGuys
    00091         if (nbSurvive)
    00092             {
    00093                 _pop.nth_element(nbSurvive);
    00094                 // copy best
    00095                 _luckyGuys.resize(nbSurvive);
    00096                 std::copy(_pop.begin(), _pop.begin()+nbSurvive, _luckyGuys.begin());
    00097                 // erase them from pop
    00098                 _pop.erase(_pop.begin(), _pop.begin()+nbSurvive);
    00099             }
    00100         unsigned nbRemaining = _pop.size();
    00101
    00102         // carefull, we can have a rate of 1 if we want to kill all remaining
    00103         unsigned nbDie = std::min(howmanyDie(pSize), pSize-nbSurvive);
    00104         if (nbDie > nbRemaining)
    00105             throw std::logic_error("eoDeterministicSurviveAndDie: Too many to kill!\n");
    00106
    00107         if (!nbDie)
    00108           {
    00109             return;
    00110           }
    00111         // else
    00112         // kill the worse nbDie
    00113         _pop.nth_element(nbRemaining-nbDie);
    00114         _pop.resize(nbRemaining-nbDie);
    00115     }
    00116
    00117 };
    00118
    00131 template <class EOT>
    00132 class eoDeterministicSaDReplacement : public eoReplacement<EOT>
    00133 {
    00134 public:
    00136   eoDeterministicSaDReplacement(eoReduce<EOT>& _reduceGlobal,
    00137                  double _surviveParents, double _dieParents=0,
    00138                  double _surviveOffspring=0, double _dieOffspring=0,
    00139                  bool _interpret_as_rate = true ) :
    00140         reduceGlobal(_reduceGlobal),
    00141         sAdParents(_surviveParents, _dieParents, _interpret_as_rate),
    00142         sAdOffspring(_surviveOffspring, _dieOffspring, _interpret_as_rate)
    00143     {}
    00144
    00146     eoDeterministicSaDReplacement(
    00147                  double _surviveParents, double _dieParents=0,
    00148                  double _surviveOffspring=0, double _dieOffspring=0,
    00149                  bool _interpret_as_rate = true ) :
    00150         reduceGlobal(truncate),
    00151         sAdParents(_surviveParents, _dieParents, _interpret_as_rate),
    00152         sAdOffspring(_surviveOffspring, _dieOffspring, _interpret_as_rate)
    00153     {}
    00154
    00155     void operator()(eoPop<EOT>& _parents, eoPop<EOT>& _offspring)
    00156     {
    00157         unsigned pSize = _parents.size(); // target number of individuals
    00158
    00159         eoPop<EOT> luckyParents;       // to hold the absolute survivors
    00160         sAdParents(_parents, luckyParents);
    00161
    00162         eoPop<EOT> luckyOffspring;       // to hold the absolute survivors
    00163         sAdOffspring(_offspring, luckyOffspring);
    00164
    00165         unsigned survivorSize = luckyOffspring.size() + luckyParents.size();
    00166         if (survivorSize > pSize)
    00167             throw std::logic_error("eoGeneralReplacement: More survivors than parents!\n");
    00168
    00169         plus(_parents, _offspring); // all that remain in _offspring
    00170
    00171         reduceGlobal(_offspring, pSize - survivorSize);
    00172         plus(luckyParents, _offspring);
    00173         plus(luckyOffspring, _offspring);
    00174
    00175         _parents.swap(_offspring);
    00176
    00177     }
    00178
    00179 private :
    00180   eoReduce<EOT>& reduceGlobal;
    00181   eoDeterministicSurviveAndDie<EOT> sAdParents;
    00182   eoDeterministicSurviveAndDie<EOT> sAdOffspring;
    00183   // plus helper (could be replaced by operator+= ???)
    00184   eoPlus<EOT> plus;
    00185   // the default reduce: deterministic truncation
    00186   eoTruncate<EOT> truncate;
    00187 };
    00188
    00189
    00190
    00191 #endif