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)
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
00084 unsigned reducedParentSize = howManyReducedParents(_parents.size());
00085 if (!reducedParentSize)
00086 _parents.clear();
00087 else if (reducedParentSize != _parents.size())
00088 reduceParents(_parents, reducedParentSize);
00089
00090
00091 unsigned reducedOffspringSize = howManyReducedOffspring(offSize);
00092 if (!reducedOffspringSize)
00093 throw std::runtime_error("No offspring left after reduction!");
00094 if (reducedOffspringSize != offSize)
00095 reduceOffspring(_offspring, reducedOffspringSize);
00096
00097
00098 _parents.resize(reducedParentSize + _offspring.size());
00099 std::copy(_offspring.begin(), _offspring.end(),
00100 _parents.begin()+reducedParentSize);
00101
00102
00103
00104 if (elite && strongElitism)
00105 {
00106 if (_parents.size() != finalPopSize-elite)
00107 reduceFinal(_parents, finalPopSize-elite);
00108
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 {
00115 if (_parents.size() != finalPopSize)
00116 reduceFinal(_parents, finalPopSize);
00117 if (elite)
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;
00134 bool strongElitism;
00135 eoHowMany howManyReducedParents;
00136 eoHowMany howManyReducedOffspring;
00137
00138 eoReduce<EOT> & reduceParents;
00139 eoReduce<EOT> & reduceOffspring;
00140 eoReduce<EOT> & reduceFinal;
00141 };
00142
00143 #endif