EvolvingObjects
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
 All Classes Namespaces Files Functions Variables Typedefs Friends