Changed the populator to be a) more efficient and b) more useable
It is no longer derived from eoPop, it now gets a destination population. This saves a lot of copying. The semantics has changed a little as well. It is now an _infinite_ iterator. operator++ will *not* dispense new individuals, but will merely stay at the end. To get a new indy, use operator*() as before. eoEasyEA now checks the checkpoint *after* making a generation and clears the offspring eoGeneralBreeder is changed to reflect the changes in eoPopulator eoSequentialSelect now uses setup() rather than init()
This commit is contained in:
parent
a27aa7112a
commit
ead2ac2c62
4 changed files with 88 additions and 57 deletions
|
|
@ -114,11 +114,13 @@ template<class EOT> class eoEasyEA: public eoAlgo<EOT>
|
||||||
{
|
{
|
||||||
eoPop<EOT> offspring;
|
eoPop<EOT> offspring;
|
||||||
|
|
||||||
while ( continuator( _pop ) )
|
do
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
unsigned pSize = _pop.size();
|
unsigned pSize = _pop.size();
|
||||||
|
offspring.clear(); // new offspring
|
||||||
|
|
||||||
breed(_pop, offspring);
|
breed(_pop, offspring);
|
||||||
|
|
||||||
apply<EOT>(eval, offspring);
|
apply<EOT>(eval, offspring);
|
||||||
|
|
@ -137,7 +139,7 @@ template<class EOT> class eoEasyEA: public eoAlgo<EOT>
|
||||||
s.append( " in eoEasyEA");
|
s.append( " in eoEasyEA");
|
||||||
throw runtime_error( s );
|
throw runtime_error( s );
|
||||||
}
|
}
|
||||||
} // while
|
} while ( continuator( _pop ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
||||||
|
|
@ -69,17 +69,15 @@ class eoGeneralBreeder: public eoBreed<EOT>
|
||||||
{
|
{
|
||||||
unsigned target = howMany(_parents.size());
|
unsigned target = howMany(_parents.size());
|
||||||
|
|
||||||
eoSelectivePopulator<EOT> it(_parents, select);
|
_offspring.clear();
|
||||||
|
eoSelectivePopulator<EOT> 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
|
_offspring.resize(target); // you might have generated a few more
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -36,11 +36,15 @@
|
||||||
See eoGenOp and eoOpContainer
|
See eoGenOp and eoOpContainer
|
||||||
*/
|
*/
|
||||||
template <class EOT>
|
template <class EOT>
|
||||||
class eoPopulator : public eoPop<EOT>
|
class eoPopulator
|
||||||
{
|
{
|
||||||
public :
|
public :
|
||||||
|
|
||||||
eoPopulator(const eoPop<EOT>& _src) : current(begin()), src(_src) {}
|
eoPopulator(const eoPop<EOT>& _src, eoPop<EOT>& _dest) : dest(_dest), current(dest.end()), src(_src)
|
||||||
|
{
|
||||||
|
dest.reserve(src.size()); // we don't know this, but wth.
|
||||||
|
current = dest.end();
|
||||||
|
}
|
||||||
|
|
||||||
struct OutOfIndividuals {};
|
struct OutOfIndividuals {};
|
||||||
|
|
||||||
|
|
@ -50,24 +54,20 @@ public :
|
||||||
*/
|
*/
|
||||||
EOT& operator*(void)
|
EOT& operator*(void)
|
||||||
{
|
{
|
||||||
if (current == end())
|
if (current == dest.end())
|
||||||
operator++();
|
get_next(); // get a new individual
|
||||||
|
|
||||||
return *current;
|
return *current;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** only prefix increment defined
|
/** only prefix increment defined
|
||||||
* if needed, adds a new individual using the embedded selector
|
Does not add a new element when at the end, use operator* for that
|
||||||
* and set the current pointer to the newly inserted individual
|
If not on the end, increment the pointer to the next individual
|
||||||
* otherwise simply increment the current pointer
|
|
||||||
*/
|
*/
|
||||||
eoPopulator& operator++()
|
eoPopulator& operator++()
|
||||||
{
|
{
|
||||||
if (current == end())
|
if (current == dest.end())
|
||||||
{ // get new individual from derived class select()
|
{ // keep the pointer there
|
||||||
push_back(select());
|
|
||||||
current = end();
|
|
||||||
--current;
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
// else
|
// else
|
||||||
|
|
@ -80,40 +80,66 @@ public :
|
||||||
*/
|
*/
|
||||||
void insert(const EOT& _eo)
|
void insert(const EOT& _eo)
|
||||||
{ /* not really efficient, but its nice to have */
|
{ /* not really efficient, but its nice to have */
|
||||||
current = eoPop<EOT>::insert(current, _eo);
|
current = dest.insert(current, _eo);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** just to make memory mangement more efficient
|
/** just to make memory mangement more efficient
|
||||||
*/
|
*/
|
||||||
void reserve(int how_many)
|
void reserve(int how_many)
|
||||||
{
|
{
|
||||||
size_t sz = current - begin();
|
size_t sz = current - dest.begin();
|
||||||
eoPop<EOT>::reserve(size() + how_many);
|
if (dest.capacity() < dest.size() + how_many)
|
||||||
current = begin() + sz;
|
{
|
||||||
|
dest.reserve(dest.size() + how_many);
|
||||||
|
}
|
||||||
|
|
||||||
|
current = dest.begin() + sz;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** can be useful for operators with embedded selectors
|
/** 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<EOT>& source(void) { return src; }
|
const eoPop<EOT>& source(void) { return src; }
|
||||||
|
|
||||||
|
/** Get the offspring population.
|
||||||
|
Can be useful when you want to do some online niching kind of thing
|
||||||
|
*/
|
||||||
|
eoPop<EOT>& offspring(void) { return dest; }
|
||||||
|
|
||||||
typedef unsigned position_type;
|
typedef unsigned position_type;
|
||||||
|
|
||||||
/** this is a direct access container: tell position */
|
/** 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 */
|
/** 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 */
|
/** 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
|
/** the pure virtual selection method - will be instanciated in
|
||||||
* eoSeqPopulator and eoPropPopulator
|
* eoSeqPopulator and eoPropPopulator
|
||||||
*/
|
*/
|
||||||
|
virtual const EOT& select() = 0;
|
||||||
|
|
||||||
|
protected :
|
||||||
|
eoPop<EOT>& dest;
|
||||||
eoPop<EOT>::iterator current;
|
eoPop<EOT>::iterator current;
|
||||||
const eoPop<EOT>& src;
|
const eoPop<EOT>& 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<EOT>
|
||||||
{
|
{
|
||||||
public :
|
public :
|
||||||
|
|
||||||
eoSeqPopulator(const eoPop<EOT>& _pop) :
|
eoSeqPopulator(const eoPop<EOT>& _pop, eoPop<EOT>& _dest) :
|
||||||
eoPopulator<EOT>(_pop), src_it(_pop.begin()) {}
|
eoPopulator<EOT>(_pop, _dest), current(0) {}
|
||||||
|
|
||||||
const EOT& select(void)
|
const EOT& select(void)
|
||||||
{
|
{
|
||||||
if (src_it == src.end())
|
if (current >= src.size())
|
||||||
{
|
{
|
||||||
throw OutOfIndividuals();
|
throw OutOfIndividuals();
|
||||||
}
|
}
|
||||||
|
|
||||||
const EOT& res = *src_it++;
|
const EOT& res = src[current++];
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
private :
|
private :
|
||||||
vector<EOT>::const_iterator src_it;
|
unsigned current;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -151,8 +177,11 @@ template <class EOT>
|
||||||
class eoSelectivePopulator : public eoPopulator<EOT>
|
class eoSelectivePopulator : public eoPopulator<EOT>
|
||||||
{
|
{
|
||||||
public :
|
public :
|
||||||
eoSelectivePopulator(const eoPop<EOT>& _pop, eoSelectOne<EOT>& _sel)
|
eoSelectivePopulator(const eoPop<EOT>& _pop, eoPop<EOT>& _dest, eoSelectOne<EOT>& _sel)
|
||||||
: eoPopulator<EOT>(_pop), sel(_sel) {}
|
: eoPopulator<EOT>(_pop, _dest), sel(_sel)
|
||||||
|
{
|
||||||
|
sel.setup(_pop);
|
||||||
|
}
|
||||||
|
|
||||||
const EOT& select()
|
const EOT& select()
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -87,10 +87,11 @@ template <class EOT> class eoSequentialSelect: public eoSelectOne<EOT>
|
||||||
eoSequentialSelect(bool _ordered = true):
|
eoSequentialSelect(bool _ordered = true):
|
||||||
ordered(_ordered), current(MAXINT) {}
|
ordered(_ordered), current(MAXINT) {}
|
||||||
|
|
||||||
void init(const eoPop<EOT>& _pop)
|
void setup(const eoPop<EOT>& _pop)
|
||||||
{
|
{
|
||||||
|
eoPters.resize(_pop.size());
|
||||||
if (ordered) // probably we could have a marker to avoid re-sorting
|
if (ordered) // probably we could have a marker to avoid re-sorting
|
||||||
_pop.sort(eoPters);
|
_pop.sort(eoPters);
|
||||||
else
|
else
|
||||||
_pop.shuffle(eoPters);
|
_pop.shuffle(eoPters);
|
||||||
current=0;
|
current=0;
|
||||||
|
|
@ -99,7 +100,8 @@ template <class EOT> class eoSequentialSelect: public eoSelectOne<EOT>
|
||||||
virtual const EOT& operator()(const eoPop<EOT>& _pop)
|
virtual const EOT& operator()(const eoPop<EOT>& _pop)
|
||||||
{
|
{
|
||||||
if (current >= _pop.size())
|
if (current >= _pop.size())
|
||||||
init(_pop);
|
setup(_pop);
|
||||||
|
|
||||||
unsigned eoN = current;
|
unsigned eoN = current;
|
||||||
current++;
|
current++;
|
||||||
return *eoPters[eoN] ;
|
return *eoPters[eoN] ;
|
||||||
|
|
|
||||||
Reference in a new issue