diff --git a/eo/src/eoEasyEA.h b/eo/src/eoEasyEA.h index dbc1deba..a152abfa 100644 --- a/eo/src/eoEasyEA.h +++ b/eo/src/eoEasyEA.h @@ -98,7 +98,7 @@ template class eoEasyEA: public eoAlgo eoTransform& _transform, eoMerge& _merge, eoReduce& _reduce - ) : continuator(_continuator), + ) : continuator(_continuator), eval(_eval), selectTransform(_select, _transform), breed(selectTransform), @@ -108,19 +108,21 @@ template class eoEasyEA: public eoAlgo - + /// Apply a few generation of evolution to the population. - virtual void operator()(eoPop& _pop) + virtual void operator()(eoPop& _pop) { eoPop offspring; - - while ( continuator( _pop ) ) + + do { try { - unsigned pSize = _pop.size(); + unsigned pSize = _pop.size(); + offspring.clear(); // new offspring + breed(_pop, offspring); - + apply(eval, offspring); replace(_pop, offspring); // after replace, the new pop. is in _pop @@ -137,9 +139,9 @@ template class eoEasyEA: public eoAlgo s.append( " in eoEasyEA"); throw runtime_error( s ); } - } // while + } while ( continuator( _pop ) ); } - + private: // If selectTransform needs not be used, dummySelect and dummyTransform are used diff --git a/eo/src/eoGeneralBreeder.h b/eo/src/eoGeneralBreeder.h index 4c1eff80..563d23a8 100644 --- a/eo/src/eoGeneralBreeder.h +++ b/eo/src/eoGeneralBreeder.h @@ -69,17 +69,15 @@ class eoGeneralBreeder: public eoBreed { unsigned target = howMany(_parents.size()); - eoSelectivePopulator it(_parents, select); + _offspring.clear(); + eoSelectivePopulator it(_parents, _offspring, select); - select.setup(_parents); + while (_offspring.size() < target) + { + op(it); + ++it; + } - while (it.size() < target) - { - op(it); - ++it; - } - - swap(_offspring, it); _offspring.resize(target); // you might have generated a few more } diff --git a/eo/src/eoPopulator.h b/eo/src/eoPopulator.h index 00ee03f5..c2eed79e 100644 --- a/eo/src/eoPopulator.h +++ b/eo/src/eoPopulator.h @@ -36,11 +36,15 @@ See eoGenOp and eoOpContainer */ template -class eoPopulator : public eoPop +class eoPopulator { public : - eoPopulator(const eoPop& _src) : current(begin()), src(_src) {} + eoPopulator(const eoPop& _src, eoPop& _dest) : dest(_dest), current(dest.end()), src(_src) + { + dest.reserve(src.size()); // we don't know this, but wth. + current = dest.end(); + } struct OutOfIndividuals {}; @@ -50,24 +54,20 @@ public : */ EOT& operator*(void) { - if (current == end()) - operator++(); + if (current == dest.end()) + get_next(); // get a new individual return *current; } /** only prefix increment defined - * if needed, adds a new individual using the embedded selector - * and set the current pointer to the newly inserted individual - * otherwise simply increment the current pointer + Does not add a new element when at the end, use operator* for that + If not on the end, increment the pointer to the next individual */ eoPopulator& operator++() { - if (current == end()) - { // get new individual from derived class select() - push_back(select()); - current = end(); - --current; + if (current == dest.end()) + { // keep the pointer there return *this; } // else @@ -80,40 +80,66 @@ public : */ void insert(const EOT& _eo) { /* not really efficient, but its nice to have */ - current = eoPop::insert(current, _eo); + current = dest.insert(current, _eo); } /** just to make memory mangement more efficient */ void reserve(int how_many) { - size_t sz = current - begin(); - eoPop::reserve(size() + how_many); - current = begin() + sz; + size_t sz = current - dest.begin(); + if (dest.capacity() < dest.size() + how_many) + { + dest.reserve(dest.size() + how_many); + } + + current = dest.begin() + sz; } /** can be useful for operators with embedded selectors - * e.g. your barin and my beauty -type + * e.g. your brain and my beauty -type */ const eoPop& source(void) { return src; } + /** Get the offspring population. + Can be useful when you want to do some online niching kind of thing + */ + eoPop& offspring(void) { return dest; } + typedef unsigned position_type; /** this is a direct access container: tell position */ - position_type tellp() { return current - begin(); } + position_type tellp() { return current - dest.begin(); } /** this is a direct access container: go to position */ - void seekp(position_type pos) { current = begin() + pos; } + void seekp(position_type pos) { current = dest.begin() + pos; } /** no more individuals */ - bool exhausted(void) { return current == end(); } + bool exhausted(void) { return current == dest.end(); } - virtual const EOT& select() = 0; - -protected : /** the pure virtual selection method - will be instanciated in * eoSeqPopulator and eoPropPopulator */ + virtual const EOT& select() = 0; + +protected : + eoPop& dest; eoPop::iterator current; const eoPop& src; + +private : + void get_next() + { + if (current == dest.end()) + { // get new individual from derived class select() + dest.push_back(select()); + current = dest.end(); + --current; + return; + } + // else + ++current; + return; + } + }; @@ -125,22 +151,22 @@ class eoSeqPopulator : public eoPopulator { public : - eoSeqPopulator(const eoPop& _pop) : - eoPopulator(_pop), src_it(_pop.begin()) {} + eoSeqPopulator(const eoPop& _pop, eoPop& _dest) : + eoPopulator(_pop, _dest), current(0) {} const EOT& select(void) { - if (src_it == src.end()) + if (current >= src.size()) { throw OutOfIndividuals(); } - const EOT& res = *src_it++; + const EOT& res = src[current++]; return res; } private : - vector::const_iterator src_it; + unsigned current; }; @@ -151,8 +177,11 @@ template class eoSelectivePopulator : public eoPopulator { public : - eoSelectivePopulator(const eoPop& _pop, eoSelectOne& _sel) - : eoPopulator(_pop), sel(_sel) {} + eoSelectivePopulator(const eoPop& _pop, eoPop& _dest, eoSelectOne& _sel) + : eoPopulator(_pop, _dest), sel(_sel) + { + sel.setup(_pop); + } const EOT& select() { diff --git a/eo/src/eoRandomSelect.h b/eo/src/eoRandomSelect.h index 417c0e29..c73c6dd8 100644 --- a/eo/src/eoRandomSelect.h +++ b/eo/src/eoRandomSelect.h @@ -60,25 +60,25 @@ template class eoRandomSelect: public eoSelectOne template class eoBestSelect: public eoSelectOne { public: - + /// not a big deal!!! - virtual const EOT& operator()(const eoPop& _pop) + virtual const EOT& operator()(const eoPop& _pop) { return _pop.best_element() ; } }; //----------------------------------------------------------------------------- -/** eoSequentialSelect: returns all individual in order +/** eoSequentialSelect: returns all individual in order * looping back to the beginning when exhasuted * can be from best to worse, or in random order * - * It is the eoSelectOne equivalent of eoDetSelect - + * It is the eoSelectOne equivalent of eoDetSelect - * though eoDetSelect always returns individuals from best to worst */ //----------------------------------------------------------------------------- -template class eoSequentialSelect: public eoSelectOne +template class eoSequentialSelect: public eoSelectOne { public: /** Ctor: sets the current pter to MAXINT so init will take place first time @@ -87,19 +87,21 @@ template class eoSequentialSelect: public eoSelectOne eoSequentialSelect(bool _ordered = true): ordered(_ordered), current(MAXINT) {} - void init(const eoPop& _pop) + void setup(const eoPop& _pop) { + eoPters.resize(_pop.size()); if (ordered) // probably we could have a marker to avoid re-sorting - _pop.sort(eoPters); + _pop.sort(eoPters); else _pop.shuffle(eoPters); current=0; } - virtual const EOT& operator()(const eoPop& _pop) + virtual const EOT& operator()(const eoPop& _pop) { if (current >= _pop.size()) - init(_pop); + setup(_pop); + unsigned eoN = current; current++; return *eoPters[eoN] ;