# eoReduceMergeReduce.h

    00001
    00024 //-----------------------------------------------------------------------------
    00025
    00026 #ifndef _eoReduceMergeReduce_h
    00027 #define _eoReduceMergeReduce_h
    00028
    00029
    00030 //-----------------------------------------------------------------------------
    00031 #include <eoPop.h>
    00032 #include <eoFunctor.h>
    00033 #include <eoMerge.h>
    00034 #include <eoReduce.h>
    00035 #include <utils/eoHowMany.h>
    00036 //-----------------------------------------------------------------------------
    00037
    00048 template <class EOT>
    00049 class eoReduceMergeReduce : public eoReplacement<EOT>
    00050 {
    00051 public:
    00052   eoReduceMergeReduce(eoHowMany _howManyElite,
    00053                       bool _strongElitism,
    00054                       eoHowMany _howManyReducedParents,
    00055                       eoReduce<EOT> & _reduceParents,
    00056                       eoHowMany _howManyReducedOffspring,
    00057                       eoReduce<EOT> & _reduceOffspring,
    00058                       eoReduce<EOT> & _reduceFinal) :
    00059     howManyElite(_howManyElite),
    00060     strongElitism(_strongElitism),
    00061     howManyReducedParents(_howManyReducedParents),
    00062     howManyReducedOffspring (_howManyReducedOffspring),
    00063     reduceParents(_reduceParents),
    00064     reduceOffspring(_reduceOffspring),
    00065     reduceFinal(_reduceFinal)
    00066   {}
    00067
    00068     void operator()(eoPop<EOT> & _parents, eoPop<EOT> & _offspring)
    00069     {
    00070       eoPop<EOT> temp;
    00071       unsigned int finalPopSize = _parents.size();
    00072       unsigned int offSize = _offspring.size();
    00073
    00074       unsigned int elite = howManyElite(finalPopSize);
    00075       if (elite)                   // some parents MUST be saved somewhere
    00076         {
    00077           temp.resize(elite);
    00078           _parents.nth_element(elite);
    00079           std::copy(_parents.begin(), _parents.begin()+elite, temp.begin());
    00080           _parents.erase(_parents.begin(), _parents.begin()+elite);
    00081         }
    00082
    00083       // the reduce steps. First the parents
    00084       unsigned reducedParentSize = howManyReducedParents(_parents.size());
    00085       if (!reducedParentSize)
    00086         _parents.clear();
    00087       else if (reducedParentSize != _parents.size())
    00088         reduceParents(_parents, reducedParentSize);
    00089
    00090       // then the offspring
    00091       unsigned reducedOffspringSize = howManyReducedOffspring(offSize);
    00092       if (!reducedOffspringSize)
    00093         throw std::runtime_error("No offspring left after reduction!");
    00094       if (reducedOffspringSize != offSize) // need reduction
    00095         reduceOffspring(_offspring, reducedOffspringSize);
    00096
    00097       // now merge reduced populations
    00098       _parents.resize(reducedParentSize + _offspring.size());
    00099       std::copy(_offspring.begin(), _offspring.end(),
    00100                 _parents.begin()+reducedParentSize);
    00101
    00102       // reduce the resulting population
    00103       // size depstd::ends on elitism
    00104       if (elite && strongElitism)
    00105         {
    00106           if (_parents.size() != finalPopSize-elite)
    00107             reduceFinal(_parents, finalPopSize-elite);
    00108           // and put back the elite
    00109           unsigned oldPSize = _parents.size();
    00110           _parents.resize(_parents.size()+elite);
    00111           std::copy(temp.begin(), temp.end(), _parents.begin()+oldPSize);
    00112         }
    00113       else
    00114         {                   // only reduce final pop to right size
    00115           if (_parents.size() != finalPopSize)
    00116             reduceFinal(_parents, finalPopSize);
    00117           if (elite)       // then treat weak elitism
    00118             {
    00119               unsigned toSave = 0;
    00120               _parents.sort();
    00121               EOT & eoLimit = _parents[elite-1];
    00122               unsigned index=0;
    00123               while ( (temp[index++] > eoLimit) && (index < temp.size()) )
    00124                 toSave++;
    00125               if (toSave)
    00126                 for (unsigned i=0; i<toSave; i++)
    00127                   _parents[finalPopSize-1-i] = temp[i];
    00128             }
    00129         }
    00130     }
    00131
    00132 private:
    00133   eoHowMany howManyElite;          // if 0, no elitism at all
    00134   bool strongElitism;              // if false -> weak estd::listism
    00135   eoHowMany howManyReducedParents; // if 0, no parent in final replacement
    00136   eoHowMany howManyReducedOffspring; // if 0, std::runtime_error
    00137   // the reducers
    00138   eoReduce<EOT> & reduceParents;
    00139   eoReduce<EOT> & reduceOffspring;
    00140   eoReduce<EOT> & reduceFinal;
    00141 };
    00142
    00143 #endif