THe big eoReplacement update:
The interface for eoReplacement is now eoPop<EOT>&, eoPop<EOT>& (i.e. no const) and the result must be in the first argument in the end. Hence it is possible to do SSGA and all intermediate replacmeent procedures The classes derived from eoMergeReduce.h are now in a separate file The SSGA-like replcaement procedures are in eoReduceMerge.h A more general replacement can be found in eoSurviveAndDie.h (it could be made a littel more general - still open for upgrades). Also some accessors have been added to the eoPop (best and worse individuals) And include file eo has been updated
This commit is contained in:
parent
25dd305ee6
commit
6acdcb6d9b
12 changed files with 902 additions and 96 deletions
|
|
@ -4,7 +4,7 @@
|
|||
##
|
||||
###############################################################################
|
||||
|
||||
SUBDIRS = es ga gp utils other
|
||||
SUBDIRS = es ga utils other
|
||||
CPPFLAGS = -O2
|
||||
|
||||
lib_LIBRARIES = libeo.a
|
||||
|
|
|
|||
25
eo/src/eo
25
eo/src/eo
|
|
@ -30,8 +30,20 @@
|
|||
|
||||
// some defines to make things easier to get at first sight
|
||||
|
||||
// tunigni the amount of output using a boolean argument:
|
||||
// true should always mean more output
|
||||
#define eo_verbose true
|
||||
#define eo_no_verbose false
|
||||
// to be used in selection / replacement procedures to indicate whether
|
||||
// the argument (rate, a double) shoudl be treated as a rate (number=rate*popSize)
|
||||
// or as an absolute integer (number=rate regardless of popsize).
|
||||
// the default value shoudl ALWAYS be true (eo_as_a_rate).
|
||||
//
|
||||
// this construct is mandatory because in some cases you might not know the
|
||||
// population size that will enter the replacement for instance - so you
|
||||
// cannot simply have a pre-computed (double) rate of 1/popSize
|
||||
#define eo_is_a_rate true
|
||||
#define eo_is_an_integer false
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include <utils/eoData.h>
|
||||
|
|
@ -86,13 +98,24 @@
|
|||
#include <eoSteadyFitContinue.h>
|
||||
#include <eoFitContinue.h>
|
||||
|
||||
// Selection and reproduction stuff
|
||||
// Selection
|
||||
#include <eoSelectOne.h>
|
||||
#include <eoSelectRandom.h>
|
||||
#include <eoDetTournament.h>
|
||||
#include <eoProportional.h>
|
||||
#include <eoStochTournament.h>
|
||||
#include <eoSelectPerc.h>
|
||||
#include <eoSelectNumber.h>
|
||||
#include <eoSelectMany.h>
|
||||
|
||||
|
||||
// Replacement
|
||||
// #include <eoReplacement.h>
|
||||
#include <eoMergeReduce.h>
|
||||
#include <eoReduceMerge.h>
|
||||
#include <eoSurviveAndDie.h>
|
||||
|
||||
// Variation
|
||||
#include <eoProportionalCombinedOp.h>
|
||||
#include <eoProportionalOpSel.h>
|
||||
#include <eoProportionalGOpSel.h>
|
||||
|
|
|
|||
|
|
@ -119,24 +119,23 @@ template<class EOT> class eoEasyEA: public eoAlgo<EOT>
|
|||
{
|
||||
try
|
||||
{
|
||||
unsigned pSize = _pop.size();
|
||||
breed(_pop, offspring);
|
||||
|
||||
apply<EOT>(eval, offspring);
|
||||
|
||||
replace(_pop, offspring);
|
||||
|
||||
if (offspring.size() < _pop.size())
|
||||
replace(_pop, offspring); // after replace, the new pop. is in _pop
|
||||
|
||||
if (pSize > _pop.size())
|
||||
throw runtime_error("Population shrinking!");
|
||||
else if (offspring.size() > _pop.size())
|
||||
else if (pSize < _pop.size())
|
||||
throw runtime_error("Population growing!");
|
||||
|
||||
_pop.swap(offspring);
|
||||
|
||||
}
|
||||
catch (exception& e)
|
||||
{
|
||||
string s = e.what();
|
||||
s.append( " in eoSelectTransformReduce ");
|
||||
s.append( " in eoEasyEA");
|
||||
throw runtime_error( s );
|
||||
}
|
||||
} // while
|
||||
|
|
|
|||
|
|
@ -50,32 +50,55 @@ template<class Chrom> class eoMerge: public eoBF<const eoPop<Chrom>&, eoPop<Chro
|
|||
|
||||
/**
|
||||
Straightforward elitism class, specify the number of individuals to copy
|
||||
into new geneneration
|
||||
into new geneneration or the rate w.r.t. pop size
|
||||
*/
|
||||
template <class EOT> class eoElitism : public eoMerge<EOT>
|
||||
{
|
||||
public :
|
||||
eoElitism(unsigned _howmany) : howmany(_howmany) {}
|
||||
|
||||
void operator()(const eoPop<EOT>& _pop, eoPop<EOT>& offspring)
|
||||
{
|
||||
if (howmany == 0)
|
||||
return;
|
||||
|
||||
if (howmany > _pop.size())
|
||||
throw std::logic_error("Elite larger than population");
|
||||
|
||||
vector<const EOT*> result;
|
||||
_pop.nth_element(howmany, result);
|
||||
|
||||
for (size_t i = 0; i < result.size(); ++i)
|
||||
{
|
||||
offspring.push_back(*result[i]);
|
||||
}
|
||||
}
|
||||
|
||||
private :
|
||||
unsigned howmany;
|
||||
public :
|
||||
eoElitism(double _rate, bool _interpret_as_rate = true):
|
||||
rate(0), howmany(0)
|
||||
{
|
||||
if (_interpret_as_rate)
|
||||
{
|
||||
if ( (_rate<0) || (_rate>1) )
|
||||
throw std::logic_error("eoElitism: rate shoud be in [0,1]");
|
||||
rate = _rate;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_rate<0)
|
||||
throw std::logic_error("Negative number of offspring in eoElitism!");
|
||||
howmany = (unsigned int)_rate;
|
||||
if (howmany != _rate)
|
||||
cout << "Warning: Number of guys to merge in eoElitism was rounded";
|
||||
}
|
||||
}
|
||||
|
||||
void operator()(const eoPop<EOT>& _pop, eoPop<EOT>& _offspring)
|
||||
{
|
||||
if ((howmany == 0) && (rate == 0.0))
|
||||
return;
|
||||
unsigned howmanyLocal;
|
||||
if (howmany == 0) // rate is specified
|
||||
howmanyLocal = (unsigned int) (rate * _pop.size());
|
||||
else
|
||||
howmanyLocal = howmany;
|
||||
|
||||
if (howmanyLocal > _pop.size())
|
||||
throw std::logic_error("Elite larger than population");
|
||||
|
||||
vector<const EOT*> result;
|
||||
_pop.nth_element(howmanyLocal, result);
|
||||
|
||||
for (size_t i = 0; i < result.size(); ++i)
|
||||
{
|
||||
_offspring.push_back(*result[i]);
|
||||
}
|
||||
}
|
||||
|
||||
private :
|
||||
double rate;
|
||||
unsigned howmany;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -93,18 +116,17 @@ Very elitist class, copies entire population into next gen
|
|||
template <class EOT> class eoPlus : public eoMerge<EOT>
|
||||
{
|
||||
public :
|
||||
void operator()(const eoPop<EOT>& _pop, eoPop<EOT>& offspring)
|
||||
void operator()(const eoPop<EOT>& _pop, eoPop<EOT>& _offspring)
|
||||
{
|
||||
offspring.reserve(offspring.size() + _pop.size());
|
||||
_offspring.reserve(_offspring.size() + _pop.size());
|
||||
|
||||
for (size_t i = 0; i < _pop.size(); ++i)
|
||||
{
|
||||
offspring.push_back(_pop[i]);
|
||||
_offspring.push_back(_pop[i]);
|
||||
}
|
||||
}
|
||||
|
||||
private :
|
||||
unsigned howmany;
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
|
|
|||
98
eo/src/eoMergeReduce.h
Normal file
98
eo/src/eoMergeReduce.h
Normal file
|
|
@ -0,0 +1,98 @@
|
|||
/** -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*-
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
eoMergeReduce.h
|
||||
(c) Maarten Keijzer, GeNeura Team, 2000
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
Contact: todos@geneura.ugr.es, http://geneura.ugr.es
|
||||
*/
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef _eoMergeReduce_h
|
||||
#define _eoMergeReduce_h
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
#include <eoPop.h>
|
||||
#include <eoFunctor.h>
|
||||
#include <eoMerge.h>
|
||||
#include <eoReduce.h>
|
||||
#include <eoReplacement.h>
|
||||
#include <utils/eoHowMany.h>
|
||||
//-----------------------------------------------------------------------------
|
||||
/**
|
||||
Replacement strategies that combine en eoMerge and an eoReduce.
|
||||
|
||||
@classes: eoMergeReduce, the base (pure abstract) class
|
||||
eoPlusReplacement the ES plus strategy
|
||||
eoCommaReplacement the ES comma strategy
|
||||
*/
|
||||
|
||||
/**
|
||||
eoMergeReduce: abstract replacement strategy that is just an application of
|
||||
an embedded merge, followed by an embedded reduce
|
||||
*/
|
||||
template <class EOT>
|
||||
class eoMergeReduce : public eoReplacement<EOT>
|
||||
{
|
||||
public:
|
||||
eoMergeReduce(eoMerge<EOT>& _merge, eoReduce<EOT>& _reduce) :
|
||||
merge(_merge), reduce(_reduce)
|
||||
{}
|
||||
|
||||
void operator()(eoPop<EOT>& _parents, eoPop<EOT>& _offspring)
|
||||
{
|
||||
merge(_parents, _offspring); // parents untouched, result in offspring
|
||||
reduce(_offspring, _parents.size());
|
||||
_parents.swap(_offspring);
|
||||
}
|
||||
|
||||
private :
|
||||
eoMerge<EOT>& merge;
|
||||
eoReduce<EOT>& reduce;
|
||||
};
|
||||
|
||||
/**
|
||||
ES type of replacement strategy: first add parents to population, then truncate
|
||||
*/
|
||||
template <class EOT>
|
||||
class eoPlusReplacement : public eoMergeReduce<EOT>
|
||||
{
|
||||
public :
|
||||
eoPlusReplacement() : eoMergeReduce<EOT>(plus, truncate) {}
|
||||
|
||||
private :
|
||||
eoPlus<EOT> plus;
|
||||
eoTruncate<EOT> truncate;
|
||||
};
|
||||
|
||||
/**
|
||||
ES type of replacement strategy: ignore parents, truncate offspring
|
||||
*/
|
||||
template <class EOT>
|
||||
class eoCommaReplacement : public eoMergeReduce<EOT>
|
||||
{
|
||||
public :
|
||||
eoCommaReplacement() : eoMergeReduce<EOT>(no_elite, truncate) {}
|
||||
|
||||
private :
|
||||
eoNoElitism<EOT> no_elite;
|
||||
eoTruncate<EOT> truncate;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
|
|
@ -123,6 +123,7 @@ class eoPop: public vector<EOT>, public eoObject, public eoPersistent
|
|||
std::sort(begin(), end(), greater<EOT>());
|
||||
}
|
||||
|
||||
// creates a vector<EOT*> pointing to the individuals in descending order
|
||||
void sort(vector<const EOT*>& result) const
|
||||
{
|
||||
result.resize(size());
|
||||
|
|
@ -132,9 +133,37 @@ class eoPop: public vector<EOT>, public eoObject, public eoPersistent
|
|||
std::sort(result.begin(), result.end(), Cmp());
|
||||
}
|
||||
|
||||
// returns an iterator to the best individual DOES NOT MOVE ANYBODY
|
||||
eoPop<EOT>::iterator it_best_element()
|
||||
{
|
||||
typename eoPop<EOT>::const_iterator it = max_element(begin(), end());
|
||||
return it;
|
||||
}
|
||||
|
||||
// returns an iterator to the best individual DOES NOT MOVE ANYBODY
|
||||
const EOT & best_element() const
|
||||
{
|
||||
typename eoPop<EOT>::const_iterator it = max_element(begin(), end());
|
||||
return (*it);
|
||||
}
|
||||
|
||||
// returns a const reference to the worse individual DOES NOT MOVE ANYBODY
|
||||
const EOT & worse_element() const
|
||||
{
|
||||
typename eoPop<EOT>::const_iterator it = min_element(begin(), end());
|
||||
return (*it);
|
||||
}
|
||||
|
||||
// returns an iterator to the worse individual DOES NOT MOVE ANYBODY
|
||||
eoPop<EOT>::iterator it_worse_element()
|
||||
{
|
||||
typename eoPop<EOT>::iterator it = min_element(begin(), end());
|
||||
return it;
|
||||
}
|
||||
|
||||
/**
|
||||
slightly faster algorithm than sort to find all individuals that are better
|
||||
than the nth individual
|
||||
than the nth individual. INDIVIDUALS ARE MOVED AROUND in the pop.
|
||||
*/
|
||||
eoPop<EOT>::iterator nth_element(int nth)
|
||||
{
|
||||
|
|
@ -168,6 +197,7 @@ class eoPop: public vector<EOT>, public eoObject, public eoPersistent
|
|||
std::nth_element(result.begin(), it, result.end(), Cmp());
|
||||
}
|
||||
|
||||
// does STL swap with other pop
|
||||
void swap(eoPop<EOT>& other)
|
||||
{
|
||||
std::swap(static_cast<vector<EOT>& >(*this), static_cast<vector<EOT>& >(other));
|
||||
|
|
|
|||
|
|
@ -33,26 +33,199 @@
|
|||
// EO includes
|
||||
#include <eoPop.h> // eoPop
|
||||
#include <eoFunctor.h> // eoReduce
|
||||
#include <utils/selectors.h>
|
||||
|
||||
/**
|
||||
* eoReduce: .reduce the new generation to the specified size
|
||||
At the moment, limited to truncation - with 2 different methods,
|
||||
one that sorts the whole population, and one that repeatidely kills
|
||||
the worst. Ideally, we should be able to choose at run-time!!!
|
||||
*/
|
||||
|
||||
template<class Chrom> class eoReduce: public eoBF<eoPop<Chrom>&, unsigned, void>
|
||||
template<class EOT> class eoReduce: public eoBF<eoPop<EOT>&, unsigned, void>
|
||||
{};
|
||||
|
||||
/** truncation method using sort */
|
||||
template <class EOT> class eoTruncate : public eoReduce<EOT>
|
||||
{
|
||||
void operator()(eoPop<EOT>& _newgen, unsigned _newsize)
|
||||
{
|
||||
if (_newgen.size() == _newsize)
|
||||
return;
|
||||
if (_newgen.size() < _newsize)
|
||||
throw std::logic_error("eoTruncate: Cannot truncate to a larger size!\n");
|
||||
|
||||
_newgen.nth_element(_newsize);
|
||||
_newgen.resize(_newsize);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
EP truncation method (some global stochastic tournament + sort)
|
||||
Softer selective pressure than pure truncate
|
||||
*/
|
||||
template <class EOT> class eoEPReduce : public eoReduce<EOT>
|
||||
{
|
||||
public:
|
||||
typedef typename EOT::Fitness Fitness;
|
||||
|
||||
eoEPReduce(unsigned _t_size):
|
||||
t_size(_t_size)
|
||||
{
|
||||
if (t_size < 2)
|
||||
{ // warning, error?
|
||||
t_size = 2;
|
||||
}
|
||||
}
|
||||
|
||||
/// helper struct for comparing on pairs
|
||||
typedef pair<float, eoPop<EOT>::iterator> EPpair;
|
||||
struct Cmp {
|
||||
bool operator()(const EPpair a, const EPpair b) const
|
||||
{ return b.first < a.first; }
|
||||
};
|
||||
|
||||
|
||||
void operator()(eoPop<EOT>& _newgen, unsigned _newsize)
|
||||
{
|
||||
unsigned int presentSize = _newgen.size();
|
||||
if (presentSize == _newsize)
|
||||
return;
|
||||
if (presentSize < _newsize)
|
||||
throw std::logic_error("eoTruncate: Cannot truncate to a larger size!\n");
|
||||
vector<EPpair> scores(presentSize);
|
||||
for (unsigned i=0; i<presentSize; i++)
|
||||
{
|
||||
scores[i].second = _newgen.begin()+i;
|
||||
Fitness fit = _newgen[i].fitness();
|
||||
for (unsigned itourn = 0; itourn < t_size; ++itourn)
|
||||
{
|
||||
const EOT & competitor = _newgen[rng.random(presentSize)];
|
||||
if (fit > competitor.fitness())
|
||||
scores[i].first += 1;
|
||||
else if (fit == competitor.fitness())
|
||||
scores[i].first += 0.5;
|
||||
}
|
||||
}
|
||||
// now we have the scores
|
||||
typename vector<EPpair>::iterator it = scores.begin() + _newsize;
|
||||
std::nth_element(scores.begin(), it, scores.end(), Cmp());
|
||||
it = scores.begin() + _newsize; // just in case ???
|
||||
while (it < scores.end())
|
||||
_newgen.erase(it->second);
|
||||
}
|
||||
private:
|
||||
unsigned t_size;
|
||||
};
|
||||
|
||||
/** a truncate class that does not sort, but repeatidely kills the worse.
|
||||
To be used in SSGA-like replacements (e.g. see eoSSGAWorseReplacement)
|
||||
*/
|
||||
template <class EOT>
|
||||
class eoLinearTruncate : public eoReduce<EOT>
|
||||
{
|
||||
void operator()(eoPop<EOT>& _newgen, unsigned _newsize)
|
||||
{
|
||||
unsigned oldSize = _newgen.size();
|
||||
if (oldSize == _newsize)
|
||||
return;
|
||||
if (oldSize < _newsize)
|
||||
throw std::logic_error("eoLinearTruncate: Cannot truncate to a larger size!\n");
|
||||
for (unsigned i=0; i<oldSize - _newsize; i++)
|
||||
{
|
||||
eoPop<EOT>::iterator it = _newgen.it_worse_element();
|
||||
_newgen.erase(it);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/** a truncate class based on a repeated deterministic (reverse!) tournament
|
||||
To be used in SSGA-like replacements (e.g. see eoSSGADetTournamentReplacement)
|
||||
*/
|
||||
template <class EOT>
|
||||
class eoDetTournamentTruncate : public eoReduce<EOT>
|
||||
{
|
||||
public:
|
||||
eoDetTournamentTruncate(unsigned _t_size):
|
||||
t_size(_t_size)
|
||||
{
|
||||
if (t_size < 2)
|
||||
{
|
||||
cout << "Warning, Size for eoDetTournamentTruncate adjusted to 2\n";
|
||||
t_size = 2;
|
||||
}
|
||||
}
|
||||
|
||||
void operator()(eoPop<EOT>& _newgen, unsigned _newsize)
|
||||
{
|
||||
unsigned oldSize = _newgen.size();
|
||||
if (_newsize == 0)
|
||||
{
|
||||
_newgen.resize(0);
|
||||
return;
|
||||
}
|
||||
if (oldSize == _newsize)
|
||||
return;
|
||||
if (oldSize < _newsize)
|
||||
throw std::logic_error("eoDetTournamentTruncate: Cannot truncate to a larger size!\n");
|
||||
|
||||
// Now OK to erase some losers
|
||||
for (unsigned i=0; i<oldSize - _newsize; i++)
|
||||
{
|
||||
EOT & eo = inverse_deterministic_tournament<EOT>(_newgen, t_size);
|
||||
_newgen.erase(&eo);
|
||||
}
|
||||
}
|
||||
private:
|
||||
unsigned t_size;
|
||||
};
|
||||
|
||||
/** a truncate class based on a repeated deterministic (reverse!) tournament
|
||||
To be used in SSGA-like replacements (e.g. see eoSSGAStochTournamentReplacement)
|
||||
*/
|
||||
template <class EOT>
|
||||
class eoStochTournamentTruncate : public eoReduce<EOT>
|
||||
{
|
||||
public:
|
||||
eoStochTournamentTruncate(double _t_rate):
|
||||
t_rate(_t_rate)
|
||||
{
|
||||
if (t_rate <= 0.5)
|
||||
{
|
||||
cout << "Warning, Rate for eoStochTournamentTruncate adjusted to 0.51\n";
|
||||
t_rate = 0.51;
|
||||
}
|
||||
if (t_rate > 1)
|
||||
{
|
||||
cout << "Warning, Rate for eoStochTournamentTruncate adjusted to 1\n";
|
||||
t_rate = 1;
|
||||
}
|
||||
}
|
||||
|
||||
void operator()(eoPop<EOT>& _newgen, unsigned _newsize)
|
||||
{
|
||||
unsigned oldSize = _newgen.size();
|
||||
if (_newsize == 0)
|
||||
{
|
||||
_newgen.resize(0);
|
||||
return;
|
||||
}
|
||||
if (oldSize == _newsize)
|
||||
return;
|
||||
if (oldSize < _newsize)
|
||||
throw std::logic_error("eoStochTournamentTruncate: Cannot truncate to a larger size!\n");
|
||||
// Now OK to erase some losers
|
||||
for (unsigned i=0; i<oldSize - _newsize; i++)
|
||||
{
|
||||
EOT & eo = inverse_stochastic_tournament<EOT>(_newgen, t_rate);
|
||||
_newgen.erase(&eo);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
double t_rate;
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#endif //eoInsertion_h
|
||||
|
|
|
|||
119
eo/src/eoReduceMerge.h
Normal file
119
eo/src/eoReduceMerge.h
Normal file
|
|
@ -0,0 +1,119 @@
|
|||
/** -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*-
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
eoReduceMerge.h
|
||||
(c) Maarten Keijzer, Marc Schoenauer, GeNeura Team, 2000
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
Contact: todos@geneura.ugr.es, http://geneura.ugr.es
|
||||
Marc.Schoenauer@polytechnique.fr
|
||||
mkeijzer@dhi.dk
|
||||
*/
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef _eoReduceMerge_h
|
||||
#define _eoReduceMerge_h
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
#include <eoPop.h>
|
||||
#include <eoFunctor.h>
|
||||
#include <eoMerge.h>
|
||||
#include <eoReduce.h>
|
||||
#include <eoReplacement.h>
|
||||
#include <utils/eoHowMany.h>
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
/**
|
||||
eoReduceMerge: Replacement strategies that start by reducing the parents,
|
||||
then merge with the offspring
|
||||
|
||||
This is the way to do SSGA: the offspring gets inserted in the population
|
||||
even if it is worse than anybody else.
|
||||
|
||||
@classes: eoReduceMerge, eoSSGAWorseReplacement,
|
||||
eoSSGADetTournamentReplacement, eoSSGAStochTournamentReplacement
|
||||
*/
|
||||
|
||||
template <class EOT>
|
||||
class eoReduceMerge : public eoReplacement<EOT>
|
||||
{
|
||||
public:
|
||||
eoReduceMerge(eoReduce<EOT>& _reduce, eoMerge<EOT>& _merge) :
|
||||
reduce(_reduce), merge(_merge)
|
||||
{}
|
||||
|
||||
void operator()(eoPop<EOT>& _parents, eoPop<EOT>& _offspring)
|
||||
{
|
||||
if (_parents.size() < _offspring.size())
|
||||
throw std::logic_error("eoReduceMerge: More offspring than parents!\n");
|
||||
reduce(_parents, _parents.size() - _offspring.size());
|
||||
merge(_offspring, _parents);
|
||||
}
|
||||
|
||||
private :
|
||||
eoReduce<EOT>& reduce;
|
||||
eoMerge<EOT>& merge;
|
||||
};
|
||||
|
||||
/**
|
||||
SSGA replace worst. Is an eoReduceMerge.
|
||||
*/
|
||||
template <class EOT>
|
||||
class eoSSGAWorseReplacement : public eoReduceMerge<EOT>
|
||||
{
|
||||
public :
|
||||
eoSSGAWorseReplacement() : eoReduceMerge<EOT>(truncate, plus) {}
|
||||
|
||||
private :
|
||||
eoLinearTruncate<EOT> truncate;
|
||||
eoPlus<EOT> plus;
|
||||
};
|
||||
|
||||
/**
|
||||
SSGA deterministic tournament replacement. Is an eoReduceMerge.
|
||||
*/
|
||||
template <class EOT>
|
||||
class eoSSGADetTournamentReplacement : public eoReduceMerge<EOT>
|
||||
{
|
||||
public :
|
||||
eoSSGADetTournamentReplacement(unsigned _t_size) :
|
||||
eoReduceMerge<EOT>(truncate, plus), truncate(_t_size) {}
|
||||
|
||||
private :
|
||||
eoDetTournamentTruncate<EOT> truncate;
|
||||
eoPlus<EOT> plus;
|
||||
};
|
||||
|
||||
/** SSGA stochastic tournament replacement. Is an eoReduceMerge.
|
||||
It much cleaner to insert directly the offspring in the parent population,
|
||||
but it is NOT equivalent in case of more than 1 offspring as already
|
||||
replaced could be removed , which is not possible in the eoReduceMerge
|
||||
So what the heck ! */
|
||||
template <class EOT>
|
||||
class eoSSGAStochTournamentReplacement : public eoReduceMerge<EOT>
|
||||
{
|
||||
public :
|
||||
eoSSGAStochTournamentReplacement(double _t_rate) :
|
||||
eoReduceMerge<EOT>(truncate, plus), truncate(_t_rate) {}
|
||||
|
||||
private :
|
||||
eoStochTournamentTruncate<EOT> truncate;
|
||||
eoPlus<EOT> plus;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
-----------------------------------------------------------------------------
|
||||
eoReplacement.h
|
||||
(c) Maarten Keijzer, GeNeura Team, 2000
|
||||
(c) Maarten Keijzer, Marc Schoenauer, GeNeura Team, 2000
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
|
|
@ -18,7 +18,9 @@
|
|||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
Contact: todos@geneura.ugr.es, http://geneura.ugr.es
|
||||
Contact: todos@geneura.ugr.es, http://geneura.ugr.es
|
||||
Marc.Schoenauer@polytechnique.fr
|
||||
mkeijzer@dhi.dk
|
||||
*/
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
|
@ -31,81 +33,85 @@
|
|||
#include <eoFunctor.h>
|
||||
#include <eoMerge.h>
|
||||
#include <eoReduce.h>
|
||||
#include <utils/eoHowMany.h>
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
eoReplacement: High level strategy for creating a new generation
|
||||
from parents and offspring. This is a combination of eoMerge and eoReduce,
|
||||
so there is an implementation called eoMergeReduce that can be found below
|
||||
from parents and offspring.
|
||||
|
||||
@see eoMerge, eoReduce, eoMergeReduce
|
||||
The eoMergeReduce, combination of eoMerge and eoReduce, can be found
|
||||
in file eoMergeReduce.h
|
||||
|
||||
Removed the const before first argument: though it makes too many classes
|
||||
with the same interface, it allows to minimize the number of actual copies
|
||||
by choosing the right destination
|
||||
I also removed the enforced "swap" in the eoEasyAlgo and hence the generational
|
||||
replacement gets a class of its own that only does the swap (instead of the
|
||||
eoNoReplacement that did nothing, relying on the algo to swap popualtions).
|
||||
MS 12/12/2000
|
||||
|
||||
NOTE: the resulting population should always be in the first argument
|
||||
(replace parents by offspring)! The second argument can contain any rubbish
|
||||
|
||||
@see eoMerge, eoReduce, eoMergeReduce, eoReduceMerge
|
||||
|
||||
@classes eoReplacement, base (pure abstract) class
|
||||
eoGenerationalReplacement, as it says ...
|
||||
eoWeakElitistReplacement a wrapper to add elitism
|
||||
*/
|
||||
|
||||
/**
|
||||
eoReplacement: the base class for all replacementp functors
|
||||
*/
|
||||
template<class EOT>
|
||||
class eoReplacement : public eoBF<const eoPop<EOT>&, eoPop<EOT>&, void>
|
||||
class eoReplacement : public eoBF<eoPop<EOT>&, eoPop<EOT>&, void>
|
||||
{};
|
||||
|
||||
/**
|
||||
no replacement
|
||||
generational replacement == swap populations
|
||||
*/
|
||||
template <class EOT>
|
||||
class eoNoReplacement : public eoReplacement<EOT>
|
||||
class eoGenerationalReplacement : public eoReplacement<EOT>
|
||||
{
|
||||
public :
|
||||
/// do nothing
|
||||
void operator()(const eoPop<EOT>&, eoPop<EOT>&)
|
||||
{}
|
||||
/// swap
|
||||
void operator()(eoPop<EOT>& _parents, eoPop<EOT>& _offspring)
|
||||
{
|
||||
_parents.swap(_offspring);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
eoMergeReduce: special replacement strategy that is just an application of an embedded merge,
|
||||
followed by an embedded reduce
|
||||
/**
|
||||
eoWeakElitistReplacement: a wrapper for other replacement procedures.
|
||||
Copies in the new pop the best individual from the old pop,
|
||||
AFTER normal replacement, if the best of the new pop is worse than the best
|
||||
of the old pop. Removes the worse individual from the new pop.
|
||||
This could be changed by adding a selector there...
|
||||
*/
|
||||
template <class EOT>
|
||||
class eoMergeReduce : public eoReplacement<EOT>
|
||||
class eoWeakElitistReplacement : public eoReplacement<EOT>
|
||||
{
|
||||
public:
|
||||
eoMergeReduce(eoMerge<EOT>& _merge, eoReduce<EOT>& _reduce) :
|
||||
merge(_merge), reduce(_reduce)
|
||||
{}
|
||||
public :
|
||||
typedef typename EOT::Fitness Fitness;
|
||||
|
||||
void operator()(const eoPop<EOT>& _parents, eoPop<EOT>& _offspring)
|
||||
{
|
||||
merge(_parents, _offspring);
|
||||
reduce(_offspring, _parents.size());
|
||||
}
|
||||
// Ctor, takes an eoReplacement
|
||||
eoWeakElitistReplacement(eoReplacement<EOT> & _replace) :
|
||||
replace(_replace) {}
|
||||
|
||||
private :
|
||||
eoMerge<EOT>& merge;
|
||||
eoReduce<EOT>& reduce;
|
||||
/// do replacement
|
||||
void operator()(eoPop<EOT>& _pop, eoPop<EOT>& _offspring)
|
||||
{
|
||||
const EOT & oldChamp = _pop.best_element();
|
||||
replace(_pop, _offspring); // "normal" replacement, parents are the new
|
||||
if (_pop.best_element() < oldChamp) // need to do something
|
||||
{
|
||||
typename eoPop<EOT>::iterator itPoorGuy = _pop.it_worse_element();
|
||||
(*itPoorGuy) = oldChamp;
|
||||
}
|
||||
}
|
||||
private:
|
||||
eoReplacement<EOT> & replace;
|
||||
};
|
||||
|
||||
/**
|
||||
ES type of replacement strategy: first add parents to population, then truncate
|
||||
*/
|
||||
template <class EOT>
|
||||
class eoPlusReplacement : public eoMergeReduce<EOT>
|
||||
{
|
||||
public :
|
||||
eoPlusReplacement() : eoMergeReduce<EOT>(plus, truncate) {}
|
||||
|
||||
private :
|
||||
eoPlus<EOT> plus;
|
||||
eoTruncate<EOT> truncate;
|
||||
};
|
||||
|
||||
/**
|
||||
ES type of replacement strategy: ignore parents, truncate offspring
|
||||
*/
|
||||
template <class EOT>
|
||||
class eoCommaReplacement : public eoMergeReduce<EOT>
|
||||
{
|
||||
public :
|
||||
eoCommaReplacement() : eoMergeReduce<EOT>(no_elite, truncate) {}
|
||||
|
||||
private :
|
||||
eoNoElitism<EOT> no_elite;
|
||||
eoTruncate<EOT> truncate;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
|
|
|
|||
76
eo/src/eoSelectMany.h
Normal file
76
eo/src/eoSelectMany.h
Normal file
|
|
@ -0,0 +1,76 @@
|
|||
/** -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*-
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
eoSelectMany.h
|
||||
(c) Maarten Keijzer, Marc Schoenauer, GeNeura Team, 2000
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
Contact: todos@geneura.ugr.es, http://geneura.ugr.es
|
||||
Marc.Schoenauer@polytechnique.fr
|
||||
mkeijzer@dhi.dk
|
||||
*/
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef _eoSelectMany_h
|
||||
#define _eoSelectMany_h
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
#include <eoSelect.h>
|
||||
#include <eoSelectOne.h>
|
||||
#include <utils/eoHowMany.h>
|
||||
#include <math.h>
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
/** eoSelectMany selects many individuals using eoSelectOne as it's
|
||||
mechanism. Therefore eoSelectMany needs an eoSelectOne in its ctor
|
||||
|
||||
It will use an eoHowMnay to determine the number of guys to select,
|
||||
and push them to the back of the destination population.
|
||||
*/
|
||||
template<class EOT>
|
||||
class eoSelectMany : public eoSelect<EOT>
|
||||
{
|
||||
public:
|
||||
/// init
|
||||
eoSelectMany(eoSelectOne<EOT>& _select,
|
||||
double _rate, bool _interpret_as_rate = true)
|
||||
: select(_select), howMany(_rate, _interpret_as_rate) {}
|
||||
|
||||
/**
|
||||
The implementation repeatidly selects an individual
|
||||
|
||||
@param _source the source population
|
||||
@param _dest the resulting population (size of this population is the number of times eoSelectOne is called. It empties the destination and adds the selection into it)
|
||||
*/
|
||||
virtual void operator()(const eoPop<EOT>& _source, eoPop<EOT>& _dest)
|
||||
{
|
||||
unsigned target = howMany(_source.size());
|
||||
|
||||
_dest.resize(target);
|
||||
|
||||
select.setup(_source);
|
||||
|
||||
for (size_t i = 0; i < _dest.size(); ++i)
|
||||
_dest[i] = select(_source);
|
||||
}
|
||||
|
||||
private :
|
||||
eoSelectOne<EOT>& select;
|
||||
eoHowMany howMany;
|
||||
};
|
||||
|
||||
#endif
|
||||
72
eo/src/eoSelectNumber.h
Normal file
72
eo/src/eoSelectNumber.h
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
/** -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*-
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
eoSelectNumber.h
|
||||
(c) Maarten Keijzer, Marc Schoenauer, GeNeura Team, 2000
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
Contact: todos@geneura.ugr.es, http://geneura.ugr.es
|
||||
*/
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef _eoSelectNumber_h
|
||||
#define _eoSelectNumber_h
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
#include <eoSelect.h>
|
||||
#include <eoSelectOne.h>
|
||||
#include <math.h>
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
/** eoSelectNumber selects many individuals using eoSelectOne as it's
|
||||
mechanism. Therefore eoSelectNumber needs an eoSelectOne in its ctor
|
||||
|
||||
It will select a fixed number of individuals and pushes them to
|
||||
the back of the destination population.
|
||||
*/
|
||||
template<class EOT>
|
||||
class eoSelectNumber : public eoSelect<EOT>
|
||||
{
|
||||
public:
|
||||
/// init
|
||||
eoSelectNumber(eoSelectOne<EOT>& _select, unsigned _nb_to_select = 1)
|
||||
: select(_select), nb_to_select(_nb_to_select) {}
|
||||
|
||||
/**
|
||||
The implementation repeatidly selects an individual
|
||||
|
||||
@param _source the source population
|
||||
@param _dest the resulting population (size of this population is the number of times eoSelectOne is called. It empties the destination and adds the selection into it)
|
||||
*/
|
||||
virtual void operator()(const eoPop<EOT>& _source, eoPop<EOT>& _dest)
|
||||
{
|
||||
size_t target = static_cast<size_t>(nb_to_select);
|
||||
|
||||
_dest.resize(target);
|
||||
|
||||
select.setup(_source);
|
||||
|
||||
for (size_t i = 0; i < _dest.size(); ++i)
|
||||
_dest[i] = select(_source);
|
||||
}
|
||||
|
||||
private :
|
||||
eoSelectOne<EOT>& select;
|
||||
unsigned nb_to_select;
|
||||
};
|
||||
|
||||
#endif
|
||||
188
eo/src/eoSurviveAndDie.h
Normal file
188
eo/src/eoSurviveAndDie.h
Normal file
|
|
@ -0,0 +1,188 @@
|
|||
/** -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*-
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
eoSurviveAndDie.h
|
||||
(c) Maarten Keijzer, Marc Schoenauer, GeNeura Team, 2000
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
Contact: todos@geneura.ugr.es, http://geneura.ugr.es
|
||||
Marc.Schoenauer@polytechnique.fr
|
||||
mkeijzer@dhi.dk
|
||||
*/
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef _eoSurviveAndDie_h
|
||||
#define _eoSurviveAndDie_h
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
#include <eoPop.h>
|
||||
#include <eoFunctor.h>
|
||||
#include <eoMerge.h>
|
||||
#include <eoReduce.h>
|
||||
#include <utils/eoHowMany.h>
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
eoSurviveAndDie: takes a population (first argument),
|
||||
kills the ones that are to die,
|
||||
puts the ones that are to survive into the second argument
|
||||
removes them from the first pop argument
|
||||
|
||||
@classes: eoSurviveAndDie, eoDeterministicSurviveAndDie,
|
||||
eoDeterministicSaDReplacement
|
||||
*/
|
||||
|
||||
/** eoSurviveAndDie
|
||||
A pure abstract class, to store the howmany's
|
||||
*/
|
||||
template <class EOT>
|
||||
class eoSurviveAndDie : public eoBF<eoPop<EOT> &, eoPop<EOT> &, void>
|
||||
{
|
||||
public:
|
||||
eoSurviveAndDie(double _survive, double _die, bool _interpret_as_rate = true):
|
||||
howmanySurvive(_survive, _interpret_as_rate),
|
||||
howmanyDie(_die, _interpret_as_rate)
|
||||
{}
|
||||
|
||||
protected:
|
||||
eoHowMany howmanySurvive;
|
||||
eoHowMany howmanyDie;
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
an instance (theonly one as of today, Dec. 20, 2000) of an eoSurviveAndDie,
|
||||
that does everything deterministically
|
||||
|
||||
used in eoDeterministicSaDReplacement
|
||||
*/
|
||||
|
||||
template <class EOT>
|
||||
class eoDeterministicSurviveAndDie : public eoSurviveAndDie<EOT>
|
||||
{
|
||||
public:
|
||||
eoDeterministicSurviveAndDie(double _survive, double _die,
|
||||
bool _interpret_as_rate = true):
|
||||
eoSurviveAndDie<EOT>(_survive, _die, _interpret_as_rate)
|
||||
{}
|
||||
|
||||
void operator()(eoPop<EOT> & _pop, eoPop<EOT> & _luckyGuys)
|
||||
{
|
||||
unsigned pSize = _pop.size();
|
||||
unsigned nbSurvive = howmanySurvive(pSize);
|
||||
// first, save the best into _luckyGuys
|
||||
if (nbSurvive)
|
||||
{
|
||||
_pop.nth_element(nbSurvive);
|
||||
// copy best
|
||||
_luckyGuys.resize(nbSurvive);
|
||||
copy(_pop.begin(), _pop.begin()+nbSurvive, _luckyGuys.begin());
|
||||
// erase them from pop
|
||||
_pop.erase(_pop.begin(), _pop.begin()+nbSurvive);
|
||||
}
|
||||
unsigned nbRemaining = _pop.size();
|
||||
|
||||
// carefull, we can have a rate of 1 if we want to kill all remaining
|
||||
unsigned nbDie = min(howmanyDie(pSize), pSize-nbSurvive);
|
||||
if (nbDie > nbRemaining)
|
||||
throw std::logic_error("eoDeterministicSurviveAndDie: Too many to kill!\n");
|
||||
|
||||
if (!nbDie)
|
||||
{
|
||||
return;
|
||||
}
|
||||
// else
|
||||
// kill the worse nbDie
|
||||
_pop.nth_element(nbRemaining-nbDie);
|
||||
_pop.resize(nbRemaining-nbDie);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
eoDeterministicSaDReplacement: replacement strategy that is just, in sequence
|
||||
saves best and kill worse from parents
|
||||
+ saves best and kill worse from offspring
|
||||
+ merge remaining (neither save nor killed) parents and offspring
|
||||
+ reduce that merged population
|
||||
= returns reduced pop + best parents + best offspring
|
||||
|
||||
An obvious use is as strong elitist strategy,
|
||||
i.e. preserving best parents, and reducing
|
||||
(either offspring or parents+offspring)
|
||||
*/
|
||||
template <class EOT>
|
||||
class eoDeterministicSaDReplacement : public eoReplacement<EOT>
|
||||
{
|
||||
public:
|
||||
/** Constructor with reduce */
|
||||
eoDeterministicSaDReplacement(eoReduce<EOT>& _reduceGlobal,
|
||||
double _surviveParents, double _dieParents=0,
|
||||
double _surviveOffspring=0, double _dieOffspring=0,
|
||||
bool _interpret_as_rate = true ) :
|
||||
reduceGlobal(_reduceGlobal),
|
||||
sAdParents(_surviveParents, _dieParents, _interpret_as_rate),
|
||||
sAdOffspring(_surviveOffspring, _dieOffspring, _interpret_as_rate)
|
||||
{}
|
||||
|
||||
/** Constructor with default truncate used as reduce */
|
||||
eoDeterministicSaDReplacement(
|
||||
double _surviveParents, double _dieParents=0,
|
||||
double _surviveOffspring=0, double _dieOffspring=0,
|
||||
bool _interpret_as_rate = true ) :
|
||||
reduceGlobal(truncate),
|
||||
sAdParents(_surviveParents, _dieParents, _interpret_as_rate),
|
||||
sAdOffspring(_surviveOffspring, _dieOffspring, _interpret_as_rate)
|
||||
{}
|
||||
|
||||
void operator()(eoPop<EOT>& _parents, eoPop<EOT>& _offspring)
|
||||
{
|
||||
unsigned pSize = _parents.size(); // target number of individuals
|
||||
|
||||
eoPop<EOT> luckyParents; // to hold the absolute survivors
|
||||
sAdParents(_parents, luckyParents);
|
||||
|
||||
eoPop<EOT> luckyOffspring; // to hold the absolute survivors
|
||||
sAdOffspring(_offspring, luckyOffspring);
|
||||
|
||||
unsigned survivorSize = luckyOffspring.size() + luckyParents.size();
|
||||
if (survivorSize > pSize)
|
||||
throw std::logic_error("eoGeneralReplacement: More survivors than parents!\n");
|
||||
|
||||
plus(_parents, _offspring); // all that remain in _offspring
|
||||
|
||||
reduceGlobal(_offspring, pSize - survivorSize);
|
||||
plus(luckyParents, _offspring);
|
||||
plus(luckyOffspring, _offspring);
|
||||
|
||||
_parents.swap(_offspring);
|
||||
|
||||
}
|
||||
|
||||
private :
|
||||
eoReduce<EOT>& reduceGlobal;
|
||||
eoDeterministicSurviveAndDie<EOT> sAdParents;
|
||||
eoDeterministicSurviveAndDie<EOT> sAdOffspring;
|
||||
// plus helper (could be replaced by operator+= ???)
|
||||
eoPlus<EOT> plus;
|
||||
// the default reduce: deterministic truncation
|
||||
eoTruncate<EOT> truncate;
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
Loading…
Add table
Add a link
Reference in a new issue