Adjust code to perform to C++ standard according to gcc-3.4

interpretation... (Have not compiled/checked/changed paradisEO.)

That is, the current code compiles with gcc-3.4 and the checks
(besides t-MGE1bit) all pass.
This commit is contained in:
kuepper 2004-12-23 15:29:07 +00:00
commit 85a326c5e4
35 changed files with 1057 additions and 864 deletions

View file

@ -48,7 +48,7 @@ namespace std {
copy(v.begin(), v.end(), oi); copy(v.begin(), v.end(), oi);
return os; return os;
} }
istream& operator>>(istream& is, mlp::vector& v) istream& operator>>(istream& is, mlp::vector& v)
{ {
for (mlp::vector::iterator vi = v.begin() ; vi != v.end() ; vi++) { for (mlp::vector::iterator vi = v.begin() ; vi != v.end() ; vi++) {
@ -63,8 +63,8 @@ namespace mlp
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
// useful typedefs // useful typedefs
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
const real max_real = MLP_MAXFLOAT; const real max_real = MLP_MAXFLOAT;
const real min_real = MLP_MINFLOAT; const real min_real = MLP_MINFLOAT;
@ -72,38 +72,38 @@ namespace mlp
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
// sigmoid // sigmoid
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
real sigmoid(const real& x) real sigmoid(const real& x)
{ {
return 1.0 / (1.0 + exp(-x)); return 1.0 / (1.0 + exp(-x));
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
// neuron // neuron
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
struct neuron struct neuron
{ {
real bias; real bias;
vector weight; vector weight;
neuron(const unsigned& num_inputs = 0): weight(num_inputs) {} neuron(const unsigned& num_inputs = 0): weight(num_inputs) {}
void reset() void reset()
{ {
normal_generator<real> rnd(1.0); normal_generator<real> rnd(1.0);
bias = rnd(); bias = rnd();
generate(weight.begin(), weight.end(), rnd); generate(weight.begin(), weight.end(), rnd);
} }
real operator()(const vector& input) const real operator()(const vector& input) const
{ {
return sigmoid(bias + weight * input); return sigmoid(bias + weight * input);
} }
unsigned length() const { return weight.size() + 1; } unsigned length() const { return weight.size() + 1; }
void normalize() void normalize()
{ {
real n = sqrt(bias * bias + weight * weight); real n = sqrt(bias * bias + weight * weight);
@ -114,7 +114,7 @@ namespace mlp
void desaturate() void desaturate()
{ {
bias = -5.0 + 10.0 / (1.0 + exp(bias / -5.0)); bias = -5.0 + 10.0 / (1.0 + exp(bias / -5.0));
for (vector::iterator w = weight.begin(); w != weight.end(); ++w) for (vector::iterator w = weight.begin(); w != weight.end(); ++w)
*w = -5.0 + 10.0 / (1.0 + exp(*w / -5.0)); *w = -5.0 + 10.0 / (1.0 + exp(*w / -5.0));
} }
@ -127,7 +127,7 @@ namespace mlp
void perturb(double magnitude = 0.3, double probability = 1.0) void perturb(double magnitude = 0.3, double probability = 1.0)
{ {
for (vector::iterator w = weight.begin(); w != weight.end(); ++w) for (vector::iterator w = weight.begin(); w != weight.end(); ++w)
if ( probability >= 1.0 || drand48() < probability) if ( probability >= 1.0 || drand48() < probability)
perturb_num(*w, magnitude); perturb_num(*w, magnitude);
@ -143,7 +143,7 @@ namespace std {
{ {
return os << n.bias << " " << n.weight; return os << n.bias << " " << n.weight;
} }
istream& operator>>(istream& is, mlp::neuron& n) istream& operator>>(istream& is, mlp::neuron& n)
{ {
return is >> n.bias >> n.weight; return is >> n.bias >> n.weight;
@ -152,15 +152,15 @@ namespace std {
} }
namespace mlp { namespace mlp {
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
// layer // layer
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
class layer: public std::vector<neuron> class layer: public std::vector<neuron>
{ {
public: public:
layer(const unsigned& num_inputs = 0, const unsigned& num_neurons = 0): layer(const unsigned& num_inputs = 0, const unsigned& num_neurons = 0):
std::vector<neuron>(num_neurons, neuron(num_inputs)) {} std::vector<neuron>(num_neurons, neuron(num_inputs)) {}
void reset() void reset()
@ -169,11 +169,11 @@ namespace mlp {
for(iterator n = begin(); n != end(); ++n) for(iterator n = begin(); n != end(); ++n)
n->reset(); n->reset();
} }
vector operator()(const vector& input) const vector operator()(const vector& input) const
{ {
vector output(size()); vector output(size());
for(unsigned i = 0; i < output.size(); ++i) for(unsigned i = 0; i < output.size(); ++i)
output[i] = (*this)[i](input); output[i] = (*this)[i](input);
@ -212,7 +212,7 @@ namespace std {
copy(l.begin(), l.end(), oi); copy(l.begin(), l.end(), oi);
return os; return os;
} }
istream& operator>>(istream& is, mlp::layer& l) istream& operator>>(istream& is, mlp::layer& l)
{ {
for (mlp::layer::iterator li = l.begin() ; li != l.end() ; li++) { for (mlp::layer::iterator li = l.begin() ; li != l.end() ; li++) {
@ -224,7 +224,7 @@ namespace std {
} }
namespace mlp { namespace mlp {
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
// net // net
@ -234,7 +234,7 @@ namespace mlp {
{ {
public: public:
net(const unsigned& num_inputs = 0, net(const unsigned& num_inputs = 0,
const unsigned& num_outputs = 0, const unsigned& num_outputs = 0,
const std::vector<unsigned>& hidden = std::vector<unsigned>()) const std::vector<unsigned>& hidden = std::vector<unsigned>())
{ {
init(num_inputs,num_outputs,hidden); init(num_inputs,num_outputs,hidden);
@ -272,8 +272,8 @@ namespace mlp {
assert(c == '>'); assert(c == '>');
} }
void init( unsigned num_inputs, void init( unsigned num_inputs,
unsigned num_outputs, unsigned num_outputs,
const std::vector<unsigned>& hidden ) { const std::vector<unsigned>& hidden ) {
clear(); clear();
switch(hidden.size()) switch(hidden.size())
@ -317,21 +317,21 @@ namespace mlp {
unsigned num_inputs() const { return front().front().length() - 1; } unsigned num_inputs() const { return front().front().length() - 1; }
unsigned num_outputs() const { return back().size(); } unsigned num_outputs() const { return back().size(); }
unsigned num_hidden_layers() const { unsigned num_hidden_layers() const {
signed s = (signed) size() -1; signed s = (signed) size() -1;
return (s<0) ? 0 : s ; return (s<0) ? 0 : s ;
} }
unsigned length() unsigned length()
{ {
unsigned sum = 0; unsigned sum = 0;
for(iterator l = begin(); l != end(); ++l) for(iterator l = begin(); l != end(); ++l)
sum += l->length(); sum += l->length();
return sum; return sum;
} }
void normalize() void normalize()
{ {
@ -356,38 +356,38 @@ namespace mlp {
vector net::operator()(const vector& input) const vector net::operator()(const vector& input) const
{ {
vector tmp = input; vector tmp = input;
for(const_iterator l = begin(); l != end(); ++l) for(const_iterator l = begin(); l != end(); ++l)
tmp = (*l)(tmp); tmp = (*l)(tmp);
return tmp; return tmp;
} }
#endif #endif
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
// sample // sample
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
struct sample struct sample
{ {
vector input, output; vector input, output;
sample(unsigned input_size = 0, unsigned output_size = 0): sample(unsigned input_size = 0, unsigned output_size = 0):
input(input_size), output(output_size) {} input(input_size), output(output_size) {}
}; };
istream& operator>>(istream& is, sample& s) istream& operator>>(istream& is, sample& s)
{ {
return is >> s.input >> s.output; return is >> s.input >> s.output;
} }
ostream& operator<<(ostream& os, const sample& s) ostream& operator<<(ostream& os, const sample& s)
{ {
return os << s.input << " " << s.output; return os << s.input << " " << s.output;
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
// set // set
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
@ -395,8 +395,8 @@ namespace mlp {
class set: public std::vector<sample> class set: public std::vector<sample>
{ {
public: public:
set(unsigned input_size = 0, unsigned output_size = 0, set(unsigned input_size = 0, unsigned output_size = 0,
unsigned num_samples = 0): unsigned num_samples = 0):
std::vector<sample>(num_samples, sample(input_size, output_size)) {} std::vector<sample>(num_samples, sample(input_size, output_size)) {}
set(istream& is) : std::vector<sample>(0, sample(0, 0)) { set(istream& is) : std::vector<sample>(0, sample(0, 0)) {
@ -433,9 +433,9 @@ namespace mlp {
{ {
real sum = 0; real sum = 0;
for(net::const_reverse_iterator l1 = n1.rbegin(), l2 = n2.rbegin(); for(net::const_reverse_iterator l1 = n1.rbegin(), l2 = n2.rbegin();
l1 != n1.rend() && l2 != n2.rend(); ++l1, ++l2) l1 != n1.rend() && l2 != n2.rend(); ++l1, ++l2)
for(layer::const_iterator n1 = l1->begin(), n2 = l2->begin(); for(layer::const_iterator n1 = l1->begin(), n2 = l2->begin();
n1 != l1->end() && n2 != l2->end(); ++n1, ++n2) n1 != l1->end() && n2 != l2->end(); ++n1, ++n2)
{ {
real b = n1->bias - n2->bias; real b = n1->bias - n2->bias;
@ -462,6 +462,7 @@ namespace mlp {
#endif // mlp_h #endif // mlp_h
// Local Variables: // Local Variables:
// mode:C++ // mode:C++
// c-file-style: "Stroustrup"
// End: // End:

View file

@ -3,7 +3,7 @@
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
#include <stdlib.h> // EXIT_SUCCESS EXIT_FAILURE #include <stdlib.h> // EXIT_SUCCESS EXIT_FAILURE
#include <stdexcept> // exception #include <stdexcept> // exception
#include <iostream> // cerr cout #include <iostream> // cerr cout
#include <fstream> // ifstream #include <fstream> // ifstream
#include <string> // string #include <string> // string
@ -51,8 +51,8 @@ int main(int argc, char** argv)
} }
catch (exception& e) catch (exception& e)
{ {
cerr << argv[0] << ": " << e.what() << endl; cerr << argv[0] << ": " << e.what() << endl;
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
return 0; return 0;
@ -65,7 +65,7 @@ int main(int argc, char** argv)
void arg(int argc, char** argv) void arg(int argc, char** argv)
{ {
eoParser parser(argc, argv); eoParser parser(argc, argv);
parser.processParam(pop_size, "genetic operators"); parser.processParam(pop_size, "genetic operators");
parser.processParam(generations, "genetic operators"); parser.processParam(generations, "genetic operators");
parser.processParam(mut_rate, "genetic operators"); parser.processParam(mut_rate, "genetic operators");
@ -90,49 +90,49 @@ void ga()
// create population // create population
eoInitChrom init; eoInitChrom init;
eoPop<Chrom> pop(pop_size.value(), init); eoPop<Chrom> pop(pop_size.value(), init);
// evaluate population // evaluate population
eoEvalFuncPtr<Chrom> evaluator(eoChromEvaluator); eoEvalFuncPtr<Chrom> evaluator(eoChromEvaluator);
apply<Chrom>(evaluator, pop); apply<Chrom>(evaluator, pop);
// selector // selector
eoProportionalSelect<Chrom> select(pop); eoProportionalSelect<Chrom> select(pop);
// genetic operators // genetic operators
eoChromMutation mutation; eoChromMutation mutation;
eoChromXover xover; eoChromXover xover;
// stop condition // stop condition
eoGenContinue<Chrom> continuator1(generations.value()); eoGenContinue<Chrom> continuator1(generations.value());
eoFitContinue<Chrom> continuator2(solution.fitness()); eoFitContinue<Chrom> continuator2(solution.fitness());
eoCombinedContinue<Chrom> continuator(continuator1, continuator2); eoCombinedContinue<Chrom> continuator(continuator1, continuator2);
// checkpoint // checkpoint
eoCheckPoint<Chrom> checkpoint(continuator); eoCheckPoint<Chrom> checkpoint(continuator);
// monitor // monitor
eoStdoutMonitor monitor; eoStdoutMonitor monitor;
checkpoint.add(monitor); checkpoint.add(monitor);
// statistics // statistics
eoBestFitnessStat<Chrom> stats; eoBestFitnessStat<Chrom> stats;
checkpoint.add(stats); checkpoint.add(stats);
monitor.add(stats); monitor.add(stats);
// genetic algorithm // genetic algorithm
eoSGA<Chrom> sga(select, eoSGA<Chrom> sga(select,
xover, xover_rate.value(), xover, xover_rate.value(),
mutation, mut_rate.value(), mutation, mut_rate.value(),
evaluator, evaluator,
checkpoint); checkpoint);
sga(pop); sga(pop);
cout << "solution = " << solution << endl cout << "solution = " << solution << endl
<< "best = " << *max_element(pop.begin(), pop.end()) << endl; << "best = " << *max_element(pop.begin(), pop.end()) << endl;
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Local Variables: // Local Variables:
// mode:C++ // mode:C++
// End: // End:

View file

@ -18,7 +18,7 @@
Contact: todos@geneura.ugr.es, http://geneura.ugr.es Contact: todos@geneura.ugr.es, http://geneura.ugr.es
Marc.Schoenauer@polytechnique.fr Marc.Schoenauer@polytechnique.fr
CVS Info: $Date: 2003-02-27 19:26:44 $ $Header: /home/nojhan/dev/eodev/eodev_cvs/eo/contrib/MGE/eoVirus.h,v 1.2 2003-02-27 19:26:44 okoenig Exp $ $Author: okoenig $ CVS Info: $Date: 2004-12-23 15:29:07 $ $Header: /home/nojhan/dev/eodev/eodev_cvs/eo/contrib/MGE/eoVirus.h,v 1.3 2004-12-23 15:29:07 kuepper Exp $ $Author: kuepper $
*/ */
#ifndef eoVirus_h #ifndef eoVirus_h
@ -43,9 +43,15 @@ CVS Info: $Date: 2003-02-27 19:26:44 $ $Header: /home/nojhan/dev/eodev/eodev_cvs
\ingroup bitstring \ingroup bitstring
* based on STL's vector<bool> specialization. * based on STL's vector<bool> specialization.
*/ */
template <class FitT> class eoVirus: public eoBit<FitT> template <class FitT>
class eoVirus: public eoBit<FitT>
{ {
public: public:
using eoBit<FitT>::begin;
using eoBit<FitT>::end;
using eoBit<FitT>::size;
/** /**
* (Default) Constructor. * (Default) Constructor.
@ -110,3 +116,9 @@ template <class FitT> class eoVirus: public eoBit<FitT>
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
#endif //eoBit_h #endif //eoBit_h
// Local Variables:
// mode: C++
// c-file-style: "Stroustrup"
// End:

View file

@ -46,16 +46,14 @@
template <class EoType> template <class EoType>
class eoDominanceMap : public eoUF<const eoPop<EoType>&, void>, public std::vector<std::vector<bool> > class eoDominanceMap : public eoUF<const eoPop<EoType>&, void>, public std::vector<std::vector<bool> >
{ {
public : public:
/** /** Clears the map */
Clears the map void clear() {
*/ std::vector<std::vector<bool> >::clear();
void clear() #warning Is this correct? Was: "fitnesses.clear()"
{ fitness.clear();
std::vector<std::vector<bool> >::clear(); }
fitnesses.clear();
}
/** /**
Update or create the dominance map Update or create the dominance map

View file

@ -1,9 +1,9 @@
/** -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*- /** -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*-
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
eoLinearFitScaling.h eoLinearFitScaling.h
(c) GeNeura Team, 1998, Maarten Keijzer, Marc Schoenauer, 2001 (c) GeNeura Team, 1998, Maarten Keijzer, Marc Schoenauer, 2001
This library is free software; you can redistribute it and/or This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either License as published by the Free Software Foundation; either
@ -43,47 +43,48 @@ template <class EOT>
class eoLinearFitScaling : public eoPerf2Worth<EOT> // false: do not cache fitness class eoLinearFitScaling : public eoPerf2Worth<EOT> // false: do not cache fitness
{ {
public: public:
/* Ctor:
@param _p selective pressure (in (1,2]
@param _e exponent (1 == linear)
*/
eoLinearFitScaling(double _p=2.0):
pressure(_p) {}
/* COmputes the ranked fitness: fitnesses range in [m,M] using eoLinearFitScaling< EOT >::value;
with m=2-pressure/popSize and M=pressure/popSize.
in between, the progression depends on exponent (linear if 1).
*/
virtual void operator()(const eoPop<EOT>& _pop)
{
unsigned pSize =_pop.size();
// value() refers to the vector of worthes (we're in an eoParamvalue)
value().resize(pSize);
// best and worse fitnesses /* Ctor:
double bestFitness = static_cast<double> (_pop.best_element().fitness()); @param _p selective pressure (in (1,2])
// double worstFitness = static_cast<double> (_pop.worse_element().fitness()); @param _e exponent (1 == linear)
*/
eoLinearFitScaling(double _p=2.0)
: pressure(_p) {}
// average fitness /* COmputes the ranked fitness: fitnesses range in [m,M]
double sum=0.0; with m=2-pressure/popSize and M=pressure/popSize.
unsigned i; in between, the progression depends on exponent (linear if 1).
for (i=0; i<pSize; i++) */
sum += static_cast<double>(_pop[i].fitness()); virtual void operator()(const eoPop<EOT>& _pop) {
double averageFitness = sum/pSize; unsigned pSize =_pop.size();
// value() refers to the vector of worthes (we're in an eoParamvalue)
value().resize(pSize);
// the coefficients for linear scaling // best and worse fitnesses
double denom = pSize*(bestFitness - averageFitness); double bestFitness = static_cast<double> (_pop.best_element().fitness());
double alpha = (pressure-1)/denom; // double worstFitness = static_cast<double> (_pop.worse_element().fitness());
double beta = (bestFitness - pressure*averageFitness)/denom;
for (i=0; i<pSize; i++) // truncate to 0 // average fitness
{ double sum=0.0;
value()[i] = std::max(alpha*_pop[i].fitness()+beta, 0.0); unsigned i;
} for (i=0; i<pSize; i++)
sum += static_cast<double>(_pop[i].fitness());
double averageFitness = sum/pSize;
// the coefficients for linear scaling
double denom = pSize*(bestFitness - averageFitness);
double alpha = (pressure-1)/denom;
double beta = (bestFitness - pressure*averageFitness)/denom;
for (i=0; i<pSize; i++) { // truncate to 0
value()[i] = std::max(alpha*_pop[i].fitness()+beta, 0.0);
}
} }
private:
double pressure; // selective pressure private:
double pressure; // selective pressure
}; };

View file

@ -41,11 +41,14 @@
template <class EOT> template <class EOT>
class eoNDSorting : public eoPerf2WorthCached<EOT, double> class eoNDSorting : public eoPerf2WorthCached<EOT, double>
{ {
public : public:
eoNDSorting() : nasty_declone_flag_that_only_is_implemented_for_two_objectives(false) using eoNDSorting< EOT >::value;
{}
eoNDSorting()
: nasty_declone_flag_that_only_is_implemented_for_two_objectives(false)
{}
/** Pure virtual function that calculates the 'distance' for each element in the current front /** Pure virtual function that calculates the 'distance' for each element in the current front
Implement to create your own nondominated sorting algorithm. The size of the returned std::vector Implement to create your own nondominated sorting algorithm. The size of the returned std::vector
should be equal to the size of the current_front. should be equal to the size of the current_front.
@ -56,7 +59,7 @@ class eoNDSorting : public eoPerf2WorthCached<EOT, double>
{ {
// resize the worths beforehand // resize the worths beforehand
value().resize(_pop.size()); value().resize(_pop.size());
typedef typename EOT::Fitness::fitness_traits traits; typedef typename EOT::Fitness::fitness_traits traits;
switch (traits::nObjectives()) switch (traits::nObjectives())
@ -77,7 +80,7 @@ class eoNDSorting : public eoPerf2WorthCached<EOT, double>
} }
} }
} }
private : private :
/** used in fast nondominated sorting /** used in fast nondominated sorting
@ -90,7 +93,7 @@ private :
}; };
void one_objective(const eoPop<EOT>& _pop) void one_objective(const eoPop<EOT>& _pop)
{ {
unsigned i; unsigned i;
std::vector<DummyEO> tmp_pop; std::vector<DummyEO> tmp_pop;
tmp_pop.resize(_pop.size()); tmp_pop.resize(_pop.size());
@ -101,23 +104,23 @@ private :
tmp_pop[i].fitness(_pop[i].fitness()); tmp_pop[i].fitness(_pop[i].fitness());
tmp_pop[i].index = i; tmp_pop[i].index = i;
} }
std::sort(tmp_pop.begin(), tmp_pop.end(), std::greater<DummyEO>()); std::sort(tmp_pop.begin(), tmp_pop.end(), std::greater<DummyEO>());
for (i = 0; i < _pop.size(); ++i) for (i = 0; i < _pop.size(); ++i)
{ {
value()[tmp_pop[i].index] = _pop.size() - i; // set rank value()[tmp_pop[i].index] = _pop.size() - i; // set rank
} }
// no point in calculcating niche penalty, as every distinct fitness value has a distinct rank // no point in calculcating niche penalty, as every distinct fitness value has a distinct rank
} }
/** /**
* Optimization for two objectives. Makes the algorithm run in * Optimization for two objectives. Makes the algorithm run in
* complexity O(n log n) where n is the population size * complexity O(n log n) where n is the population size
* *
* This is the same complexity as for a single objective * This is the same complexity as for a single objective
* or truncation selection or sorting. * or truncation selection or sorting.
* *
* It will perform a sort on the two objectives seperately, * It will perform a sort on the two objectives seperately,
* and from the information on the ranks of the individuals on * and from the information on the ranks of the individuals on
@ -129,15 +132,15 @@ private :
* After that it is a simple exercise to calculate the distance * After that it is a simple exercise to calculate the distance
* penalty * penalty
*/ */
void two_objectives(const eoPop<EOT>& _pop) void two_objectives(const eoPop<EOT>& _pop)
{ {
unsigned i; unsigned i;
typedef typename EOT::Fitness::fitness_traits traits; typedef typename EOT::Fitness::fitness_traits traits;
assert(traits::nObjectives() == 2); assert(traits::nObjectives() == 2);
std::vector<unsigned> sort1(_pop.size()); // index into population sorted on first objective std::vector<unsigned> sort1(_pop.size()); // index into population sorted on first objective
for (i = 0; i < _pop.size(); ++i) for (i = 0; i < _pop.size(); ++i)
{ {
sort1[i] = i; sort1[i] = i;
@ -146,34 +149,34 @@ private :
std::sort(sort1.begin(), sort1.end(), Sorter(_pop)); std::sort(sort1.begin(), sort1.end(), Sorter(_pop));
// Ok, now the meat of the algorithm // Ok, now the meat of the algorithm
unsigned last_front = 0; unsigned last_front = 0;
double max1 = -1e+20; double max1 = -1e+20;
for (i = 0; i < _pop.size(); ++i) for (i = 0; i < _pop.size(); ++i)
{ {
max1 = std::max(max1, _pop[i].fitness()[1]); max1 = std::max(max1, _pop[i].fitness()[1]);
} }
max1 = max1 + 1.0; // add a bit to it so that it is a real upperbound max1 = max1 + 1.0; // add a bit to it so that it is a real upperbound
unsigned prev_front = 0; unsigned prev_front = 0;
std::vector<double> d; std::vector<double> d;
d.resize(_pop.size(), max1); // initialize with the value max1 everywhere d.resize(_pop.size(), max1); // initialize with the value max1 everywhere
std::vector<std::vector<unsigned> > fronts(_pop.size()); // to store indices into the front std::vector<std::vector<unsigned> > fronts(_pop.size()); // to store indices into the front
for (i = 0; i < _pop.size(); ++i) for (i = 0; i < _pop.size(); ++i)
{ {
unsigned index = sort1[i]; unsigned index = sort1[i];
// check for clones and delete them // check for clones and delete them
if (0 && i > 0) if (0 && i > 0)
{ {
unsigned prev = sort1[i-1]; unsigned prev = sort1[i-1];
if ( _pop[index].fitness() == _pop[prev].fitness()) if ( _pop[index].fitness() == _pop[prev].fitness())
{ // it's a clone, give it the worst rank! { // it's a clone, give it the worst rank!
if (nasty_declone_flag_that_only_is_implemented_for_two_objectives) if (nasty_declone_flag_that_only_is_implemented_for_two_objectives)
//declone //declone
fronts.back().push_back(index); fronts.back().push_back(index);
@ -182,32 +185,32 @@ private :
continue; continue;
} }
} }
double value2 = _pop[index].fitness()[1]; double value2 = _pop[index].fitness()[1];
if (traits::maximizing(1)) if (traits::maximizing(1))
value2 = max1 - value2; value2 = max1 - value2;
// perform binary search using std::upper_bound, a log n operation for each member // perform binary search using std::upper_bound, a log n operation for each member
std::vector<double>::iterator it = std::vector<double>::iterator it =
std::upper_bound(d.begin(), d.begin() + last_front, value2); std::upper_bound(d.begin(), d.begin() + last_front, value2);
unsigned front = unsigned(it - d.begin()); unsigned front = unsigned(it - d.begin());
if (front == last_front) ++last_front; if (front == last_front) ++last_front;
assert(it != d.end()); assert(it != d.end());
*it = value2; //update d *it = value2; //update d
fronts[front].push_back(index); // add it to the front fronts[front].push_back(index); // add it to the front
prev_front = front; prev_front = front;
} }
// ok, and finally the niche penalty // ok, and finally the niche penalty
for (i = 0; i < fronts.size(); ++i) for (i = 0; i < fronts.size(); ++i)
{ {
if (fronts[i].size() == 0) continue; if (fronts[i].size() == 0) continue;
// Now we have the indices to the current front in current_front, do the niching // Now we have the indices to the current front in current_front, do the niching
std::vector<double> niche_count = niche_penalty(fronts[i], _pop); std::vector<double> niche_count = niche_penalty(fronts[i], _pop);
@ -224,31 +227,31 @@ private :
{ {
value()[fronts[i][j]] = i + niche_count[j] / (max_niche + 1.); // divide by max_niche + 1 to ensure that this front does not overlap with the next value()[fronts[i][j]] = i + niche_count[j] / (max_niche + 1.); // divide by max_niche + 1 to ensure that this front does not overlap with the next
} }
} }
// invert ranks to obtain a 'bigger is better' score // invert ranks to obtain a 'bigger is better' score
rank_to_worth(); rank_to_worth();
} }
class Sorter class Sorter
{ {
public: public:
Sorter(const eoPop<EOT>& _pop) : pop(_pop) {} Sorter(const eoPop<EOT>& _pop) : pop(_pop) {}
bool operator()(unsigned i, unsigned j) const bool operator()(unsigned i, unsigned j) const
{ {
typedef typename EOT::Fitness::fitness_traits traits; typedef typename EOT::Fitness::fitness_traits traits;
double diff = pop[i].fitness()[0] - pop[j].fitness()[0]; double diff = pop[i].fitness()[0] - pop[j].fitness()[0];
if (fabs(diff) < traits::tol()) if (fabs(diff) < traits::tol())
{ {
diff = pop[i].fitness()[1] - pop[j].fitness()[1]; diff = pop[i].fitness()[1] - pop[j].fitness()[1];
if (fabs(diff) < traits::tol()) if (fabs(diff) < traits::tol())
return false; return false;
if (traits::maximizing(1)) if (traits::maximizing(1))
return diff > 0.; return diff > 0.;
return diff < 0.; return diff < 0.;
@ -261,7 +264,7 @@ private :
const eoPop<EOT>& pop; const eoPop<EOT>& pop;
}; };
void m_objectives(const eoPop<EOT>& _pop) void m_objectives(const eoPop<EOT>& _pop)
{ {
unsigned i; unsigned i;
@ -348,7 +351,7 @@ private :
rank_to_worth(); rank_to_worth();
} }
void rank_to_worth() void rank_to_worth()
{ {
// now all that's left to do is to transform lower rank into higher worth // now all that's left to do is to transform lower rank into higher worth
@ -356,7 +359,7 @@ private :
// but make sure it's an integer upper bound, so that all ranks inside the highest integer are the front // but make sure it's an integer upper bound, so that all ranks inside the highest integer are the front
max_fitness = ceil(max_fitness); max_fitness = ceil(max_fitness);
for (unsigned i = 0; i < value().size(); ++i) for (unsigned i = 0; i < value().size(); ++i)
{ {
value()[i] = max_fitness - value()[i]; value()[i] = max_fitness - value()[i];
@ -409,21 +412,26 @@ public :
double nicheSize; double nicheSize;
}; };
/** /** @brief Fast Elitist Non-Dominant Sorting Genetic Algorithm
Adapted from Deb, Agrawal, Pratab and Meyarivan: A Fast Elitist Non-Dominant Sorting Genetic Algorithm for MultiObjective Optimization: NSGA-II
KanGAL Report No. 200001
Note that this class does not do the sorting per se, but the sorting of it worth_std::vector will give the right order Adapted from Deb, Agrawal, Pratab and Meyarivan: A Fast Elitist
Non-Dominant Sorting Genetic Algorithm for MultiObjective
Optimization: NSGA-II KanGAL Report No. 200001
The crowding distance is calculated as the sum of the distances to the nearest neighbours. As we need to return the Note that this class does not do the sorting per se, but the sorting
penalty value, we have to invert that and invert it again in the base class, but such is life, sigh of it worth_std::vector will give the right order
The crowding distance is calculated as the sum of the distances to
the nearest neighbours. As we need to return the penalty value, we
have to invert that and invert it again in the base class, but such
is life, sigh
*/ */
template <class EOT> template <class EOT>
class eoNDSorting_II : public eoNDSorting<EOT> class eoNDSorting_II : public eoNDSorting<EOT>
{ {
public: public:
typedef std::pair<double, unsigned> double_index_pair; typedef std::pair<double, unsigned> double_index_pair;
class compare_nodes class compare_nodes
{ {
@ -441,7 +449,7 @@ class eoNDSorting_II : public eoNDSorting<EOT>
unsigned i; unsigned i;
std::vector<double> niche_count(_cf.size(), 0.); std::vector<double> niche_count(_cf.size(), 0.);
unsigned nObjectives = traits::nObjectives(); //_pop[_cf[0]].fitness().size(); unsigned nObjectives = traits::nObjectives(); //_pop[_cf[0]].fitness().size();
for (unsigned o = 0; o < nObjectives; ++o) for (unsigned o = 0; o < nObjectives; ++o)

View file

@ -87,55 +87,57 @@ class eoOpContainer : public eoGenOp<EOT>
template <class EOT> template <class EOT>
class eoSequentialOp : public eoOpContainer<EOT> class eoSequentialOp : public eoOpContainer<EOT>
{ {
public : public:
typedef unsigned position_type;
using eoOpContainer< EOT >::ops;
using eoOpContainer< EOT >::rates;
typedef unsigned position_type;
void apply(eoPopulator<EOT>& _pop) void apply(eoPopulator<EOT>& _pop) {
{ position_type pos = _pop.tellp();
position_type pos = _pop.tellp(); for (size_t i = 0; i < rates.size(); ++i) {
_pop.seekp(pos);
do {
if (eo::rng.flip(rates[i])) {
// try
// {
// apply it to all the guys in the todo std::list
(*ops[i])(_pop);
// }
// check for out of individuals and do nothing with that...
// catch(eoPopulator<EOT>::OutOfIndividuals&)
// {
// std::cout << "Warning: not enough individuals to handle\n";
// return ;
// }
}
for (size_t i = 0; i < rates.size(); ++i) if (!_pop.exhausted())
{ ++_pop;
_pop.seekp(pos); }
while (!_pop.exhausted());
do
{
if (eo::rng.flip(rates[i]))
{
// try
// {
// apply it to all the guys in the todo std::list
(*ops[i])(_pop);
// }
// check for out of individuals and do nothing with that...
// catch(eoPopulator<EOT>::OutOfIndividuals&)
// {
// std::cout << "Warning: not enough individuals to handle\n";
// return ;
// }
}
if (!_pop.exhausted())
++_pop;
} }
while (!_pop.exhausted()); }
} virtual std::string className() const {return "SequentialOp";}
}
virtual std::string className() const {return "SequentialOp";}
private : private:
std::vector<size_t> to_apply; std::vector<size_t> to_apply;
std::vector<size_t> production; std::vector<size_t> production;
}; };
/** The proportional versions: easy! */ /** The proportional versions: easy! */
template <class EOT> template <class EOT>
class eoProportionalOp : public eoOpContainer<EOT> class eoProportionalOp : public eoOpContainer<EOT>
{ {
public : public:
using eoOpContainer< EOT >::ops;
using eoOpContainer< EOT >::rates;
void apply(eoPopulator<EOT>& _pop) void apply(eoPopulator<EOT>& _pop)
{ {

View file

@ -39,10 +39,13 @@
template <class EOT> template <class EOT>
class eoParetoRanking : public eoPerf2WorthCached<EOT, double> class eoParetoRanking : public eoPerf2WorthCached<EOT, double>
{ {
public : public:
eoParetoRanking(eoDominanceMap<EOT>& _dominanceMap) : using eoParetoRanking< EOT>::value;
eoPerf2WorthCached<EOT, double>(), dominanceMap(_dominanceMap) {}
eoParetoRanking(eoDominanceMap<EOT>& _dominanceMap)
: eoPerf2WorthCached<EOT, double>(), dominanceMap(_dominanceMap)
{}
void calculate_worths(const eoPop<EOT>& _pop) void calculate_worths(const eoPop<EOT>& _pop)
{ {

View file

@ -35,20 +35,24 @@
#include <vector> #include <vector>
#include <string> #include <string>
/** Base class to transform raw fitnesses into fitness for selection /** @brief Base class to transform raw fitnesses into fitness for selection
@see eoSelectFromWorth @see eoSelectFromWorth
*/ */
template <class EOT, class WorthT = double> template <class EOT, class WorthT = double>
class eoPerf2Worth : public eoUF<const eoPop<EOT>&, void>, public eoValueParam<std::vector<WorthT> > class eoPerf2Worth : public eoUF<const eoPop<EOT>&, void>, public eoValueParam<std::vector<WorthT> >
{ {
public: public:
eoPerf2Worth(std::string _description = "Worths"):eoValueParam<std::vector<WorthT> >(std::vector<WorthT>(0),
_description) {}
/** using eoPerf2Worth<EOT, WorthT>::value;
Sort population according to worth, will keep the worths and fitness_cache in sync with the population.
*/ /** @brief default constructor */
eoPerf2Worth(std::string _description = "Worths")
: eoValueParam<std::vector<WorthT> >(std::vector<WorthT>(0), _description)
{}
/** Sort population according to worth, will keep the worths and
fitness_cache in sync with the population. */
virtual void sort_pop(eoPop<EOT>& _pop) virtual void sort_pop(eoPop<EOT>& _pop)
{ // start with a std::vector of indices { // start with a std::vector of indices
std::vector<unsigned> indices(_pop.size()); std::vector<unsigned> indices(_pop.size());
@ -75,28 +79,28 @@ class eoPerf2Worth : public eoUF<const eoPop<EOT>&, void>, public eoValueParam<s
std::swap(value(), tmp_worths); std::swap(value(), tmp_worths);
} }
/** helper class used to sort indices into populations/worths /** helper class used to sort indices into populations/worths */
*/ class compare_worth
class compare_worth
{
public :
compare_worth(const std::vector<WorthT>& _worths) : worths(_worths) {}
bool operator()(unsigned a, unsigned b) const
{ {
return worths[b] < worths[a]; // sort in descending (!) order public:
}
private : compare_worth(const std::vector<WorthT>& _worths) : worths(_worths) {}
const std::vector<WorthT>& worths; bool operator()(unsigned a, unsigned b) const {
}; return worths[b] < worths[a]; // sort in descending (!) order
}
virtual void resize(eoPop<EOT>& _pop, unsigned sz) private:
{
_pop.resize(sz); const std::vector<WorthT>& worths;
value().resize(sz); };
}
virtual void resize(eoPop<EOT>& _pop, unsigned sz) {
_pop.resize(sz);
value().resize(sz);
};
}; };
@ -106,8 +110,11 @@ Perf2Worth with fitness cache
template <class EOT, class WorthT = typename EOT::Fitness> template <class EOT, class WorthT = typename EOT::Fitness>
class eoPerf2WorthCached : public eoPerf2Worth<EOT, WorthT> class eoPerf2WorthCached : public eoPerf2Worth<EOT, WorthT>
{ {
public: public:
eoPerf2WorthCached(std::string _description = "Worths") : eoPerf2Worth<EOT, WorthT>(_description) {}
using eoPerf2Worth<EOT, WorthT>::value;
eoPerf2WorthCached(std::string _description = "Worths") : eoPerf2Worth<EOT, WorthT>(_description) {}
/** /**
@ -164,7 +171,7 @@ class eoPerf2WorthCached : public eoPerf2Worth<EOT, WorthT>
indices[i] = i; indices[i] = i;
} }
std::sort(indices.begin(), indices.end(), eoPerf2Worth<EOT,WorthT>::compare_worth(value())); std::sort(indices.begin(), indices.end(), compare_worth(value()));
eoPop<EOT> tmp_pop; eoPop<EOT> tmp_pop;
tmp_pop.resize(_pop.size()); tmp_pop.resize(_pop.size());
@ -216,22 +223,25 @@ class eoPerf2WorthCached : public eoPerf2Worth<EOT, WorthT>
std::vector <typename EOT::Fitness> fitness_cache; std::vector <typename EOT::Fitness> fitness_cache;
}; };
/**
A dummy perf2worth, just in case you need it
*/ /** A dummy perf2worth, just in case you need it */
template <class EOT> template <class EOT>
class eoNoPerf2Worth : public eoPerf2Worth<EOT, typename EOT::Fitness> class eoNoPerf2Worth : public eoPerf2Worth<EOT, typename EOT::Fitness>
{ {
public: public:
using eoValueParam< EOT >::value;
// default behaviour, just copy fitnesses // default behaviour, just copy fitnesses
void operator()(const eoPop<EOT>& _pop) void operator()(const eoPop<EOT>& _pop) {
{ unsigned i;
unsigned i; value().resize(_pop.size());
value.resize(_pop.size()); for (i = 0; i < _pop.size(); ++i)
for (i = 0; i < _pop.size(); ++i) value()[i]=_pop[i];
value()[i]=_pop[i];
} }
}; };
#endif #endif

View file

@ -1,9 +1,9 @@
// -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*- // -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*-
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// eoPopulator.h // eoPopulator.h
// (c) Maarten Keijzer and Marc Schoenauer, 2001 // (c) Maarten Keijzer and Marc Schoenauer, 2001
/* /*
This library is free software; you can redistribute it and/or This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either License as published by the Free Software Foundation; either
@ -120,15 +120,15 @@ public :
*/ */
virtual const EOT& select() = 0; virtual const EOT& select() = 0;
protected : protected:
eoPop<EOT>& dest; eoPop<EOT>& dest;
typename eoPop<EOT>::iterator current; typename eoPop<EOT>::iterator current;
const eoPop<EOT>& src; const eoPop<EOT>& src;
private : private:
void get_next()
{ void get_next() {
if (current == dest.end()) if(current == dest.end())
{ // get new individual from derived class select() { // get new individual from derived class select()
dest.push_back(select()); dest.push_back(select());
current = dest.end(); current = dest.end();
@ -143,31 +143,34 @@ private :
}; };
/** SeqPopulator: an eoPopulator that sequentially goes through the population /** SeqPopulator: an eoPopulator that sequentially goes through the
is supposed to be used after a batch select of a whole bunch or genitors population is supposed to be used after a batch select of a whole
*/ bunch or genitors
*/
template <class EOT> template <class EOT>
class eoSeqPopulator : public eoPopulator<EOT> class eoSeqPopulator : public eoPopulator<EOT>
{ {
public : public:
eoSeqPopulator(const eoPop<EOT>& _pop, eoPop<EOT>& _dest) : eoSeqPopulator(const eoPop<EOT>& _pop, eoPop<EOT>& _dest) :
eoPopulator<EOT>(_pop, _dest), current(0) {} eoPopulator<EOT>(_pop, _dest), current(0) {}
/** the select method simply returns next individual in the src pop */ /** the select method simply returns next individual in the src pop */
const EOT& select(void) const EOT& select(void) {
{ if(current >= eoPopulator< EOT >::src.size()) {
if (current >= src.size()) throw OutOfIndividuals();
{ }
throw OutOfIndividuals();
}
const EOT& res = src[current++]; const EOT& res = eoPopulator< EOT >::src[current++];
return res; return res;
} }
private :
unsigned current; private:
struct OutOfIndividuals {};
unsigned current;
}; };
@ -178,20 +181,22 @@ template <class EOT>
class eoSelectivePopulator : public eoPopulator<EOT> class eoSelectivePopulator : public eoPopulator<EOT>
{ {
public : public :
eoSelectivePopulator(const eoPop<EOT>& _pop, eoPop<EOT>& _dest, eoSelectOne<EOT>& _sel)
: eoPopulator<EOT>(_pop, _dest), sel(_sel) using eoPopulator< EOT >::src;
{
sel.setup(_pop); eoSelectivePopulator(const eoPop<EOT>& _pop, eoPop<EOT>& _dest, eoSelectOne<EOT>& _sel)
: eoPopulator<EOT>(_pop, _dest), sel(_sel)
{ sel.setup(_pop); };
/** the select method actually selects one guy from the src pop */
const EOT& select() {
return sel(src);
} }
/** the select method actually selects one guy from the src pop */
const EOT& select()
{
return sel(src);
}
private : private:
eoSelectOne<EOT>& sel;
eoSelectOne<EOT>& sel;
}; };
#endif #endif

View file

@ -38,6 +38,9 @@ template <class EOT>
class eoRanking : public eoPerf2Worth<EOT> // false: do not cache fitness class eoRanking : public eoPerf2Worth<EOT> // false: do not cache fitness
{ {
public: public:
using eoRanking< EOT >::value;
/* Ctor: /* Ctor:
@param _p selective pressure (in (1,2] @param _p selective pressure (in (1,2]
@param _e exponent (1 == linear) @param _e exponent (1 == linear)
@ -91,7 +94,7 @@ public:
{ {
int which = lookfor(rank[i], _pop); int which = lookfor(rank[i], _pop);
// value in in [0,1] // value in in [0,1]
double tmp = ((double)(pSize-i))/pSize; double tmp = ((double)(pSize-i))/pSize;
// to the exponent, and back to [m,M] // to the exponent, and back to [m,M]
value()[which] = gamma*pow(tmp, exponent)+beta; value()[which] = gamma*pow(tmp, exponent)+beta;
} }

View file

@ -11,16 +11,16 @@
modify it under the terms of the GNU Lesser General Public modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version. version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful, This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details. Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 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@inria.fr Marc.Schoenauer@inria.fr
mak@dhi.dk mak@dhi.dk
@ -43,33 +43,33 @@
class eoScalarFitnessAssembledTraits{ class eoScalarFitnessAssembledTraits{
public: public:
typedef std::vector<std::string>::size_type size_type; typedef std::vector<std::string>::size_type size_type;
static void setDescription( size_type _idx, std::string _descr ) { static void setDescription( size_type _idx, std::string _descr ) {
if ( _idx < TermDescriptions.size() ) if ( _idx < TermDescriptions.size() )
TermDescriptions[_idx] = _descr; TermDescriptions[_idx] = _descr;
else{ else{
TermDescriptions.resize(_idx, "Unnamed variable" ); TermDescriptions.resize(_idx, "Unnamed variable" );
TermDescriptions[_idx] = _descr; TermDescriptions[_idx] = _descr;
} }
} }
static std::string getDescription( size_type _idx) { static std::string getDescription( size_type _idx) {
if ( _idx < TermDescriptions.size() ) if ( _idx < TermDescriptions.size() )
return TermDescriptions[_idx ]; return TermDescriptions[_idx ];
else else
return "Unnamed Variable"; return "Unnamed Variable";
} }
static void resize( size_type _n, const std::string& _descr) { static void resize( size_type _n, const std::string& _descr) {
TermDescriptions.resize(_n, _descr); TermDescriptions.resize(_n, _descr);
} }
static size_type size() { return TermDescriptions.size(); } static size_type size() { return TermDescriptions.size(); }
static std::vector<std::string> getDescriptionVector() { return TermDescriptions; } static std::vector<std::string> getDescriptionVector() { return TermDescriptions; }
private: private:
static std::vector<std::string> TermDescriptions; static std::vector<std::string> TermDescriptions;
}; };
@ -80,7 +80,7 @@ private:
maximizing (using less<ScalarType>) or minimizing (using greater<ScalarType>). maximizing (using less<ScalarType>) or minimizing (using greater<ScalarType>).
- Stores all kinda different values met during fitness assembly, to be defined in eoEvalFunc. - Stores all kinda different values met during fitness assembly, to be defined in eoEvalFunc.
- It overrides operator<() to use the Compare template argument. - It overrides operator<() to use the Compare template argument.
- Suitable constructors and assignments and casts are defined to work - Suitable constructors and assignments and casts are defined to work
with this quantity as if it were a ScalarType. with this quantity as if it were a ScalarType.
- Global fitness value is stored as first element in the vector - Global fitness value is stored as first element in the vector
*/ */
@ -88,26 +88,32 @@ template <class ScalarType, class Compare, class FitnessTraits >
class eoScalarFitnessAssembled : public std::vector<ScalarType> { class eoScalarFitnessAssembled : public std::vector<ScalarType> {
public: public:
using std::vector< ScalarType >::empty;
using std::vector< ScalarType >::front;
using std::vector< ScalarType >::size;
typedef typename std::vector<ScalarType> baseVector; typedef typename std::vector<ScalarType> baseVector;
typedef typename baseVector::size_type size_type; typedef typename baseVector::size_type size_type;
// Basic constructors and assignments // Basic constructors and assignments
eoScalarFitnessAssembled() eoScalarFitnessAssembled()
: baseVector( FitnessTraits::size() ), : baseVector( FitnessTraits::size() ),
feasible(true), failed(false), msg("") feasible(true), failed(false), msg("")
{} {}
eoScalarFitnessAssembled( size_type _n, eoScalarFitnessAssembled( size_type _n,
const ScalarType& _val, const ScalarType& _val,
const std::string& _descr="Unnamed variable" ) const std::string& _descr="Unnamed variable" )
: baseVector(_n, _val), : baseVector(_n, _val),
feasible(true), failed(false), msg("") feasible(true), failed(false), msg("")
{ {
if ( _n > FitnessTraits::size() ) if ( _n > FitnessTraits::size() )
FitnessTraits::resize(_n, _descr); FitnessTraits::resize(_n, _descr);
} }
eoScalarFitnessAssembled( const eoScalarFitnessAssembled& other) eoScalarFitnessAssembled( const eoScalarFitnessAssembled& other)
: baseVector( other ), : baseVector( other ),
feasible(other.feasible), feasible(other.feasible),
failed(other.failed), failed(other.failed),
@ -121,27 +127,26 @@ public:
msg = other.msg; msg = other.msg;
return *this; return *this;
} }
// Constructors and assignments to work with scalar type // Constructors and assignments to work with scalar type
eoScalarFitnessAssembled( const ScalarType& v ) eoScalarFitnessAssembled( const ScalarType& v )
: baseVector( 1, v ), : baseVector( 1, v ),
feasible(true), failed(false), msg("") feasible(true), failed(false), msg("")
{} {}
eoScalarFitnessAssembled& operator=( const ScalarType& v ) { eoScalarFitnessAssembled& operator=( const ScalarType& v ) {
if ( empty() ) if( empty() )
push_back( v ); push_back( v );
else else
front() = v; front() = v;
return *this;
return *this;
} }
//! Overload push_back() //! Overload push_back()
void push_back(const ScalarType& _val ){ void push_back(const ScalarType& _val ){
baseVector::push_back( _val ); baseVector::push_back( _val );
if ( size() > FitnessTraits::size() ) if ( size() > FitnessTraits::size() )
FitnessTraits::setDescription( size()-1, "Unnamed variable"); FitnessTraits::setDescription( size()-1, "Unnamed variable");
} }
@ -156,46 +161,46 @@ public:
baseVector::resize(_n, _val); baseVector::resize(_n, _val);
FitnessTraits::resize(_n, _descr); FitnessTraits::resize(_n, _descr);
} }
//! Set description //! Set description
void setDescription( size_type _idx, std::string _descr ) { void setDescription( size_type _idx, std::string _descr ) {
FitnessTraits::setDescription( _idx, _descr ); FitnessTraits::setDescription( _idx, _descr );
} }
//! Get description //! Get description
std::string getDescription( size_type _idx ){ return FitnessTraits::getDescription( _idx ); } std::string getDescription( size_type _idx ){ return FitnessTraits::getDescription( _idx ); }
//! Get vector with descriptions //! Get vector with descriptions
std::vector<std::string> getDescriptionVector() { return FitnessTraits::getDescriptionVector(); } std::vector<std::string> getDescriptionVector() { return FitnessTraits::getDescriptionVector(); }
//! Feasibility boolean //! Feasibility boolean
/** /**
* Can be specified anywhere in fitness evaluation * Can be specified anywhere in fitness evaluation
* as an indicator if the individual is in some feasible range. * as an indicator if the individual is in some feasible range.
*/ */
bool feasible; bool feasible;
//! Failed boolean //! Failed boolean
/** /**
* Can be specified anywhere in fitness evaluation * Can be specified anywhere in fitness evaluation
* as an indicator if the evaluation of the individual failed * as an indicator if the evaluation of the individual failed
*/ */
bool failed; bool failed;
//! Message //! Message
/** /**
* Can be specified anywhere in fitness evaluation. * Can be specified anywhere in fitness evaluation.
* Typically used to store some sort of error messages, if evaluation of individual failed. * Typically used to store some sort of error messages, if evaluation of individual failed.
*/ */
std::string msg; std::string msg;
// Scalar type access // Scalar type access
operator ScalarType(void) const { operator ScalarType(void) const {
if ( empty() ) if ( empty() )
return 0.0; return 0.0;
else else
return front(); return front();
} }
//! Print term values and descriptions //! Print term values and descriptions
@ -205,11 +210,11 @@ public:
} }
// Comparison, using less by default // Comparison, using less by default
bool operator<(const eoScalarFitnessAssembled& other) const{ bool operator<(const eoScalarFitnessAssembled& other) const{
if ( empty() || other.empty() ) if ( empty() || other.empty() )
return false; return false;
else else
return Compare()( front() , other.front() ); return Compare()( front() , other.front() );
} }
// implementation of the other operators // implementation of the other operators
@ -237,10 +242,10 @@ std::ostream& operator<<(std::ostream& os, const eoScalarFitnessAssembled<F, Cmp
{ {
for (unsigned i=0; i < f.size(); ++i) for (unsigned i=0; i < f.size(); ++i)
os << f[i] << " "; os << f[i] << " ";
os << f.feasible << " "; os << f.feasible << " ";
os << f.failed << " "; os << f.failed << " ";
return os; return os;
} }
@ -252,10 +257,10 @@ std::istream& operator>>(std::istream& is, eoScalarFitnessAssembled<F, Cmp, Fitn
is >> value; is >> value;
f[i] = value; f[i] = value;
} }
is >> f.feasible; is >> f.feasible;
is >> f.failed; is >> f.failed;
return is; return is;
} }

View file

@ -1,9 +1,9 @@
/** -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*- /** -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*-
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
eoSelectFromWorth.h eoSelectFromWorth.h
(c) Maarten Keijzer, Marc Schoenauer, 2001 (c) Maarten Keijzer, Marc Schoenauer, 2001
This library is free software; you can redistribute it and/or This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either License as published by the Free Software Foundation; either
@ -33,9 +33,9 @@
#include <utils/selectors.h> #include <utils/selectors.h>
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
/** selects one element from a population (is an eoSelectOne) /** selects one element from a population (is an eoSelectOne)
but the selection is based on a std::vector of Worth that is different but the selection is based on a std::vector of Worth that is different
from the fitnesses (e.g. EO fitness is what Koza terms "raw fitness", from the fitnesses (e.g. EO fitness is what Koza terms "raw fitness",
Worth is what the selection is based upon). Worth is what the selection is based upon).
see class eoPerf2Worth: an eoStat that transforms fitnesses into Worthes see class eoPerf2Worth: an eoStat that transforms fitnesses into Worthes
@ -51,40 +51,36 @@ template <class EOT, class WorthType = double>
class eoSelectFromWorth : public eoSelectOne<EOT> class eoSelectFromWorth : public eoSelectOne<EOT>
{ {
public: public:
/* Default ctor from an eoPerf2Worth object
*/
eoSelectFromWorth(eoPerf2Worth<EOT, WorthType> & _perf2Worth) :
perf2Worth(_perf2Worth) {}
/* setup the worthes */ /* Default ctor from an eoPerf2Worth object */
virtual void setup(const eoPop<EOT>& _pop) eoSelectFromWorth(eoPerf2Worth<EOT, WorthType>& _perf2Worth)
{ : perf2Worth(_perf2Worth)
perf2Worth(_pop); {}
/* setup the worthes */
virtual void setup(const eoPop<EOT>& pop) {
perf2Worth(pop);
#ifndef NDEBUG #ifndef NDEBUG
fitness.resize(_pop.size()); fitness.resize(pop.size());
for (unsigned i = 0; i < _pop.size(); ++i) for (unsigned i = 0; i < pop.size(); ++i) {
{ fitness[i] = pop[i].fitness();
fitness[i] = _pop[i].fitness(); }
}
#endif #endif
} }
protected: protected:
eoPerf2Worth<EOT, WorthType> & perf2Worth;
eoPerf2Worth<EOT, WorthType>& perf2Worth;
#ifndef NDEBUG #ifndef NDEBUG
std::vector<typename EOT::Fitness> fitness; std::vector<typename EOT::Fitness> fitness;
void check_sync(unsigned index, const EOT& _eo) void check_sync(unsigned index, const EOT& _eo) {
{ if (fitness[index] != _eo.fitness()) {
if (fitness[index] != _eo.fitness()) throw std::runtime_error("eoSelectFromWorth: fitnesses are not in sync");
{ }
throw std::runtime_error("eoSelectFromWorth: fitnesses are not in sync");
} }
}
#endif #endif
}; };
@ -95,36 +91,34 @@ template <class EOT, class WorthT = double>
class eoDetTournamentWorthSelect : public eoSelectFromWorth<EOT, WorthT> class eoDetTournamentWorthSelect : public eoSelectFromWorth<EOT, WorthT>
{ {
public: public:
typedef typename std::vector<WorthT>::iterator worthIterator;
/* Default ctor from an eoPerf2Worth object + tournament size using eoSelectFromWorth<EOT, WorthT>::perf2Worth;
*/
eoDetTournamentWorthSelect(eoPerf2Worth<EOT, WorthT> &_perf2Worth,
unsigned _tSize) :
eoSelectFromWorth<EOT, WorthT>(_perf2Worth), tSize(_tSize) {}
/* Perform deterministic tournament on worthes typedef typename std::vector<WorthT>::iterator worthIterator;
by calling the appropriate fn
see selectors.h
*/
virtual const EOT& operator()(const eoPop<EOT>& _pop)
{
worthIterator it = deterministic_tournament(
perf2Worth.value().begin(),
perf2Worth.value().end(), tSize);
unsigned index = it - perf2Worth.value().begin(); /* Default ctor from an eoPerf2Worth object + tournament size */
eoDetTournamentWorthSelect(eoPerf2Worth<EOT, WorthT>& perf2Worth,
unsigned _tSize)
: eoSelectFromWorth<EOT, WorthT>(perf2Worth), tSize(_tSize) {}
/* Perform deterministic tournament on worthes by calling the
appropriate fn see selectors.h */
virtual const EOT& operator()(const eoPop<EOT>& pop) {
worthIterator it = deterministic_tournament(perf2Worth.value().begin(),
perf2Worth.value().end(),
tSize);
unsigned index = it - perf2Worth.value().begin();
#ifndef NDEBUG #ifndef NDEBUG
// check whether the stuff is still in sync // check whether the stuff is still in sync
check_sync(index, _pop[index]); check_sync(index, pop[index]);
#endif #endif
return pop[index];
}
return _pop[index];
}
private: private:
unsigned tSize;
unsigned tSize;
}; };
/** An instance of eoSelectPerf2Worth that does selection from the Worthes /** An instance of eoSelectPerf2Worth that does selection from the Worthes
@ -134,24 +128,25 @@ template <class EOT, class WorthT = double>
class eoStochTournamentWorthSelect : public eoSelectFromWorth<EOT, WorthT> class eoStochTournamentWorthSelect : public eoSelectFromWorth<EOT, WorthT>
{ {
public: public:
typedef typename std::vector<WorthT>::iterator worthIterator;
/* Default ctor from an eoPerf2Worth object + tournament rate using eoSelectFromWorth<EOT, WorthT>::perf2Worth;
*/
eoStochTournamentWorthSelect(eoPerf2Worth<EOT, WorthT> &_perf2Worth, typedef typename std::vector<WorthT>::iterator worthIterator;
double _tRate) :
eoSelectFromWorth<EOT, WorthT>(_perf2Worth), tRate(_tRate) {} /* Default ctor from an eoPerf2Worth object + tournament rate */
eoStochTournamentWorthSelect(eoPerf2Worth<EOT, WorthT> &_perf2Worth, double _tRate)
: eoSelectFromWorth<EOT, WorthT>(_perf2Worth), tRate(_tRate)
{}
/* Perform stochastic tournament on worthes /* Perform stochastic tournament on worthes
by calling the appropriate fn in selectors.h by calling the appropriate fn in selectors.h
*/ */
virtual const EOT& operator()(const eoPop<EOT>& _pop) virtual const EOT& operator()(const eoPop<EOT>& _pop) {
{ worthIterator it = stochastic_tournament(perf2Worth.value().begin(),
worthIterator it = stochastic_tournament( perf2Worth.value().end(),
perf2Worth.value().begin(), tRate);
perf2Worth.value().end(), tRate);
unsigned index = it - perf2Worth.value().begin(); unsigned index = it - perf2Worth.value().begin();
#ifndef NDEBUG #ifndef NDEBUG
// check whether the stuff is still in sync // check whether the stuff is still in sync
@ -172,12 +167,16 @@ template <class EOT, class WorthT = double>
class eoRouletteWorthSelect : public eoSelectFromWorth<EOT, WorthT> class eoRouletteWorthSelect : public eoSelectFromWorth<EOT, WorthT>
{ {
public: public:
typedef typename std::vector<WorthT>::iterator worthIterator;
/* Default ctor from an eoPerf2Worth object using eoSelectFromWorth<EOT, WorthT>::perf2Worth;
*/
eoRouletteWorthSelect(eoPerf2Worth<EOT, WorthT> &_perf2Worth) : typedef typename std::vector<WorthT>::iterator worthIterator;
eoSelectFromWorth<EOT, WorthT>(_perf2Worth) {}
/* Default ctor from an eoPerf2Worth object */
eoRouletteWorthSelect(eoPerf2Worth<EOT, WorthT> &_perf2Worth)
: eoSelectFromWorth<EOT, WorthT>(_perf2Worth)
{}
/* We have to override the default behavior to compute the total /* We have to override the default behavior to compute the total
* only once! * only once!
@ -195,18 +194,16 @@ public:
by calling the appropriate fn by calling the appropriate fn
see selectors.h see selectors.h
*/ */
virtual const EOT& operator()(const eoPop<EOT>& _pop) virtual const EOT& operator()(const eoPop<EOT>& _pop) {
{ // cout << "On affiche les worths\n";
// cout << "On affiche les worths\n"; // for (unsigned i=0;
// for (unsigned i=0; // i<perf2Worth.value().size();
// i<perf2Worth.value().size(); // i++)
// i++) // cout << perf2Worth.value().operator[](i) << "\n";
// cout << perf2Worth.value().operator[](i) << "\n"; // cout << endl;
// cout << endl; worthIterator it = roulette_wheel(perf2Worth.value().begin(),
worthIterator it = roulette_wheel( perf2Worth.value().end(),
perf2Worth.value().begin(), total);
perf2Worth.value().end(),
total);
unsigned index = it - perf2Worth.value().begin(); unsigned index = it - perf2Worth.value().begin();
@ -216,7 +213,7 @@ public:
#endif #endif
return _pop[index]; return _pop[index];
return _pop[it-perf2Worth.value().begin()]; return _pop[it - perf2Worth.value().begin()];
} }
private: private:

View file

@ -29,7 +29,7 @@
#include <eoPerf2Worth.h> #include <eoPerf2Worth.h>
#include <utils/eoDistance.h> #include <utils/eoDistance.h>
/** Sharing is a perf2worth class that implements /** Sharing is a perf2worth class that implements
* Goldberg and Richardson's basic sharing * Goldberg and Richardson's basic sharing
*/ */
@ -70,7 +70,7 @@
}; };
/** Sharing is a perf2worth class that implements /** Sharing is a perf2worth class that implements
* Goldberg and Richardson's basic sharing * Goldberg and Richardson's basic sharing
* see eoSharingSelect for how to use it * see eoSharingSelect for how to use it
* and test/t-eoSharing.cpp for a sample use of both * and test/t-eoSharing.cpp for a sample use of both
@ -78,10 +78,14 @@
template <class EOT> template <class EOT>
class eoSharing : public eoPerf2Worth<EOT> class eoSharing : public eoPerf2Worth<EOT>
{ {
public: public:
using eoSharing< EOT >::value;
/* Ctor requires a distance - cannot have a default distance! */ /* Ctor requires a distance - cannot have a default distance! */
eoSharing(double _nicheSize, eoDistance<EOT> & _dist) : eoPerf2Worth<EOT>("Sharing"), eoSharing(double _nicheSize, eoDistance<EOT> & _dist) : eoPerf2Worth<EOT>("Sharing"),
nicheSize(_nicheSize), nicheSize(_nicheSize),
dist(_dist) dist(_dist)
{} {}
@ -89,7 +93,7 @@ class eoSharing : public eoPerf2Worth<EOT>
*/ */
void operator()(const eoPop<EOT>& _pop) void operator()(const eoPop<EOT>& _pop)
{ {
unsigned i, j, unsigned i, j,
pSize=_pop.size(); pSize=_pop.size();
if (pSize <= 1) if (pSize <= 1)
throw std::runtime_error("Apptempt to do sharing with population of size 1"); throw std::runtime_error("Apptempt to do sharing with population of size 1");
@ -105,7 +109,7 @@ class eoSharing : public eoPerf2Worth<EOT>
for (j=0; j<i; j++) for (j=0; j<i; j++)
{ {
double d = dist(_pop[i], _pop[j]); double d = dist(_pop[i], _pop[j]);
distMatrix(i,j) = distMatrix(i,j) =
distMatrix(j,i) = ( d>nicheSize ? 0 : 1-(d/nicheSize) ); distMatrix(j,i) = ( d>nicheSize ? 0 : 1-(d/nicheSize) );
} }
} }
@ -123,7 +127,7 @@ class eoSharing : public eoPerf2Worth<EOT>
value()[i]=_pop[i].fitness()/sim[i]; value()[i]=_pop[i].fitness()/sim[i];
} }
// private data of class eoSharing // private data of class eoSharing
private: private:
double nicheSize; double nicheSize;
eoDistance<EOT> & dist; // specific distance eoDistance<EOT> & dist; // specific distance
}; };

View file

@ -1,9 +1,9 @@
/** -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*- /** -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*-
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
eoSurviveAndDie.h eoSurviveAndDie.h
(c) Maarten Keijzer, Marc Schoenauer, GeNeura Team, 2000 (c) Maarten Keijzer, Marc Schoenauer, GeNeura Team, 2000
This library is free software; you can redistribute it and/or This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either License as published by the Free Software Foundation; either
@ -37,8 +37,8 @@
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
/** /**
eoSurviveAndDie: takes a population (first argument), eoSurviveAndDie: takes a population (first argument),
kills the ones that are to die, kills the ones that are to die,
puts the ones that are to survive into the second argument puts the ones that are to survive into the second argument
removes them from the first pop argument removes them from the first pop argument
@ -54,32 +54,35 @@ class eoSurviveAndDie : public eoBF<eoPop<EOT> &, eoPop<EOT> &, void>
{ {
public: public:
eoSurviveAndDie(double _survive, double _die, bool _interpret_as_rate = true): eoSurviveAndDie(double _survive, double _die, bool _interpret_as_rate = true):
howmanySurvive(_survive, _interpret_as_rate), howmanySurvive(_survive, _interpret_as_rate),
howmanyDie(_die, _interpret_as_rate) howmanyDie(_die, _interpret_as_rate)
{} {}
protected: protected:
eoHowMany howmanySurvive; eoHowMany howmanySurvive;
eoHowMany howmanyDie; eoHowMany howmanyDie;
}; };
/** /** An instance (theonly one as of today, Dec. 20, 2000) of an
an instance (theonly one as of today, Dec. 20, 2000) of an eoSurviveAndDie, eoSurviveAndDie, that does everything deterministically
that does everything deterministically
used in eoDeterministicSaDReplacement Used in eoDeterministicSaDReplacement.
*/ */
template <class EOT> template <class EOT>
class eoDeterministicSurviveAndDie : public eoSurviveAndDie<EOT> class eoDeterministicSurviveAndDie : public eoSurviveAndDie<EOT>
{ {
public: public:
eoDeterministicSurviveAndDie(double _survive, double _die,
bool _interpret_as_rate = true): using eoSurviveAndDie< EOT >::howmanyDie;
eoSurviveAndDie<EOT>(_survive, _die, _interpret_as_rate) using eoSurviveAndDie< EOT >::howmanySurvive;
/** constructor */
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) void operator()(eoPop<EOT> & _pop, eoPop<EOT> & _luckyGuys)
{ {
unsigned pSize = _pop.size(); unsigned pSize = _pop.size();
@ -88,7 +91,7 @@ public:
if (nbSurvive) if (nbSurvive)
{ {
_pop.nth_element(nbSurvive); _pop.nth_element(nbSurvive);
// copy best // copy best
_luckyGuys.resize(nbSurvive); _luckyGuys.resize(nbSurvive);
std::copy(_pop.begin(), _pop.begin()+nbSurvive, _luckyGuys.begin()); std::copy(_pop.begin(), _pop.begin()+nbSurvive, _luckyGuys.begin());
// erase them from pop // erase them from pop
@ -100,7 +103,7 @@ public:
unsigned nbDie = std::min(howmanyDie(pSize), pSize-nbSurvive); unsigned nbDie = std::min(howmanyDie(pSize), pSize-nbSurvive);
if (nbDie > nbRemaining) if (nbDie > nbRemaining)
throw std::logic_error("eoDeterministicSurviveAndDie: Too many to kill!\n"); throw std::logic_error("eoDeterministicSurviveAndDie: Too many to kill!\n");
if (!nbDie) if (!nbDie)
{ {
return; return;
@ -118,33 +121,33 @@ eoDeterministicSaDReplacement: replacement strategy that is just, in sequence
saves best and kill worse from parents saves best and kill worse from parents
+ saves best and kill worse from offspring + saves best and kill worse from offspring
+ merge remaining (neither save nor killed) parents and offspring + merge remaining (neither save nor killed) parents and offspring
+ reduce that merged population + reduce that merged population
= returns reduced pop + best parents + best offspring = returns reduced pop + best parents + best offspring
An obvious use is as strong elitist strategy, An obvious use is as strong elitist strategy,
i.e. preserving best parents, and reducing i.e. preserving best parents, and reducing
(either offspring or parents+offspring) (either offspring or parents+offspring)
*/ */
template <class EOT> template <class EOT>
class eoDeterministicSaDReplacement : public eoReplacement<EOT> class eoDeterministicSaDReplacement : public eoReplacement<EOT>
{ {
public: public:
/** Constructor with reduce */ /** Constructor with reduce */
eoDeterministicSaDReplacement(eoReduce<EOT>& _reduceGlobal, eoDeterministicSaDReplacement(eoReduce<EOT>& _reduceGlobal,
double _surviveParents, double _dieParents=0, double _surviveParents, double _dieParents=0,
double _surviveOffspring=0, double _dieOffspring=0, double _surviveOffspring=0, double _dieOffspring=0,
bool _interpret_as_rate = true ) : bool _interpret_as_rate = true ) :
reduceGlobal(_reduceGlobal), reduceGlobal(_reduceGlobal),
sAdParents(_surviveParents, _dieParents, _interpret_as_rate), sAdParents(_surviveParents, _dieParents, _interpret_as_rate),
sAdOffspring(_surviveOffspring, _dieOffspring, _interpret_as_rate) sAdOffspring(_surviveOffspring, _dieOffspring, _interpret_as_rate)
{} {}
/** Constructor with default truncate used as reduce */ /** Constructor with default truncate used as reduce */
eoDeterministicSaDReplacement( eoDeterministicSaDReplacement(
double _surviveParents, double _dieParents=0, double _surviveParents, double _dieParents=0,
double _surviveOffspring=0, double _dieOffspring=0, double _surviveOffspring=0, double _dieOffspring=0,
bool _interpret_as_rate = true ) : bool _interpret_as_rate = true ) :
reduceGlobal(truncate), reduceGlobal(truncate),
sAdParents(_surviveParents, _dieParents, _interpret_as_rate), sAdParents(_surviveParents, _dieParents, _interpret_as_rate),
sAdOffspring(_surviveOffspring, _dieOffspring, _interpret_as_rate) sAdOffspring(_surviveOffspring, _dieOffspring, _interpret_as_rate)
{} {}

View file

@ -22,7 +22,7 @@
Marc.Schoenauer@polytechnique.fr Marc.Schoenauer@polytechnique.fr
mak@dhi.dk mak@dhi.dk
CVS Info: $Date: 2003-03-18 16:57:17 $ $Header: /home/nojhan/dev/eodev/eodev_cvs/eo/src/eoVector.h,v 1.15 2003-03-18 16:57:17 maartenkeijzer Exp $ $Author: maartenkeijzer $ CVS Info: $Date: 2004-12-23 15:29:06 $ $Header: /home/nojhan/dev/eodev/eodev_cvs/eo/src/eoVector.h,v 1.16 2004-12-23 15:29:06 kuepper Exp $ $Author: kuepper $
*/ */
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -39,20 +39,32 @@
Base class for fixed length chromosomes, just derives from EO and std::vector and Base class for fixed length chromosomes, just derives from EO and std::vector and
redirects the smaller than operator to EO (fitness based comparison). GeneType redirects the smaller than operator to EO (fitness based comparison). GeneType
must have the following methods: void ctor (needed for the std::vector<>), copy ctor, must have the following methods: void ctor (needed for the std::vector<>), copy ctor,
*/ */
template <class FitT, class GeneType> template <class FitT, class GeneType>
class eoVector : public EO<FitT>, public std::vector<GeneType> class eoVector : public EO<FitT>, public std::vector<GeneType>
{ {
public : public:
using EO<FitT>::invalidate;
using std::vector<GeneType>::operator[];
using std::vector<GeneType>::begin;
using std::vector<GeneType>::end;
using std::vector<GeneType>::resize;
using std::vector<GeneType>::size;
typedef GeneType AtomType; typedef GeneType AtomType;
typedef std::vector<GeneType> ContainerType; typedef std::vector<GeneType> ContainerType;
/** default constructor
eoVector(unsigned size = 0, GeneType value = GeneType()) : EO<FitT>(), std::vector<GeneType>(size, value) @param size Length of vector (default is 0)
{} @param value Initial value of all elements (default is default value of type GeneType)
*/
eoVector(unsigned size = 0, GeneType value = GeneType())
: EO<FitT>(), std::vector<GeneType>(size, value)
{}
/// copy ctor abstracting from the FitT /// copy ctor abstracting from the FitT
template <class OtherFitnessType> template <class OtherFitnessType>

View file

@ -3,7 +3,7 @@
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// eoEsFull.h // eoEsFull.h
// (c) GeNeura Team, 2000 - EEAAX 1999 - Maarten Keijzer 2000 // (c) GeNeura Team, 2000 - EEAAX 1999 - Maarten Keijzer 2000
/* /*
This library is free software; you can redistribute it and/or This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either License as published by the Free Software Foundation; either
@ -39,7 +39,11 @@ rates and correlated mutations.
template <class Fit> template <class Fit>
class eoEsFull : public eoVector<Fit, double> class eoEsFull : public eoVector<Fit, double>
{ {
public : public:
using eoEsFull< Fit >::size;
typedef double Type; typedef double Type;
eoEsFull(void) : eoVector<Fit, double>() {} eoEsFull(void) : eoVector<Fit, double>() {}

View file

@ -3,7 +3,7 @@
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// eoEsStdev.h // eoEsStdev.h
// (c) GeNeura Team, 2000 - EEAAX 1999 - Maarten Keijzer 2000 // (c) GeNeura Team, 2000 - EEAAX 1999 - Maarten Keijzer 2000
/* /*
This library is free software; you can redistribute it and/or This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either License as published by the Free Software Foundation; either
@ -39,7 +39,9 @@ deviations.
template <class Fit> template <class Fit>
class eoEsStdev : public eoVector<Fit, double> class eoEsStdev : public eoVector<Fit, double>
{ {
public : public:
using eoEsStdev< Fit >::size;
typedef double Type; typedef double Type;

View file

@ -3,7 +3,7 @@
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// eoNormalMutation.h // eoNormalMutation.h
// (c) EEAAX 2001 - Maarten Keijzer 2000 // (c) EEAAX 2001 - Maarten Keijzer 2000
/* /*
This library is free software; you can redistribute it and/or This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either License as published by the Free Software Foundation; either
@ -37,7 +37,7 @@
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
/** Simple normal mutation of a std::vector of real values. /** Simple normal mutation of a std::vector of real values.
* The stDev is fixed - but it is passed ans stored as a reference, * The stDev is fixed - but it is passed ans stored as a reference,
* to enable dynamic mutations (see eoOenFithMutation below). * to enable dynamic mutations (see eoOenFithMutation below).
* *
* As for the bounds, the values are here folded back into the bounds. * As for the bounds, the values are here folded back into the bounds.
@ -68,7 +68,7 @@ template<class EOT> class eoNormalVecMutation: public eoMonOp<EOT>
*/ */
eoNormalVecMutation(eoRealVectorBounds & _bounds, eoNormalVecMutation(eoRealVectorBounds & _bounds,
double _sigma, const double& _p_change = 1.0): double _sigma, const double& _p_change = 1.0):
sigma(_bounds.size(), _sigma), bounds(_bounds), p_change(_p_change) sigma(_bounds.size(), _sigma), bounds(_bounds), p_change(_p_change)
{ {
// scale to the range - if any // scale to the range - if any
for (unsigned i=0; i<bounds.size(); i++) for (unsigned i=0; i<bounds.size(); i++)
@ -105,7 +105,7 @@ private:
}; };
/** Simple normal mutation of a std::vector of real values. /** Simple normal mutation of a std::vector of real values.
* The stDev is fixed - but it is passed ans stored as a reference, * The stDev is fixed - but it is passed ans stored as a reference,
* to enable dynamic mutations (see eoOenFithMutation below). * to enable dynamic mutations (see eoOenFithMutation below).
* *
* As for the bounds, the values are here folded back into the bounds. * As for the bounds, the values are here folded back into the bounds.
@ -113,9 +113,10 @@ private:
* but this sometimes takes a long time!!! * but this sometimes takes a long time!!!
*/ */
template<class EOT> class eoNormalMutation: public eoMonOp<EOT> template<class EOT> class eoNormalMutation
: public eoMonOp<EOT>
{ {
public: public:
/** /**
* (Default) Constructor. * (Default) Constructor.
* The bounds are initialized with the global object that says: no bounds. * The bounds are initialized with the global object that says: no bounds.
@ -173,11 +174,14 @@ private:
* increase sigma if more than threshold (1/5 !) * increase sigma if more than threshold (1/5 !)
*/ */
template<class EOT> class eoOneFifthMutation : template<class EOT> class eoOneFifthMutation :
public eoNormalMutation<EOT>, public eoUpdatable public eoNormalMutation<EOT>, public eoUpdatable
{ {
public: public:
typedef typename EOT::Fitness Fitness;
using eoNormalMutation< EOT >::Sigma;
typedef typename EOT::Fitness Fitness;
/** /**
* (Default) Constructor. * (Default) Constructor.
@ -186,14 +190,14 @@ public:
* @param _sigmaInit the initial value for uniform mutation * @param _sigmaInit the initial value for uniform mutation
* @param _windowSize the size of the window for statistics * @param _windowSize the size of the window for statistics
* @param _threshold the threshold (the 1/5 - 0.2) * @param _threshold the threshold (the 1/5 - 0.2)
* @param _updateFactor multiplicative update factor for sigma * @param _updateFactor multiplicative update factor for sigma
*/ */
eoOneFifthMutation(eoEvalFunc<EOT> & _eval, double & _sigmaInit, eoOneFifthMutation(eoEvalFunc<EOT> & _eval, double & _sigmaInit,
unsigned _windowSize = 10, double _updateFactor=0.83, unsigned _windowSize = 10, double _updateFactor=0.83,
double _threshold=0.2): double _threshold=0.2):
eoNormalMutation<EOT>(_sigmaInit), eval(_eval), eoNormalMutation<EOT>(_sigmaInit), eval(_eval),
threshold(_threshold), updateFactor(_updateFactor), threshold(_threshold), updateFactor(_updateFactor),
nbMut(_windowSize, 0), nbSuccess(_windowSize, 0), genIndex(0) nbMut(_windowSize, 0), nbSuccess(_windowSize, 0), genIndex(0)
{ {
// minimal check // minimal check
if (updateFactor>=1) if (updateFactor>=1)
@ -209,7 +213,7 @@ public:
* *
* @param _eo The chromosome undergoing the mutation * @param _eo The chromosome undergoing the mutation
*/ */
bool operator()(EOT & _eo) bool operator()(EOT & _eo)
{ {
if (_eo.invalid()) // due to some crossover??? if (_eo.invalid()) // due to some crossover???
eval(_eo); eval(_eo);
@ -227,8 +231,8 @@ public:
} }
return false; // because eval has reset the validity flag return false; // because eval has reset the validity flag
} }
/** the method that will be called every generation /** the method that will be called every generation
* if the object is added to the checkpoint * if the object is added to the checkpoint
*/ */
void update() void update()
@ -255,12 +259,12 @@ public:
nbMut[genIndex] = nbSuccess[genIndex] = 0; nbMut[genIndex] = nbSuccess[genIndex] = 0;
} }
private: private:
eoEvalFunc<EOT> & eval; eoEvalFunc<EOT> & eval;
double threshold; // 1/5 ! double threshold; // 1/5 !
double updateFactor ; // the multiplicative factor double updateFactor ; // the multiplicative factor
std::vector<unsigned> nbMut; // total number of mutations per gen std::vector<unsigned> nbMut; // total number of mutations per gen
std::vector<unsigned> nbSuccess; // number of successful mutations per gen std::vector<unsigned> nbSuccess; // number of successful mutations per gen
unsigned genIndex ; // current index in std::vectors (circular) unsigned genIndex ; // current index in std::vectors (circular)
}; };

View file

@ -20,9 +20,9 @@
Marc.Schoenauer@polytechnique.fr Marc.Schoenauer@polytechnique.fr
*/ */
/* MS, Nov. 23, 2000 /* MS, Nov. 23, 2000
Added the calls to base class I/O routines that print the fitness Added the calls to base class I/O routines that print the fitness
Left printing/reading of the size of the bitstring, Left printing/reading of the size of the bitstring,
for backward compatibility, and as it is a general practice in EO for backward compatibility, and as it is a general practice in EO
MS, Feb. 7, 2001 MS, Feb. 7, 2001
@ -54,7 +54,11 @@
*/ */
template <class FitT> class eoBit: public eoVector<FitT, bool> template <class FitT> class eoBit: public eoVector<FitT, bool>
{ {
public: public:
using eoVector< FitT, bool >::begin;
using eoVector< FitT, bool >::end;
using eoVector< FitT, bool >::size;
/** /**
* (Default) Constructor. * (Default) Constructor.
@ -104,3 +108,9 @@ template <class FitT> class eoBit: public eoVector<FitT, bool>
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
#endif //eoBit_h #endif //eoBit_h
// Local Variables:
// mode: C++
// c-file-style: "Stroustrup"
// End:

View file

@ -3,7 +3,7 @@
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// eoPBILAdditive.h // eoPBILAdditive.h
// (c) Marc Schoenauer, Maarten Keijzer, 2001 // (c) Marc Schoenauer, Maarten Keijzer, 2001
/* /*
This library is free software; you can redistribute it and/or This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either License as published by the Free Software Foundation; either
@ -30,10 +30,10 @@
#include <ga/eoPBILDistrib.h> #include <ga/eoPBILDistrib.h>
/** /**
* Distribution Class for PBIL algorithm * Distribution Class for PBIL algorithm
* (Population-Based Incremental Learning, Baluja and Caruana 96) * (Population-Based Incremental Learning, Baluja and Caruana 96)
* *
* This class implements an extended update rule: * This class implements an extended update rule:
* in the original paper, the authors used * in the original paper, the authors used
* *
* p(i)(t+1) = (1-LR)*p(i)(t) + LR*best(i) * p(i)(t+1) = (1-LR)*p(i)(t) + LR*best(i)
@ -46,12 +46,12 @@ template <class EOT>
class eoPBILAdditive : public eoDistribUpdater<EOT> class eoPBILAdditive : public eoDistribUpdater<EOT>
{ {
public: public:
/** Ctor with parameters /** Ctor with parameters
* using the default values is equivalent to using eoPBILOrg * using the default values is equivalent to using eoPBILOrg
*/ */
eoPBILAdditive(double _LRBest, unsigned _nbBest = 1, eoPBILAdditive(double _LRBest, unsigned _nbBest = 1,
double _tolerance=0.0, double _tolerance=0.0,
double _LRWorst = 0.0, unsigned _nbWorst = 0 ) : double _LRWorst = 0.0, unsigned _nbWorst = 0 ) :
maxBound(1.0-_tolerance), minBound(_tolerance), maxBound(1.0-_tolerance), minBound(_tolerance),
LR(0.0), nbBest(_nbBest), nbWorst(_nbWorst) LR(0.0), nbBest(_nbBest), nbWorst(_nbWorst)
{ {
@ -75,7 +75,7 @@ public:
} }
/** Update the distribution from the current population */ /** Update the distribution from the current population */
virtual void operator()(eoDistribution<EOT> & _distrib, eoPop<EOT>& _pop) virtual void operator()(eoDistribution<EOT> & _distrib, eoPop<EOT>& _pop)
{ {
eoPBILDistrib<EOT>& distrib = dynamic_cast<eoPBILDistrib<EOT>&>(_distrib); eoPBILDistrib<EOT>& distrib = dynamic_cast<eoPBILDistrib<EOT>&>(_distrib);
@ -83,7 +83,7 @@ public:
unsigned i, popSize=_pop.size(); unsigned i, popSize=_pop.size();
std::vector<const EOT*> result; std::vector<const EOT*> result;
_pop.sort(result); // is it necessary to sort the whole population? _pop.sort(result); // is it necessary to sort the whole population?
// but I'm soooooooo lazy !!! // but I'm soooooooo lazy !!!
for (unsigned g=0; g<distrib.size(); g++) for (unsigned g=0; g<distrib.size(); g++)
@ -104,8 +104,8 @@ public:
p[g] += lrw; p[g] += lrw;
} }
// stay in [0,1] (possibly strictly due to tolerance) // stay in [0,1] (possibly strictly due to tolerance)
p[g] = min(maxBound, p[g]); p[g] = std::min(maxBound, p[g]);
p[g] = max(minBound, p[g]); p[g] = std::max(minBound, p[g]);
} }
} }

View file

@ -1,26 +1,26 @@
// -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*- // -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*-
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// eoParseTree.h : eoParseTree class (for Tree-based Genetic Programming) // eoParseTree.h : eoParseTree class (for Tree-based Genetic Programming)
// (c) Maarten Keijzer 2000 // (c) Maarten Keijzer 2000
/* /*
This library is free software; you can redistribute it and/or This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version. version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful, This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details. Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 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
mak@dhi.dk mak@dhi.dk
*/ */
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -57,27 +57,31 @@ using namespace gp_parse_tree;
template <class FType, class Node> template <class FType, class Node>
class eoParseTree : public EO<FType>, public parse_tree<Node> class eoParseTree : public EO<FType>, public parse_tree<Node>
{ {
public : public:
using eoParseTree<FType, Node >::back;
using eoParseTree<FType, Node >::ebegin;
using eoParseTree<FType, Node >::eend;
using eoParseTree<FType, Node >::size;
typedef typename parse_tree<Node>::subtree Subtree; typedef typename parse_tree<Node>::subtree Subtree;
/* For Compatibility with the intel C++ compiler for Linux 5.x */ /* For Compatibility with the intel C++ compiler for Linux 5.x */
typedef Node reference; typedef Node reference;
typedef const reference const_reference; typedef const reference const_reference;
/** /**
* Default Constructor * Default Constructor
*/ */
eoParseTree(void) {} eoParseTree(void) {}
/**
/**
* Copy Constructor * Copy Constructor
* @param tree The tree to copy * @param tree The tree to copy
*/ */
eoParseTree(const parse_tree<Node>& tree) : parse_tree<Node>(tree) {} eoParseTree(const parse_tree<Node>& tree) : parse_tree<Node>(tree) {}
// eoParseTree(const eoParseTree<FType, Node>& tree) : parse_tree<Node>(tree) {} // eoParseTree(const eoParseTree<FType, Node>& tree) : parse_tree<Node>(tree) {}
/** /**
* To prune me to a certain size * To prune me to a certain size
@ -90,7 +94,7 @@ public :
while (size() > _size) while (size() > _size)
{ {
back() = operator[](size()-2); back() = operator[](size()-2);
} }
} }
@ -98,8 +102,8 @@ public :
* To read me from a stream * To read me from a stream
* @param is The std::istream * @param is The std::istream
*/ */
eoParseTree(std::istream& is) : EO<FType>(), parse_tree<Node>() eoParseTree(std::istream& is) : EO<FType>(), parse_tree<Node>()
{ {
readFrom(is); readFrom(is);
} }
@ -120,21 +124,21 @@ public :
std::copy(ebegin(), eend(), std::ostream_iterator<Node>(os, " ")); std::copy(ebegin(), eend(), std::ostream_iterator<Node>(os, " "));
} }
/** /**
* To read me from a stream * To read me from a stream
* @param is The std::istream * @param is The std::istream
*/ */
void readFrom(std::istream& is) void readFrom(std::istream& is)
{ {
EO<FType>::readFrom(is); EO<FType>::readFrom(is);
unsigned sz; unsigned sz;
is >> sz; is >> sz;
std::vector<Node> v(sz); std::vector<Node> v(sz);
unsigned i; unsigned i;
@ -147,19 +151,19 @@ public :
} }
parse_tree<Node> tmp(v.begin(), v.end()); parse_tree<Node> tmp(v.begin(), v.end());
swap(tmp); swap(tmp);
/* /*
* old code which caused problems for paradisEO * old code which caused problems for paradisEO
* *
* this can be removed once it has proved itself * this can be removed once it has proved itself
EO<FType>::readFrom(is); EO<FType>::readFrom(is);
// even older code // even older code
FType fit; FType fit;
is >> fit; is >> fit;
fitness(fit); fitness(fit);
std::copy(std::istream_iterator<Node>(is), std::istream_iterator<Node>(), back_inserter(*this)); std::copy(std::istream_iterator<Node>(is), std::istream_iterator<Node>(), back_inserter(*this));
*/ */

View file

@ -3,14 +3,14 @@
/** /**
* Parse_tree and subtree classes * Parse_tree and subtree classes
* (c) copyright Maarten Keijzer 1999, 2000 * (c) copyright Maarten Keijzer 1999, 2000
* Permission to copy, use, modify, sell and distribute this software is granted provided * Permission to copy, use, modify, sell and distribute this software is granted provided
* this copyright notice appears in all copies. This software is provided "as is" without * this copyright notice appears in all copies. This software is provided "as is" without
* express or implied warranty, and with no claim as to its suitability for * express or implied warranty, and with no claim as to its suitability for
* any purpose. * any purpose.
* Permission to modify the code and to distribute modified code is granted, * Permission to modify the code and to distribute modified code is granted,
* provided the above notices as well as this one are retained, and a notice that the code was * provided the above notices as well as this one are retained, and a notice that the code was
* modified is included with the above copyright notice. * modified is included with the above copyright notice.
@ -22,31 +22,31 @@
class Node (your node in the tree) must have the following implemented: class Node (your node in the tree) must have the following implemented:
****** Arity ****** ****** Arity ******
int arity(void) const int arity(void) const
Note: the default constructor of a Node should provide a Note: the default constructor of a Node should provide a
Node with arity 0! Node with arity 0!
****** Evaluation ****** ****** Evaluation ******
A parse_tree is evaluated through one of it's apply() members: A parse_tree is evaluated through one of it's apply() members:
1) parse_tree::apply(RetVal) 1) parse_tree::apply(RetVal)
is the simplest evaluation, it will call is the simplest evaluation, it will call
RetVal Node::operator()(RetVal, subtree<Node, RetVal>::const_iterator) RetVal Node::operator()(RetVal, subtree<Node, RetVal>::const_iterator)
(Unfortunately the first RetVal argument is mandatory (although you (Unfortunately the first RetVal argument is mandatory (although you
might not need it. This is because MSVC does not support member template might not need it. This is because MSVC does not support member template
functions properly. If it cannot deduce the template arguments (as is functions properly. If it cannot deduce the template arguments (as is
the case in templatizing over return value) you are not allowed to the case in templatizing over return value) you are not allowed to
specify them. calling tree.apply<double>() would result in a syntax specify them. calling tree.apply<double>() would result in a syntax
error. That is why you have to call tree.apply(double()) instead.) error. That is why you have to call tree.apply(double()) instead.)
2) parse_tree::apply(RetVal v, It values) 2) parse_tree::apply(RetVal v, It values)
will call: will call:
@ -61,7 +61,7 @@
will call: will call:
RetVal Node::operator()(RetVal, subtree<... , It values, It2 moreValues) RetVal Node::operator()(RetVal, subtree<... , It values, It2 moreValues)
although I do not see the immediate use of this, however... although I do not see the immediate use of this, however...
4) parse_tree::apply(RetVal, It values, It2 args, It3 adfs) 4) parse_tree::apply(RetVal, It values, It2 args, It3 adfs)
@ -70,10 +70,10 @@
RetVal Node::operator()(subtree<... , It values, It2 args, It3 adfs) RetVal Node::operator()(subtree<... , It values, It2 args, It3 adfs)
can be useful for implementing adfs. can be useful for implementing adfs.
In general it is a good idea to leave the specifics of the In general it is a good idea to leave the specifics of the
arguments open so that different ways of evaluation remain arguments open so that different ways of evaluation remain
possible. Implement the simplest eval as: possible. Implement the simplest eval as:
@ -85,24 +85,24 @@
A parse_tree has two template arguments: the Node and the ReturnValue A parse_tree has two template arguments: the Node and the ReturnValue
produced by evaluating the node. The structure of the tree is defined produced by evaluating the node. The structure of the tree is defined
through a subtree class that has the same two template arguments. through a subtree class that has the same two template arguments.
The nodes are stored in a tree like : The nodes are stored in a tree like :
node4 node4
/ \ / \
node3 node2 node3 node2
/ \ / \
node1 node0 node1 node0
where nodes 2 and 4 have arity 2 and nodes 0,1 and 3 arity 0 (terminals) where nodes 2 and 4 have arity 2 and nodes 0,1 and 3 arity 0 (terminals)
The nodes are subtrees, containing the structure of the tree, together The nodes are subtrees, containing the structure of the tree, together
with its size and depth. They contain a Node, the user defined template with its size and depth. They contain a Node, the user defined template
argument. To access these nodes from a subtree, use operator-> or operator*. argument. To access these nodes from a subtree, use operator-> or operator*.
The numbers behind the nodes define a reverse-polish or postfix The numbers behind the nodes define a reverse-polish or postfix
traversel through the tree. The parse_tree defines iterators traversel through the tree. The parse_tree defines iterators
on the tree such that on the tree such that
tree.begin() points at the subtree at node0 and tree.begin() points at the subtree at node0 and
tree.back() returns the subtree at node4, the complete tree tree.back() returns the subtree at node4, the complete tree
@ -134,9 +134,9 @@
std::vector<Node> vec(tree.size()); std::vector<Node> vec(tree.size());
copy(tree.ebegin(), tree.eend(), vec.begin()); copy(tree.ebegin(), tree.eend(), vec.begin());
You can also copy it to an std::ostream_iterator with this You can also copy it to an std::ostream_iterator with this
technique, given that your Node implements an appropriate technique, given that your Node implements an appropriate
operator<<. Reinitializing a tree with the std::vector is also operator<<. Reinitializing a tree with the std::vector is also
simple: simple:
tree.clear(); tree.clear();
@ -158,7 +158,7 @@
#ifdef _MSC_VER #ifdef _MSC_VER
#pragma warning(disable : 4786) // disable this nagging warning about the limitations of the mirkosoft debugger #pragma warning(disable : 4786) // disable this nagging warning about the limitations of the mirkosoft debugger
#endif #endif
namespace gp_parse_tree namespace gp_parse_tree
{ {
@ -166,7 +166,7 @@ namespace gp_parse_tree
/// This ones defined because gcc does not always implement namespaces /// This ones defined because gcc does not always implement namespaces
template <class T> template <class T>
inline void do_the_swap(T& a, T& b) inline void do_the_swap(T& a, T& b)
{ {
T tmp = a; T tmp = a;
a = b; a = b;
@ -181,7 +181,7 @@ template <class T> class parse_tree
class subtree class subtree
{ {
/* /*
a bit nasty way to use a pool allocator (which would otherwise use slooow new and delete) a bit nasty way to use a pool allocator (which would otherwise use slooow new and delete)
TODO: use the std::allocator interface TODO: use the std::allocator interface
*/ */
@ -198,42 +198,42 @@ public :
typedef subtree* iterator; typedef subtree* iterator;
typedef const subtree* const_iterator; typedef const subtree* const_iterator;
/* Constructors, assignments */ /* Constructors, assignments */
subtree(void) : content(node_allocator.allocate()), args(0), parent(0), _cumulative_size(0), _depth(0), _size(1) subtree(void) : content(node_allocator.allocate()), args(0), parent(0), _cumulative_size(0), _depth(0), _size(1)
{} {}
subtree(const subtree& s) subtree(const subtree& s)
: content(node_allocator.allocate()), : content(node_allocator.allocate()),
args(0), args(0),
parent(0), parent(0),
_cumulative_size(1), _cumulative_size(1),
_depth(1), _depth(1),
_size(1) _size(1)
{ {
copy(s); copy(s);
} }
subtree(const T& t) : content(node_allocator.allocate()), args(0), parent(0), _cumulative_size(0), _depth(0), _size(1) subtree(const T& t) : content(node_allocator.allocate()), args(0), parent(0), _cumulative_size(0), _depth(0), _size(1)
{ copy(t); } { copy(t); }
template <class It> template <class It>
subtree(It b, It e) : content(node_allocator.allocate()), args(0), parent(0), _cumulative_size(0), _depth(0), _size(1) subtree(It b, It e) : content(node_allocator.allocate()), args(0), parent(0), _cumulative_size(0), _depth(0), _size(1)
{ // initialize in prefix order for efficiency reasons { // initialize in prefix order for efficiency reasons
init(b, --e); init(b, --e);
} }
virtual ~subtree(void) { tree_allocator.deallocate(args, arity()); node_allocator.deallocate(content); } virtual ~subtree(void) { tree_allocator.deallocate(args, arity()); node_allocator.deallocate(content); }
subtree& operator=(const subtree& s) subtree& operator=(const subtree& s)
{ {
if (s.get_root() == get_root()) if (s.get_root() == get_root())
{ // from the same tree, maybe a child. Don't take any chances { // from the same tree, maybe a child. Don't take any chances
subtree anotherS = s; subtree anotherS = s;
return copy(anotherS); return copy(anotherS);
} }
copy(s); copy(s);
updateAfterInsert(); updateAfterInsert();
return *this; return *this;
} }
@ -242,9 +242,9 @@ public :
/* Access to the nodes */ /* Access to the nodes */
T& operator*(void) { return *content; } T& operator*(void) { return *content; }
const T& operator*(void) const { return *content; } const T& operator*(void) const { return *content; }
T* operator->(void) { return content; } T* operator->(void) { return content; }
const T* operator->(void) const { return content; } const T* operator->(void) const { return content; }
/* Equality, inequality check, Node needs to implement operator== */ /* Equality, inequality check, Node needs to implement operator== */
@ -274,11 +274,11 @@ public :
/* Evaluation with an increasing amount of user defined arguments */ /* Evaluation with an increasing amount of user defined arguments */
template <class RetVal> template <class RetVal>
void apply(RetVal& v) const { (*content)(v, begin()); } void apply(RetVal& v) const { (*content)(v, begin()); }
template <class RetVal, class It> template <class RetVal, class It>
void apply(RetVal& v, It values) const void apply(RetVal& v, It values) const
{ {
(*content)(v, begin(), values); (*content)(v, begin(), values);
} }
template <class RetVal, class It> template <class RetVal, class It>
@ -289,11 +289,11 @@ public :
/* template <class RetVal, class It, class It2> /* template <class RetVal, class It, class It2>
void apply(RetVal& v, It values, It2 moreValues) const void apply(RetVal& v, It values, It2 moreValues) const
{ (*content)(v, begin(), values, moreValues); } { (*content)(v, begin(), values, moreValues); }
template <class RetVal, class It, class It2, class It3> template <class RetVal, class It, class It2, class It3>
void apply(RetVal& v, It values, It2 moreValues, It3 evenMoreValues) const void apply(RetVal& v, It values, It2 moreValues, It3 evenMoreValues) const
{ (*content)(v, begin(), values, moreValues, evenMoreValues); } { (*content)(v, begin(), values, moreValues, evenMoreValues); }
*/ */
@ -310,7 +310,7 @@ public :
args[i].find_nodes(result, p); args[i].find_nodes(result, p);
} }
} }
template <class Pred> template <class Pred>
void find_nodes(std::vector<const subtree*>& result, Pred& p) const void find_nodes(std::vector<const subtree*>& result, Pred& p) const
{ {
@ -324,7 +324,7 @@ public :
args[i].find_nodes(result, p); args[i].find_nodes(result, p);
} }
} }
/* Iterators */ /* Iterators */
iterator begin(void) { return args; } iterator begin(void) { return args; }
@ -339,21 +339,21 @@ public :
/* Some statistics */ /* Some statistics */
size_t size(void) const { return _size; } size_t size(void) const { return _size; }
size_t cumulative_size(void) const { return _cumulative_size; } size_t cumulative_size(void) const { return _cumulative_size; }
size_t depth(void) const { return _depth; } size_t depth(void) const { return _depth; }
const subtree& select_cumulative(size_t which) const const subtree& select_cumulative(size_t which) const
{ return imp_select_cumulative(which); } { return imp_select_cumulative(which); }
subtree& select_cumulative(size_t which) subtree& select_cumulative(size_t which)
{ return const_cast<subtree&>(imp_select_cumulative(which)); } { return const_cast<subtree&>(imp_select_cumulative(which)); }
subtree& get_node(size_t which) subtree& get_node(size_t which)
{ return const_cast<subtree&>(imp_get_node(which));} { return const_cast<subtree&>(imp_get_node(which));}
const subtree& get_node(size_t which) const const subtree& get_node(size_t which) const
{ return imp_get_node(which); } { return imp_get_node(which); }
subtree* get_parent(void) { return parent; } subtree* get_parent(void) { return parent; }
const subtree* get_parent(void) const { return parent; } const subtree* get_parent(void) const { return parent; }
@ -364,7 +364,7 @@ public :
{ {
do_the_swap(content, y.content); do_the_swap(content, y.content);
do_the_swap(args, y.args); do_the_swap(args, y.args);
adopt(); adopt();
y.adopt(); y.adopt();
@ -381,7 +381,7 @@ protected :
virtual void updateAfterInsert(void) virtual void updateAfterInsert(void)
{ {
_depth = 0; _depth = 0;
_size = 1; _size = 1;
_cumulative_size = 0; _cumulative_size = 0;
for (iterator it = begin(); it != end(); ++it) for (iterator it = begin(); it != end(); ++it)
@ -411,7 +411,7 @@ private :
return args[i].imp_select_cumulative(which); return args[i].imp_select_cumulative(which);
which -= args[i]._cumulative_size; which -= args[i]._cumulative_size;
} }
return *this; // error! return *this; // error!
} }
@ -419,7 +419,7 @@ private :
{ {
if (which == size() - 1) if (which == size() - 1)
return *this; return *this;
for (int i = arity() - 1; i >= 0; --i) for (int i = arity() - 1; i >= 0; --i)
{ {
unsigned c_size = args[i].size(); unsigned c_size = args[i].size();
@ -442,9 +442,9 @@ private :
subtree& copy(const subtree& s) subtree& copy(const subtree& s)
{ {
int old_arity = arity(); int old_arity = arity();
int new_arity = s.arity(); int new_arity = s.arity();
if (new_arity != old_arity) if (new_arity != old_arity)
{ {
tree_allocator.deallocate(args, old_arity); tree_allocator.deallocate(args, old_arity);
@ -455,7 +455,7 @@ private :
switch(new_arity) switch(new_arity)
{ {
case 3 : args[2].copy(s.args[2]); args[2].parent = this; // no break! case 3 : args[2].copy(s.args[2]); args[2].parent = this; // no break!
case 2 : args[1].copy(s.args[1]); args[1].parent = this; case 2 : args[1].copy(s.args[1]); args[1].parent = this;
case 1 : args[0].copy(s.args[0]); args[0].parent = this; case 1 : args[0].copy(s.args[0]); args[0].parent = this;
case 0 : break; case 0 : break;
default : default :
@ -467,8 +467,8 @@ private :
} }
} }
} }
*content = *s.content; *content = *s.content;
_size = s._size; _size = s._size;
_depth = s._depth; _depth = s._depth;
_cumulative_size = s._cumulative_size; _cumulative_size = s._cumulative_size;
@ -479,24 +479,24 @@ private :
subtree& copy(const T& t) subtree& copy(const T& t)
{ {
int oldArity = arity(); int oldArity = arity();
if (content != &t) if (content != &t)
*content = t; *content = t;
else else
oldArity = -1; oldArity = -1;
int ar = arity(); int ar = arity();
if (ar != oldArity) if (ar != oldArity)
{ {
if (oldArity != -1) if (oldArity != -1)
tree_allocator.deallocate(args, oldArity); tree_allocator.deallocate(args, oldArity);
args = tree_allocator.allocate(ar); args = tree_allocator.allocate(ar);
//if (ar > 0) //if (ar > 0)
// args = new subtree [ar]; // args = new subtree [ar];
//else //else
// args = 0; // args = 0;
} }
@ -521,7 +521,7 @@ private :
} }
} }
} }
} }
void adopt(void) void adopt(void)
@ -539,7 +539,7 @@ private :
it->parent = this; it->parent = this;
} }
} }
} }
} }
template <class It> template <class It>
@ -582,22 +582,22 @@ private :
parse_tree(void) : _root(), pushed() {} parse_tree(void) : _root(), pushed() {}
parse_tree(const parse_tree& org) : _root(org._root), pushed(org.pushed) { } parse_tree(const parse_tree& org) : _root(org._root), pushed(org.pushed) { }
parse_tree(const subtree& sub) : _root(sub), pushed() { } parse_tree(const subtree& sub) : _root(sub), pushed() { }
template <class It> template <class It>
parse_tree(It b, It e) : _root(b, e), pushed() {} parse_tree(It b, It e) : _root(b, e), pushed() {}
virtual ~parse_tree(void) {} virtual ~parse_tree(void) {}
parse_tree& operator=(const parse_tree& org) { return copy(org); } parse_tree& operator=(const parse_tree& org) { return copy(org); }
parse_tree& operator=(const subtree& sub) parse_tree& operator=(const subtree& sub)
{ return copy(sub); } { return copy(sub); }
/* Equality and inequality */ /* Equality and inequality */
bool operator==(const parse_tree& other) const bool operator==(const parse_tree& other) const
{ return _root == other._root; } { return _root == other._root; }
bool operator !=(const parse_tree& other) const bool operator !=(const parse_tree& other) const
{ return !operator==(other); } { return !operator==(other); }
@ -610,13 +610,13 @@ private :
/* Evaluation (application), with an increasing number of user defined arguments */ /* Evaluation (application), with an increasing number of user defined arguments */
template <class RetVal> template <class RetVal>
void apply(RetVal& v) const void apply(RetVal& v) const
{ _root.apply(v); } { _root.apply(v); }
template <class RetVal, class It> template <class RetVal, class It>
void apply(RetVal& v, It varValues) const void apply(RetVal& v, It varValues) const
{ _root.apply(v, varValues); } { _root.apply(v, varValues); }
template <class RetVal, class It> template <class RetVal, class It>
void apply_mem_func(RetVal& v, It misc, void (T::* f)(RetVal&, typename subtree::iterator, It)) void apply_mem_func(RetVal& v, It misc, void (T::* f)(RetVal&, typename subtree::iterator, It))
{ {
@ -624,11 +624,11 @@ private :
} }
//template <class RetVal, class It, class It2> //template <class RetVal, class It, class It2>
// void apply(RetVal& v, It varValues, It2 moreValues) const // void apply(RetVal& v, It varValues, It2 moreValues) const
// { _root.apply(v, varValues, moreValues); } // { _root.apply(v, varValues, moreValues); }
//template <class RetVal, class It, class It2, class It3> //template <class RetVal, class It, class It2, class It3>
// void apply(RetVal& v, It varValues, It2 moreValues, It3 evenMoreValues) const // void apply(RetVal& v, It varValues, It2 moreValues, It3 evenMoreValues) const
// { _root.apply(v, varValues, moreValues, evenMoreValues); } // { _root.apply(v, varValues, moreValues, evenMoreValues); }
template <class Pred> template <class Pred>
@ -636,13 +636,13 @@ private :
{ {
_root.find_nodes(result, p); _root.find_nodes(result, p);
} }
template <class Pred> template <class Pred>
void find_nodes(std::vector<const subtree*>& result, Pred& p) const void find_nodes(std::vector<const subtree*>& result, Pred& p) const
{ {
_root.find_nodes(p); _root.find_nodes(p);
} }
/* Customized Swap */ /* Customized Swap */
void swap(parse_tree<T>& other) void swap(parse_tree<T>& other)
{ {
@ -655,8 +655,8 @@ private :
class base_iterator class base_iterator
{ {
public : public :
base_iterator() {} base_iterator() {}
base_iterator(subtree* n) { node = n; } base_iterator(subtree* n) { node = n; }
base_iterator& operator=(const base_iterator& org) base_iterator& operator=(const base_iterator& org)
@ -670,7 +670,7 @@ private :
base_iterator operator+(size_t n) const base_iterator operator+(size_t n) const
{ {
base_iterator tmp = *this; base_iterator tmp = *this;
for(;n != 0; --n) for(;n != 0; --n)
{ {
++tmp; ++tmp;
@ -678,7 +678,7 @@ private :
return tmp; return tmp;
} }
base_iterator& operator++(void) base_iterator& operator++(void)
{ {
subtree* parent = node->get_parent(); subtree* parent = node->get_parent();
@ -702,7 +702,7 @@ private :
{ {
node = &(--it)->get_node(0); node = &(--it)->get_node(0);
} }
return *this; return *this;
} }
@ -719,13 +719,16 @@ private :
class iterator : public base_iterator class iterator : public base_iterator
{ {
public : public:
typedef std::forward_iterator_tag iterator_category;
typedef subtree value_type; using base_iterator::node;
typedef size_t distance_type;
typedef size_t difference_type; typedef std::forward_iterator_tag iterator_category;
typedef subtree* pointer; typedef subtree value_type;
typedef subtree& reference; typedef size_t distance_type;
typedef size_t difference_type;
typedef subtree* pointer;
typedef subtree& reference;
iterator() : base_iterator() {} iterator() : base_iterator() {}
iterator(subtree* n): base_iterator(n) {} iterator(subtree* n): base_iterator(n) {}
@ -736,15 +739,20 @@ private :
subtree* operator->(void) { return node; } subtree* operator->(void) { return node; }
}; };
class embedded_iterator : public base_iterator class embedded_iterator : public base_iterator
{ {
public : public:
typedef std::forward_iterator_tag iterator_category;
typedef T value_type; using base_iterator::node;
typedef size_t distance_type;
typedef size_t difference_type; typedef std::forward_iterator_tag iterator_category;
typedef T* pointer; typedef T value_type;
typedef T& reference; typedef size_t distance_type;
typedef size_t difference_type;
typedef T* pointer;
typedef T& reference;
embedded_iterator() : base_iterator() {} embedded_iterator() : base_iterator() {}
embedded_iterator(subtree* n): base_iterator(n) {} embedded_iterator(subtree* n): base_iterator(n) {}
@ -757,7 +765,8 @@ private :
class base_const_iterator class base_const_iterator
{ {
public : public:
base_const_iterator() {} base_const_iterator() {}
base_const_iterator(const subtree* n) { node = n; } base_const_iterator(const subtree* n) { node = n; }
@ -802,19 +811,22 @@ private :
} }
protected : protected :
const subtree* node; const subtree* node;
}; };
class const_iterator : public base_const_iterator class const_iterator : public base_const_iterator
{ {
public : public:
typedef std::forward_iterator_tag iterator_category;
typedef const subtree value_type; using base_iterator::node;
typedef size_t distance_type;
typedef size_t difference_type; typedef std::forward_iterator_tag iterator_category;
typedef const subtree* pointer; typedef const subtree value_type;
typedef const subtree& reference; typedef size_t distance_type;
typedef size_t difference_type;
typedef const subtree* pointer;
typedef const subtree& reference;
const_iterator() : base_const_iterator() {} const_iterator() : base_const_iterator() {}
const_iterator(const subtree* n): base_const_iterator(n) {} const_iterator(const subtree* n): base_const_iterator(n) {}
@ -827,7 +839,10 @@ private :
class embedded_const_iterator : public base_const_iterator class embedded_const_iterator : public base_const_iterator
{ {
public : public:
using base_const_iterator::node;
typedef std::forward_iterator_tag iterator_category; typedef std::forward_iterator_tag iterator_category;
typedef const T value_type; typedef const T value_type;
typedef size_t distance_type; typedef size_t distance_type;
@ -843,7 +858,7 @@ private :
embedded_const_iterator operator+(size_t n) const embedded_const_iterator operator+(size_t n) const
{ {
embedded_const_iterator tmp = *this; embedded_const_iterator tmp = *this;
for(;n != 0; --n) for(;n != 0; --n)
{ {
++tmp; ++tmp;
@ -858,12 +873,12 @@ private :
/* Iterator access */ /* Iterator access */
iterator begin(void) { return iterator(&operator[](0)); } iterator begin(void) { return iterator(&operator[](0)); }
const_iterator begin(void) const { return const_iterator(&operator[](0)); } const_iterator begin(void) const { return const_iterator(&operator[](0)); }
iterator end(void) { return iterator(0); } iterator end(void) { return iterator(0); }
const_iterator end(void) const { return const_iterator(0);} const_iterator end(void) const { return const_iterator(0);}
embedded_iterator ebegin(void) { return embedded_iterator(&operator[](0)); } embedded_iterator ebegin(void) { return embedded_iterator(&operator[](0)); }
embedded_const_iterator ebegin(void) const { return embedded_const_iterator(&operator[](0)); } embedded_const_iterator ebegin(void) const { return embedded_const_iterator(&operator[](0)); }
embedded_iterator eend(void) { return embedded_iterator(0); } embedded_iterator eend(void) { return embedded_iterator(0); }
embedded_const_iterator eend(void) const { return embedded_const_iterator(0);} embedded_const_iterator eend(void) const { return embedded_const_iterator(0);}
@ -885,12 +900,12 @@ private :
{ {
if (!empty()) if (!empty())
pushed.push_back(_root); pushed.push_back(_root);
_root = t; _root = t;
for (typename subtree::iterator it = _root.begin(); it != _root.end(); it++) for (typename subtree::iterator it = _root.begin(); it != _root.end(); it++)
{ {
*it = pushed.back(); *it = pushed.back();
pushed.pop_back(); pushed.pop_back();
} }
@ -902,7 +917,7 @@ private :
const subtree& back(void) const { return _root; } const subtree& back(void) const { return _root; }
subtree& root(void) { return _root; } subtree& root(void) { return _root; }
const subtree& root(void) const { return _root; } const subtree& root(void) const { return _root; }
subtree& front(void) { return _root[0]; } subtree& front(void) { return _root[0]; }
const subtree& front(void) const { return _root[0]; } const subtree& front(void) const { return _root[0]; }
@ -917,13 +932,13 @@ private :
{ return get_cumulative(i); } { return get_cumulative(i); }
private : private :
parse_tree& copy(const parse_tree& org) parse_tree& copy(const parse_tree& org)
{ {
_root = org._root; _root = org._root;
pushed = org.pushed; pushed = org.pushed;
return *this; return *this;
} }
parse_tree& copy(const subtree& sub) parse_tree& copy(const subtree& sub)
@ -939,25 +954,25 @@ private :
namespace std namespace std
{ // for use with stlport on MSVC { // for use with stlport on MSVC
template <class T> inline template <class T> inline
std::forward_iterator_tag iterator_category(typename gp_parse_tree::parse_tree<T>::embedded_iterator) std::forward_iterator_tag iterator_category(typename gp_parse_tree::parse_tree<T>::embedded_iterator)
{ {
return std::forward_iterator_tag(); return std::forward_iterator_tag();
} }
template <class T> inline template <class T> inline
ptrdiff_t* distance_type(typename gp_parse_tree::parse_tree<T>::embedded_iterator) ptrdiff_t* distance_type(typename gp_parse_tree::parse_tree<T>::embedded_iterator)
{ {
return 0; return 0;
} }
template <class T> inline template <class T> inline
std::forward_iterator_tag iterator_category(typename gp_parse_tree::parse_tree<T>::iterator) std::forward_iterator_tag iterator_category(typename gp_parse_tree::parse_tree<T>::iterator)
{ {
return std::forward_iterator_tag(); return std::forward_iterator_tag();
} }
template <class T> inline template <class T> inline
ptrdiff_t* distance_type(typename gp_parse_tree::parse_tree<T>::iterator) ptrdiff_t* distance_type(typename gp_parse_tree::parse_tree<T>::iterator)
{ {
return 0; return 0;

View file

@ -2,10 +2,10 @@
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
eoExternalEO.h eoExternalEO.h
Definition of an object that allows an external struct to be inserted in EO Definition of an object that allows an external struct to be inserted in EO
(c) Maarten Keijzer (mkeijzer@mad.scientist.com) and GeNeura Team, 1999, 2000 (c) Maarten Keijzer (mkeijzer@mad.scientist.com) and GeNeura Team, 1999, 2000
This library is free software; you can redistribute it and/or This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either License as published by the Free Software Foundation; either
@ -28,7 +28,7 @@
#include <EO.h> // EO #include <EO.h> // EO
/** /**
* Definition of an object that allows an external struct * Definition of an object that allows an external struct
* to be inserted in EO. This struct or class can be of any * to be inserted in EO. This struct or class can be of any
* form, the only thing this class does is attach a fitness * form, the only thing this class does is attach a fitness
@ -40,28 +40,33 @@ class eoExternalEO : public EO<Fit>, virtual public External
{ {
public : public :
eoExternalEO(void) : EO<Fit>(), External() {} eoExternalEO(void)
: EO<Fit>(), External()
{}
/** /** Init externalEo with the struct itself and set fitness to zero */
Init externalEo with the struct itself and set fitness to zero eoExternalEO(const External& ext)
*/ : EO<Fit>(), External(ext)
eoExternalEO(const External& ext) : EO<Fit>(), External(ext) {} {}
eoExternalEO(std::istream& is) : EO<Fit>(), External(ext) { readFrom(is); }
eoExternalEO(std::istream& is, const External& ext)
: EO<Fit>(), External(ext)
{ readFrom(is); }
/** /**
* Read object, the external struct needs to have an operator>> defined * Read object, the external struct needs to have an operator>> defined
*/ */
virtual void readFrom(std::istream& _is) virtual void readFrom(std::istream& _is)
{ {
EO<Fit>::readFrom(_is); EO<Fit>::readFrom(_is);
_is >> static_cast<External&>(*this); _is >> static_cast<External&>(*this);
} }
/** /**
* Write object. Called printOn since it prints the object _on_ a stream. * Write object. Called printOn since it prints the object _on_ a stream.
* @param _os A std::ostream. * @param _os A std::ostream.
*/ */
virtual void printOn(std::ostream& _os) const virtual void printOn(std::ostream& _os) const
{ {
EO<Fit>::printOn(_os); EO<Fit>::printOn(_os);
_os << static_cast<const External&>(*this); _os << static_cast<const External&>(*this);

View file

@ -3,7 +3,7 @@
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// eoString.h // eoString.h
// (c) GeNeura Team, 1998 // (c) GeNeura Team, 1998
/* /*
This library is free software; you can redistribute it and/or This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either License as published by the Free Software Foundation; either
@ -26,7 +26,8 @@
#define _eoString_H #define _eoString_H
// STL libraries // STL libraries
#include <string> #include <iostream>
#include <string>
#include <stdexcept> #include <stdexcept>
@ -38,13 +39,14 @@
/** Adaptor that turns an STL std::string into an EO */ /** Adaptor that turns an STL std::string into an EO */
template <class fitnessT > template <class fitnessT >
class eoString: public EO<fitnessT>, public std::string class eoString: public EO<fitnessT>, public std::string
{ {
public: public:
typedef char Type; typedef char Type;
typedef char AtomType; typedef char AtomType;
typedef std::string ContainerType; typedef std::string ContainerType;
/// Canonical part of the objects: several ctors, copy ctor, dtor and assignment operator /// Canonical part of the objects: several ctors, copy ctor, dtor and assignment operator
//@{ //@{
@ -58,7 +60,7 @@ public:
EO<fitnessT>::printOn(os); EO<fitnessT>::printOn(os);
os << ' '; os << ' ';
os << size() << ' ' << substr() << endl; os << size() << ' ' << substr() << std::endl;
} }
@ -66,12 +68,12 @@ public:
readFrom and printOn are directly inherited from eo1d readFrom and printOn are directly inherited from eo1d
*/ */
//@{ //@{
/** Inherited from eoObject /** Inherited from eoObject
@see eoObject @see eoObject
*/ */
virtual std::string className() const {return "eoString";}; virtual std::string className() const {return "eoString";};
//@} //@}
}; };

View file

@ -38,25 +38,29 @@
/** /**
Average fitness values of a population, where the fitness is Average fitness values of a population, where the fitness is
of type eoScalarAssembledFitness. Specify in the constructor, of type eoScalarAssembledFitness. Specify in the constructor,
for which fitness term (index) the average should be evaluated. for which fitness term (index) the average should be evaluated.
Only values of object where the failed boolean = false is set are counted. Only values of object where the failed boolean = false is set are counted.
*/ */
template <class EOT> template <class EOT>
class eoAssembledFitnessAverageStat : public eoStat<EOT, double> class eoAssembledFitnessAverageStat : public eoStat<EOT, double>
{ {
public : public :
typedef typename EOT::Fitness Fitness; using eoAssembledFitnessAverageStat< EOT >::value;
eoAssembledFitnessAverageStat(unsigned _whichTerm=0, std::string _description = "Average Fitness") typedef typename EOT::Fitness Fitness;
: eoStat<EOT, double>(Fitness(), _description), whichFitnessTerm(_whichTerm) {}
virtual void operator()(const eoPop<EOT>& _pop){ eoAssembledFitnessAverageStat(unsigned _whichTerm=0, std::string _description = "Average Fitness")
: eoStat<EOT, double>(Fitness(), _description), whichFitnessTerm(_whichTerm)
if ( whichFitnessTerm >= _pop[0].fitness().size() ) {}
throw std::logic_error("Fitness term requested out of range");
virtual void operator()(const eoPop<EOT>& _pop) {
if( whichFitnessTerm >= _pop[0].fitness().size() )
throw std::logic_error("Fitness term requested out of range");
double result =0.0; double result =0.0;
unsigned count = 0; unsigned count = 0;
for (typename eoPop<EOT>::const_iterator it = _pop.begin(); it != _pop.end(); ++it){ for (typename eoPop<EOT>::const_iterator it = _pop.begin(); it != _pop.end(); ++it){
@ -68,7 +72,7 @@ public :
value() = result / (double) count; value() = result / (double) count;
} }
private: private:
// Store an index of the fitness term to be evaluated in eoScalarFitnessAssembled // Store an index of the fitness term to be evaluated in eoScalarFitnessAssembled
unsigned whichFitnessTerm; unsigned whichFitnessTerm;
@ -76,29 +80,33 @@ private:
/** /**
Fitness values of best individuum in a population, where the fitness is Fitness values of best individuum in a population, where the fitness is
of type eoScalarAssembledFitness. Specify in the constructor, of type eoScalarAssembledFitness. Specify in the constructor,
for which fitness term (index) the value should be evaluated. for which fitness term (index) the value should be evaluated.
*/ */
template <class EOT> template <class EOT>
class eoAssembledFitnessBestStat : public eoStat<EOT, double> class eoAssembledFitnessBestStat : public eoStat<EOT, double>
{ {
public : public:
typedef typename EOT::Fitness Fitness;
using eoAssembledFitnessBestStat< EOT >::value;
eoAssembledFitnessBestStat(unsigned _whichTerm=0, std::string _description = "Best Fitness")
: eoStat<EOT, double>(Fitness(), _description), whichFitnessTerm(_whichTerm) {} typedef typename EOT::Fitness Fitness;
virtual void operator()(const eoPop<EOT>& _pop){ eoAssembledFitnessBestStat(unsigned _whichTerm=0, std::string _description = "Best Fitness")
: eoStat<EOT, double>(Fitness(), _description), whichFitnessTerm(_whichTerm)
if ( whichFitnessTerm >= _pop[0].fitness().size() ) {}
throw std::logic_error("Fitness term requested out of range");
virtual void operator()(const eoPop<EOT>& _pop) {
if( whichFitnessTerm >= _pop[0].fitness().size() )
throw std::logic_error("Fitness term requested out of range");
value() = _pop.best_element().fitness()[whichFitnessTerm];
}
value() = _pop.best_element().fitness()[whichFitnessTerm];
}
private: private:
// Store an index of the fitness term to be evaluated in eoScalarFitnessAssembled
unsigned whichFitnessTerm; // Store an index of the fitness term to be evaluated in eoScalarFitnessAssembled
unsigned whichFitnessTerm;
}; };
#endif #endif

View file

@ -3,7 +3,7 @@
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// eoFDCStat.h // eoFDCStat.h
// (c) Marc Schoenauer, Maarten Keijzer and GeNeura Team, 2000, 2001 // (c) Marc Schoenauer, Maarten Keijzer and GeNeura Team, 2000, 2001
/* /*
This library is free software; you can redistribute it and/or This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either License as published by the Free Software Foundation; either
@ -38,9 +38,11 @@ so they can be snapshot by some eoGnuplotSnapshot ...
template <class EOT> template <class EOT>
class eoFDCStat : public eoStat<EOT, double> class eoFDCStat : public eoStat<EOT, double>
{ {
public : public:
/** Ctor without the optimum
*/ using eoFDCStat < EOT>::value;
/** Ctor without the optimum */
eoFDCStat(eoDistance<EOT> & _dist, std::string _description = "FDC") : eoFDCStat(eoDistance<EOT> & _dist, std::string _description = "FDC") :
eoStat<EOT,double>(0, _description), dist(_dist), boolOpt(false) {} eoStat<EOT,double>(0, _description), dist(_dist), boolOpt(false) {}

View file

@ -36,6 +36,9 @@ template <class EOT, class FitT = typename EOT::Fitness>
class eoFitnessStat : public eoSortedStat<EOT, std::vector<FitT> > class eoFitnessStat : public eoSortedStat<EOT, std::vector<FitT> >
{ {
public : public :
using eoFitnessStat< EOT, FitT >::value;
eoFitnessStat(std::string _description = "AllFitnesses") : eoFitnessStat(std::string _description = "AllFitnesses") :
eoSortedStat<EOT,std::vector<FitT> >(std::vector<FitT>(0), _description) {} eoSortedStat<EOT,std::vector<FitT> >(std::vector<FitT>(0), _description) {}
@ -62,7 +65,10 @@ class eoMOFitnessStat : public eoSortedStat<EOT, std::vector<PartFitT> >
#endif #endif
{ {
public : public:
using eoMOFitnessStat< EOT, PartFitT >::value;
/** Ctor: say what component you want /** Ctor: say what component you want
*/ */
eoMOFitnessStat(unsigned _objective, std::string _description = "MO-Fitness") : eoMOFitnessStat(unsigned _objective, std::string _description = "MO-Fitness") :

View file

@ -3,7 +3,7 @@
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// eoPopStat.h // eoPopStat.h
// (c) Maarten Keijzer, Marc Schoenauer and GeNeura Team, 2001 // (c) Maarten Keijzer, Marc Schoenauer and GeNeura Team, 2001
/* /*
This library is free software; you can redistribute it and/or This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either License as published by the Free Software Foundation; either
@ -43,25 +43,28 @@ that can be used to dump to the screen
/** Thanks to MS/VC++, eoParam mechanism is unable to handle std::vectors of stats. /** Thanks to MS/VC++, eoParam mechanism is unable to handle std::vectors of stats.
This snippet is a workaround: This snippet is a workaround:
This class will "print" a whole population into a std::string - that you can later This class will "print" a whole population into a std::string - that you can later
send to any stream send to any stream
This is the plain version - see eoPopString for the Sorted version This is the plain version - see eoPopString for the Sorted version
Note: this Stat should probably be used only within eoStdOutMonitor, and not Note: this Stat should probably be used only within eoStdOutMonitor, and not
inside an eoFileMonitor, as the eoState construct will work much better there. inside an eoFileMonitor, as the eoState construct will work much better there.
*/ */
template <class EOT> template <class EOT>
class eoPopStat : public eoStat<EOT, std::string> class eoPopStat : public eoStat<EOT, std::string>
{ {
public : public:
/** default Ctor, void std::string by default, as it appears
using eoPopStat< EOT>::value;
/** default Ctor, void std::string by default, as it appears
on the description line once at beginning of evolution. and on the description line once at beginning of evolution. and
is meaningless there. _howMany defaults to 0, that is, the whole is meaningless there. _howMany defaults to 0, that is, the whole
population*/ population*/
eoPopStat(unsigned _howMany = 0, std::string _desc ="") eoPopStat(unsigned _howMany = 0, std::string _desc ="")
: eoStat<EOT, std::string>("", _desc), combien( _howMany) {} : eoStat<EOT, std::string>("", _desc), combien( _howMany) {}
/** Fills the value() of the eoParam with the dump of the population. /** Fills the value() of the eoParam with the dump of the population.
Adds a \n before so it does not get mixed up with the rest of the stats Adds a \n before so it does not get mixed up with the rest of the stats
that are written by the monitor it is probably used from. that are written by the monitor it is probably used from.
@ -73,9 +76,9 @@ void operator()(const eoPop<EOT>& _pop)
unsigned howmany=combien?combien:_pop.size(); unsigned howmany=combien?combien:_pop.size();
for (unsigned i = 0; i < howmany; ++i) for (unsigned i = 0; i < howmany; ++i)
{ {
std::ostringstream os; std::ostringstream os;
os << _pop[i] << std::endl; os << _pop[i] << std::endl;
// paranoid: // paranoid:
value() += os.str(); value() += os.str();
} }
@ -91,7 +94,7 @@ void operator()(const eoPop<EOT>& _pop)
{ {
std::ostrstream os(buffer, 1022); // leave space for emergency terminate std::ostrstream os(buffer, 1022); // leave space for emergency terminate
os << _pop[i] << std::endl << std::ends; os << _pop[i] << std::endl << std::ends;
// paranoid: // paranoid:
buffer[1022] = '\0'; buffer[1022] = '\0';
value() += buffer; value() += buffer;
@ -104,40 +107,45 @@ private:
}; };
/** Thanks to MS/VC++, eoParam mechanism is unable to handle std::vectors of stats. /** Thanks to MS/VC++, eoParam mechanism is unable to handle std::vectors of stats.
This snippet is a workaround: This snippet is a workaround:
This class will "print" a whole population into a std::string - that you can later This class will "print" a whole population into a std::string - that you can later
send to any stream send to any stream
This is the Sorted version - see eoPopString for the plain version This is the Sorted version - see eoPopString for the plain version
Note: this Stat should probably be used only within eoStdOutMonitor, and not Note: this Stat should probably be used only within eoStdOutMonitor, and not
inside an eoFileMonitor, as the eoState construct will work much better there. inside an eoFileMonitor, as the eoState construct will work much better there.
*/ */
template <class EOT> template <class EOT>
class eoSortedPopStat : public eoSortedStat<EOT, std::string> class eoSortedPopStat : public eoSortedStat<EOT, std::string>
{ {
public : public:
/** default Ctor, void std::string by default, as it appears
* on the description line once at beginning of evolution. and using eoSortedPopStat< EOT>::value;
* is meaningless there _howMany defaults to 0, that is, the whole
* population /** default Ctor, void std::string by default, as it appears on
*/ the description line once at beginning of evolution. and is
eoSortedPopStat(unsigned _howMany = 0, std::string _desc ="") : meaningless there _howMany defaults to 0, that is, the whole
eoSortedStat<EOT, std::string>("", _desc) , combien( _howMany) {} population
*/
/** Fills the value() of the eoParam with the dump of the population. eoSortedPopStat(unsigned _howMany = 0, std::string _desc ="")
Adds a \n before so it does not get mixed up with the rest of the stats : eoSortedStat<EOT, std::string>("", _desc) , combien( _howMany)
that are written by the monitor it is probably used from. {}
*/
/** Fills the value() of the eoParam with the dump of the
population. Adds a \n before so it does not get mixed up with
the rest of the stats that are written by the monitor it is
probably used from.
*/
#ifdef HAVE_SSTREAM #ifdef HAVE_SSTREAM
void operator()(const std::vector<const EOT*>& _pop) void operator()(const std::vector<const EOT*>& _pop)
{ {
value() = ""; // empty value() = ""; // empty
unsigned howMany=combien?combien:_pop.size(); unsigned howMany=combien?combien:_pop.size();
for (unsigned i = 0; i < howMany; ++i) for (unsigned i = 0; i < howMany; ++i)
{ {
std::ostringstream os; std::ostringstream os;
os << *_pop[i] << std::endl; os << *_pop[i] << std::endl;
// paranoid: // paranoid:
value() += os.str(); value() += os.str();
} }
@ -146,13 +154,13 @@ public :
void operator()(const std::vector<const EOT*>& _pop) void operator()(const std::vector<const EOT*>& _pop)
{ {
char buffer[1023]; // about one K of space per member char buffer[1023]; // about one K of space per member
value() = ""; // empty value() = ""; // empty
unsigned howMany=combien?combien:_pop.size(); unsigned howMany=combien?combien:_pop.size();
for (unsigned i = 0; i < howMany; ++i) for (unsigned i = 0; i < howMany; ++i)
{ {
std::ostrstream os(buffer, 1022); // leave space for emergency terminate std::ostrstream os(buffer, 1022); // leave space for emergency terminate
os << *_pop[i] << std::endl << std::ends; os << *_pop[i] << std::endl << std::ends;
// paranoid: // paranoid:
buffer[1022] = '\0'; buffer[1022] = '\0';
value() += buffer; value() += buffer;

View file

@ -3,7 +3,7 @@
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// eoScalarFitnessStat.h // eoScalarFitnessStat.h
// (c) Marc Schoenauer, Maarten Keijzer and GeNeura Team, 2000, 2001 // (c) Marc Schoenauer, Maarten Keijzer and GeNeura Team, 2000, 2001
/* /*
This library is free software; you can redistribute it and/or This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either License as published by the Free Software Foundation; either
@ -36,13 +36,16 @@
template <class EOT, class FitT = typename EOT::Fitness> template <class EOT, class FitT = typename EOT::Fitness>
class eoScalarFitnessStat : public eoSortedStat<EOT, std::vector<double> > class eoScalarFitnessStat : public eoSortedStat<EOT, std::vector<double> >
{ {
public : public:
eoScalarFitnessStat(std::string _description = "FitnessES",
eoRealVectorBounds & _bounds = eoDummyVectorNoBounds) : using eoScalarFitnessStat< EOT, FitT >::value;
eoSortedStat<EOT, std::vector<double> >(std::vector<double>(0), _description) ,
eoScalarFitnessStat(std::string _description = "FitnessES",
eoRealVectorBounds & _bounds = eoDummyVectorNoBounds) :
eoSortedStat<EOT, std::vector<double> >(std::vector<double>(0), _description) ,
range(*_bounds[0]) range(*_bounds[0])
{} {}
virtual void operator()(const std::vector<const EOT*>& _popPters) virtual void operator()(const std::vector<const EOT*>& _popPters)
{ {
value().resize(_popPters.size()); value().resize(_popPters.size());

View file

@ -36,8 +36,8 @@
/** /**
Base class for all statistics that need to be calculated Base class for all statistics that need to be calculated
over the (unsorted) population over the (unsorted) population
(I guess it is not really necessary? MS. (I guess it is not really necessary? MS.
Depstd::ends, there might be reasons to have a stat that is not an eoValueParam, Depstd::ends, there might be reasons to have a stat that is not an eoValueParam,
but maybe I'm just kidding myself, MK) but maybe I'm just kidding myself, MK)
*/ */
@ -57,11 +57,18 @@ public:
template <class EOT, class T> template <class EOT, class T>
class eoStat : public eoValueParam<T>, public eoStatBase<EOT> class eoStat : public eoValueParam<T>, public eoStatBase<EOT>
{ {
public : public:
eoStat(T _value, std::string _description) : eoValueParam<T>(_value, _description) {}
virtual std::string className(void) const { return "eoStat"; } eoStat(T _value, std::string _description)
: eoValueParam<T>(_value, _description)
{}
virtual std::string className(void) const
{ return "eoStat"; }
}; };
/** /**
Base class for statistics calculated over a sorted snapshot of the population Base class for statistics calculated over a sorted snapshot of the population
*/ */
@ -87,12 +94,12 @@ public :
}; };
/** /**
Average fitness of a population. Fitness can be: Average fitness of a population. Fitness can be:
- double - double
- eoMinimizingFitness or eoMaximizingFitness - eoMinimizingFitness or eoMaximizingFitness
- eoParetoFitness: - eoParetoFitness:
The average of each objective is evaluated. The average of each objective is evaluated.
( For eoScalarFitnessAssembled user eoAssembledFitnessStat classes.) ( For eoScalarFitnessAssembled user eoAssembledFitnessStat classes.)
*/ */
#ifdef _MSC_VER #ifdef _MSC_VER
@ -102,9 +109,12 @@ template <class EOT> class eoAverageStat : public eoStat<EOT, typename EOT::Fitn
#endif #endif
{ {
public : public :
using eoAverageStat< EOT >::value;
typedef typename EOT::Fitness Fitness; typedef typename EOT::Fitness Fitness;
eoAverageStat(std::string _description = "Average Fitness") eoAverageStat(std::string _description = "Average Fitness")
: eoStat<EOT, Fitness>(Fitness(), _description) {} : eoStat<EOT, Fitness>(Fitness(), _description) {}
static Fitness sumFitness(double _sum, const EOT& _eot){ static Fitness sumFitness(double _sum, const EOT& _eot){
@ -114,15 +124,15 @@ public :
eoAverageStat(double _value, std::string _desc) : eoStat<EOT, double>(_value, _desc) {} eoAverageStat(double _value, std::string _desc) : eoStat<EOT, double>(_value, _desc) {}
virtual void operator()(const eoPop<EOT>& _pop){ virtual void operator()(const eoPop<EOT>& _pop){
doit(_pop, Fitness()); // specializations for scalar and std::vector doit(_pop, Fitness()); // specializations for scalar and std::vector
} }
virtual std::string className(void) const { return "eoAverageStat"; } virtual std::string className(void) const { return "eoAverageStat"; }
private : private :
// Specialization for pareto fitness // Specialization for pareto fitness
template <class T> template <class T>
void doit(const eoPop<EOT>& _pop, eoParetoFitness<T>) void doit(const eoPop<EOT>& _pop, eoParetoFitness<T>)
{ {
@ -139,7 +149,7 @@ private :
value()[o] /= _pop.size(); value()[o] /= _pop.size();
} }
} }
// Default behavior // Default behavior
template <class T> template <class T>
void doit(const eoPop<EOT>& _pop, T) void doit(const eoPop<EOT>& _pop, T)
@ -158,10 +168,16 @@ template <class EOT>
class eoSecondMomentStats : public eoStat<EOT, std::pair<double, double> > class eoSecondMomentStats : public eoStat<EOT, std::pair<double, double> >
{ {
public : public :
using eoSecondMomentStats< EOT >::value;
typedef typename EOT::Fitness fitness_type; typedef typename EOT::Fitness fitness_type;
typedef std::pair<double, double> SquarePair; typedef std::pair<double, double> SquarePair;
eoSecondMomentStats(std::string _description = "Average & Stdev") : eoStat<EOT, SquarePair>(std::make_pair(0.0,0.0), _description) {}
eoSecondMomentStats(std::string _description = "Average & Stdev")
: eoStat<EOT, SquarePair>(std::make_pair(0.0,0.0), _description)
{}
static SquarePair sumOfSquares(SquarePair _sq, const EOT& _eo) static SquarePair sumOfSquares(SquarePair _sq, const EOT& _eo)
{ {
@ -187,7 +203,7 @@ public :
/** /**
The n_th element fitness in the population (see eoBestFitnessStat) The n_th element fitness in the population (see eoBestFitnessStat)
*/ */
#ifdef _MSC_VER #ifdef _MSC_VER
template <class EOT> template <class EOT>
class eoNthElementFitnessStat : public eoSortedStat<EOT, EOT::Fitness > class eoNthElementFitnessStat : public eoSortedStat<EOT, EOT::Fitness >
#else #else
@ -196,9 +212,11 @@ class eoNthElementFitnessStat : public eoSortedStat<EOT, typename EOT::Fitness >
#endif #endif
{ {
public : public :
using eoNthElementFitnessStat< EOT >::value;
typedef typename EOT::Fitness Fitness; typedef typename EOT::Fitness Fitness;
eoNthElementFitnessStat(unsigned _whichElement, std::string _description = "nth element fitness") eoNthElementFitnessStat(unsigned _whichElement, std::string _description = "nth element fitness")
: eoSortedStat<EOT, Fitness>(Fitness(), _description), whichElement(_whichElement) {} : eoSortedStat<EOT, Fitness>(Fitness(), _description), whichElement(_whichElement) {}
virtual void operator()(const std::vector<const EOT*>& _pop) virtual void operator()(const std::vector<const EOT*>& _pop)
@ -211,7 +229,7 @@ public :
virtual std::string className(void) const { return "eoNthElementFitnessStat"; } virtual std::string className(void) const { return "eoNthElementFitnessStat"; }
private : private :
struct CmpFitness struct CmpFitness
{ {
CmpFitness(unsigned _whichElement, bool _maxim) : whichElement(_whichElement), maxim(_maxim) {} CmpFitness(unsigned _whichElement, bool _maxim) : whichElement(_whichElement), maxim(_maxim) {}
@ -246,7 +264,7 @@ private :
value()[o] = (*nth)->fitness()[o]; value()[o] = (*nth)->fitness()[o];
} }
} }
// for everything else // for everything else
template <class T> template <class T>
void doit(const std::vector<const EOT*>& _pop, T) void doit(const std::vector<const EOT*>& _pop, T)
@ -263,7 +281,7 @@ private :
But then again, if another stat needs sorted fitness anyway, getting the best But then again, if another stat needs sorted fitness anyway, getting the best
out would be very fast. out would be very fast.
MK - 09/01/03 MK - 09/01/03
template <class EOT> template <class EOT>
class eoBestFitnessStat : public eoStat<EOT, typename EOT::Fitness > class eoBestFitnessStat : public eoStat<EOT, typename EOT::Fitness >
{ {
@ -282,9 +300,9 @@ public :
*/ */
/** /**
Best fitness of a population. Fitness can be: Best fitness of a population. Fitness can be:
- double - double
- eoMinimizingFitness or eoMaximizingFitness - eoMinimizingFitness or eoMaximizingFitness
- eoParetoFitness: - eoParetoFitness:
( For eoScalarFitnessAssembled look at eoAssembledFitnessStat ) ( For eoScalarFitnessAssembled look at eoAssembledFitnessStat )
@ -298,17 +316,23 @@ template <class EOT>
class eoBestFitnessStat : public eoStat<EOT, typename EOT::Fitness> class eoBestFitnessStat : public eoStat<EOT, typename EOT::Fitness>
#endif #endif
{ {
public : public:
using eoBestFitnessStat< EOT >::value;
typedef typename EOT::Fitness Fitness; typedef typename EOT::Fitness Fitness;
eoBestFitnessStat(std::string _description = "Best ") eoBestFitnessStat(std::string _description = "Best ")
: eoStat<EOT, Fitness>(Fitness(), _description) {} : eoStat<EOT, Fitness>(Fitness(), _description)
{}
void operator()(const eoPop<EOT>& _pop){
doit(_pop, Fitness() ); // specializations for scalar and std::vector void operator()(const eoPop<EOT>& _pop) {
doit(_pop, Fitness() ); // specializations for scalar and std::vector
} }
virtual std::string className(void) const { return "eoBestFitnessStat"; } virtual std::string className(void) const { return "eoBestFitnessStat"; }
private : private :
struct CmpFitness struct CmpFitness
@ -340,7 +364,7 @@ private :
value()[o] = it->fitness()[o]; value()[o] = it->fitness()[o];
} }
} }
// default // default
template<class T> template<class T>
void doit(const eoPop<EOT>& _pop, T) void doit(const eoPop<EOT>& _pop, T)
@ -353,8 +377,13 @@ private :
template <class EOT> template <class EOT>
class eoDistanceStat : public eoStat<EOT, double> class eoDistanceStat : public eoStat<EOT, double>
{ {
public : public:
eoDistanceStat(std::string _name = "distance") : eoStat<EOT, double>(0.0, _name) {}
using eoDistanceStat< EOT >::value;
eoDistanceStat(std::string _name = "distance")
: eoStat<EOT, double>(0.0, _name)
{}
template <class T> template <class T>
double distance(T a, T b) double distance(T a, T b)
@ -405,7 +434,7 @@ public :
virtual void operator()(const eoPop<EOT>& _pop) virtual void operator()(const eoPop<EOT>& _pop)
{ {
SquarePair result = std::accumulate(pop.begin(), pop.end(), std::make_pair(0.0, 0.0), eoSecondMomentStats::sumOfSquares); SquarePair result = std::accumulate(pop.begin(), pop.end(), std::make_pair(0.0, 0.0), eoSecondMomentStats::sumOfSquares);
double n = pop.size(); double n = pop.size();
value() = sqrt( (result.second - (result.first / n)) / (n - 1.0)); // stdev value() = sqrt( (result.second - (result.first / n)) / (n - 1.0)); // stdev
} }

View file

@ -3,7 +3,7 @@
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// eoUpdater.h // eoUpdater.h
// (c) Maarten Keijzer, Marc Schoenauer and GeNeura Team, 2000 // (c) Maarten Keijzer, Marc Schoenauer and GeNeura Team, 2000
/* /*
This library is free software; you can redistribute it and/or This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either License as published by the Free Software Foundation; either
@ -48,7 +48,7 @@ public:
*/ */
template <class T> template <class T>
class eoIncrementor : public eoUpdater class eoIncrementor : public eoUpdater
{public : {public :
/** Default Ctor - requires a reference to the thing to increment */ /** Default Ctor - requires a reference to the thing to increment */
eoIncrementor(T& _counter, T _stepsize = 1) : counter(_counter), stepsize(_stepsize) {} eoIncrementor(T& _counter, T _stepsize = 1) : counter(_counter), stepsize(_stepsize) {}
@ -70,23 +70,26 @@ private:
template <class T> template <class T>
class eoIncrementorParam : public eoUpdater, public eoValueParam<T> class eoIncrementorParam : public eoUpdater, public eoValueParam<T>
{ {
public : public:
using eoIncrementorParam< T >::value;
/** Default Ctor : a name and optionally an increment*/ /** Default Ctor : a name and optionally an increment*/
eoIncrementorParam( std::string _name, T _stepsize = 1) : eoIncrementorParam( std::string _name, T _stepsize = 1) :
eoValueParam<T>(T(0), _name), stepsize(_stepsize) {} eoValueParam<T>(T(0), _name), stepsize(_stepsize) {}
/** Ctor with a name and non-zero initial value /** Ctor with a name and non-zero initial value
* and mandatory stepSize to remove ambiguity * and mandatory stepSize to remove ambiguity
*/ */
eoIncrementorParam( std::string _name, T _countValue, T _stepsize) : eoIncrementorParam( std::string _name, T _countValue, T _stepsize) :
eoValueParam<T>(_countValue, _name), stepsize(_stepsize) {} eoValueParam<T>(_countValue, _name), stepsize(_stepsize) {}
/** Simply increments */ /** Simply increments */
virtual void operator()() virtual void operator()()
{ {
value() += stepsize; value() += stepsize;
} }
virtual std::string className(void) const { return "eoIncrementorParam"; } virtual std::string className(void) const { return "eoIncrementorParam"; }
private: private:
@ -101,7 +104,7 @@ private:
class eoTimedStateSaver : public eoUpdater class eoTimedStateSaver : public eoUpdater
{ {
public : public :
eoTimedStateSaver(time_t _interval, const eoState& _state, std::string _prefix = "state", std::string _extension = "sav") : state(_state), eoTimedStateSaver(time_t _interval, const eoState& _state, std::string _prefix = "state", std::string _extension = "sav") : state(_state),
interval(_interval), last_time(time(0)), first_time(time(0)), interval(_interval), last_time(time(0)), first_time(time(0)),
prefix(_prefix), extension(_extension) {} prefix(_prefix), extension(_extension) {}
@ -124,12 +127,12 @@ private :
class eoCountedStateSaver : public eoUpdater class eoCountedStateSaver : public eoUpdater
{ {
public : public :
eoCountedStateSaver(unsigned _interval, const eoState& _state, std::string _prefix, bool _saveOnLastCall, std::string _extension = "sav", unsigned _counter = 0) eoCountedStateSaver(unsigned _interval, const eoState& _state, std::string _prefix, bool _saveOnLastCall, std::string _extension = "sav", unsigned _counter = 0)
: state(_state), interval(_interval), counter(_counter), : state(_state), interval(_interval), counter(_counter),
saveOnLastCall(_saveOnLastCall), saveOnLastCall(_saveOnLastCall),
prefix(_prefix), extension(_extension) {} prefix(_prefix), extension(_extension) {}
eoCountedStateSaver(unsigned _interval, const eoState& _state, std::string _prefix = "state", std::string _extension = "sav", unsigned _counter = 0) eoCountedStateSaver(unsigned _interval, const eoState& _state, std::string _prefix = "state", std::string _extension = "sav", unsigned _counter = 0)
: state(_state), interval(_interval), counter(_counter), : state(_state), interval(_interval), counter(_counter),
saveOnLastCall(true), saveOnLastCall(true),
prefix(_prefix), extension(_extension) {} prefix(_prefix), extension(_extension) {}
@ -145,7 +148,7 @@ private :
const unsigned interval; const unsigned interval;
unsigned counter; unsigned counter;
bool saveOnLastCall; bool saveOnLastCall;
const std::string prefix; const std::string prefix;
const std::string extension; const std::string extension;
}; };

View file

@ -9,7 +9,7 @@
template <class EOT> template <class EOT>
const EOT& select(const eoPop<EOT>& pop, params, eoRng& gen = rng); const EOT& select(const eoPop<EOT>& pop, params, eoRng& gen = rng);
template <class EOT> template <class EOT>
EOT& select(eoPop<EOT>& pop, params, eoRng& gen = rng); EOT& select(eoPop<EOT>& pop, params, eoRng& gen = rng);
@ -17,7 +17,7 @@
and stochastic_tournament (at the moment). and stochastic_tournament (at the moment).
(c) Maarten Keijzer (mak@dhi.dk) and GeNeura Team, 1999, 2000 (c) Maarten Keijzer (mak@dhi.dk) and GeNeura Team, 1999, 2000
This library is free software; you can redistribute it and/or This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either License as published by the Free Software Foundation; either
@ -50,32 +50,32 @@ template <class EOT>
bool minimizing_fitness() bool minimizing_fitness()
{ {
EOT eo1; // Assuming people don't do anything fancy in the default constructor! EOT eo1; // Assuming people don't do anything fancy in the default constructor!
EOT eo2; EOT eo2;
/* Dear user, when the two line below do not compile you are most /* Dear user, when the two line below do not compile you are most
likely not working with scalar fitness values. In that case we're sorry likely not working with scalar fitness values. In that case we're sorry
but you cannot use lottery or roulette_wheel selection... but you cannot use lottery or roulette_wheel selection...
*/ */
#ifdef _MSC_VER #ifdef _MSC_VER
eo1.fitness( EOT::Fitness(0.0) ); eo1.fitness( EOT::Fitness(0.0) );
eo2.fitness( EOT::Fitness(1.0) ); eo2.fitness( EOT::Fitness(1.0) );
#else #else
eo1.fitness( typename EOT::Fitness(0.0) ); // tried to cast it to an EOT::Fitness, but for some reason GNU barfs on this eo1.fitness( typename EOT::Fitness(0.0) ); // tried to cast it to an EOT::Fitness, but for some reason GNU barfs on this
eo2.fitness( typename EOT::Fitness(1.0) ); eo2.fitness( typename EOT::Fitness(1.0) );
#endif #endif
return eo2 < eo1; // check whether we have a minimizing fitness return eo2 < eo1; // check whether we have a minimizing fitness
}; };
inline double scale_fitness(const std::pair<double, double>& _minmax, double _value) inline double scale_fitness(const std::pair<double, double>& _minmax, double _value)
{ {
if (_minmax.first == _minmax.second) if (_minmax.first == _minmax.second)
{ {
return 0.0; // no differences in fitness, population converged! return 0.0; // no differences in fitness, population converged!
} }
// else // else
return (_value - _minmax.first) / (_minmax.second - _minmax.first); return (_value - _minmax.first) / (_minmax.second - _minmax.first);
} }
@ -104,6 +104,8 @@ double sum_fitness(const eoPop<EOT>& _pop)
template <class EOT> template <class EOT>
double sum_fitness(const eoPop<EOT>& _pop, std::pair<double, double>& _minmax) double sum_fitness(const eoPop<EOT>& _pop, std::pair<double, double>& _minmax)
{ {
double rawTotal, scaledTotal;
typename eoPop<EOT>::const_iterator it = _pop.begin(); typename eoPop<EOT>::const_iterator it = _pop.begin();
_minmax.first = it->fitness(); _minmax.first = it->fitness();
@ -112,13 +114,13 @@ double sum_fitness(const eoPop<EOT>& _pop, std::pair<double, double>& _minmax)
for(; it != _pop.end(); ++it) for(; it != _pop.end(); ++it)
{ {
double v = static_cast<double>(it->fitness()); double v = static_cast<double>(it->fitness());
_minmax.first = std::min(_minmax.first, v); _minmax.first = std::min(_minmax.first, v);
_minmax.second = max(_minmax.second, v); _minmax.second = std::max(_minmax.second, v);
rawTotal += v; rawTotal += v;
} }
if (minimizing_fitness<EOT>()) if (minimizing_fitness<EOT>())
{ {
std::swap(_minmax.first, _minmax.second); std::swap(_minmax.first, _minmax.second);
@ -129,10 +131,12 @@ double sum_fitness(const eoPop<EOT>& _pop, std::pair<double, double>& _minmax)
// unfortunately a second loop is neccessary to scale the fitness // unfortunately a second loop is neccessary to scale the fitness
for (it = _pop.begin(); it != _pop.end(); ++it) for (it = _pop.begin(); it != _pop.end(); ++it)
{ {
double v = scale_fitness(static_cast<double>(it->fitness())); double v = scale_fitness(_minmax, static_cast<double>(it->fitness()));
scaledTotal += v; scaledTotal += v;
} }
return scaledTotal;
} }
template <class It> template <class It>
@ -143,14 +147,14 @@ It roulette_wheel(It _begin, It _end, double total, eoRng& _gen = rng)
if (roulette == 0.0) // covers the case where total==0.0 if (roulette == 0.0) // covers the case where total==0.0
return _begin + _gen.random(_end - _begin); // uniform choice return _begin + _gen.random(_end - _begin); // uniform choice
It i = _begin; It i = _begin;
while (roulette > 0.0) while (roulette > 0.0)
{ {
roulette -= static_cast<double>(*(i++)); roulette -= static_cast<double>(*(i++));
} }
return --i; return --i;
} }
@ -158,43 +162,43 @@ template <class EOT>
const EOT& roulette_wheel(const eoPop<EOT>& _pop, double total, eoRng& _gen = rng) const EOT& roulette_wheel(const eoPop<EOT>& _pop, double total, eoRng& _gen = rng)
{ {
float roulette = _gen.uniform(total); float roulette = _gen.uniform(total);
if (roulette == 0.0) // covers the case where total==0.0 if (roulette == 0.0) // covers the case where total==0.0
return _pop[_gen.random(_pop.size())]; // uniform choice return _pop[_gen.random(_pop.size())]; // uniform choice
typename eoPop<EOT>::const_iterator i = _pop.begin(); typename eoPop<EOT>::const_iterator i = _pop.begin();
while (roulette > 0.0) while (roulette > 0.0)
{ {
roulette -= static_cast<double>((i++)->fitness()); roulette -= static_cast<double>((i++)->fitness());
} }
return *--i; return *--i;
} }
template <class EOT> template <class EOT>
EOT& roulette_wheel(eoPop<EOT>& _pop, double total, eoRng& _gen = rng) EOT& roulette_wheel(eoPop<EOT>& _pop, double total, eoRng& _gen = rng)
{ {
float roulette = _gen.uniform(total); float roulette = _gen.uniform(total);
if (roulette == 0.0) // covers the case where total==0.0 if (roulette == 0.0) // covers the case where total==0.0
return _pop[_gen.random(_pop.size())]; // uniform choice return _pop[_gen.random(_pop.size())]; // uniform choice
typename eoPop<EOT>::iterator i = _pop.begin(); typename eoPop<EOT>::iterator i = _pop.begin();
while (roulette > 0.0) while (roulette > 0.0)
{ {
roulette -= static_cast<double>((i++)->fitness()); roulette -= static_cast<double>((i++)->fitness());
} }
return *--i; return *--i;
} }
template <class It> template <class It>
It deterministic_tournament(It _begin, It _end, unsigned _t_size, eoRng& _gen = rng) It deterministic_tournament(It _begin, It _end, unsigned _t_size, eoRng& _gen = rng)
{ {
It best = _begin + _gen.random(_end - _begin); It best = _begin + _gen.random(_end - _begin);
for (unsigned i = 0; i < _t_size - 1; ++i) for (unsigned i = 0; i < _t_size - 1; ++i)
{ {
It competitor = _begin + _gen.random(_end - _begin); It competitor = _begin + _gen.random(_end - _begin);
@ -223,8 +227,8 @@ EOT& deterministic_tournament(eoPop<EOT>& _pop, unsigned _t_size, eoRng& _gen =
template <class It> template <class It>
It inverse_deterministic_tournament(It _begin, It _end, unsigned _t_size, eoRng& _gen = rng) It inverse_deterministic_tournament(It _begin, It _end, unsigned _t_size, eoRng& _gen = rng)
{ {
It worst = _begin + _gen.random(_end - _begin); It worst = _begin + _gen.random(_end - _begin);
for (unsigned i = 1; i < _t_size; ++i) for (unsigned i = 1; i < _t_size; ++i)
{ {
It competitor = _begin + _gen.random(_end - _begin); It competitor = _begin + _gen.random(_end - _begin);
@ -257,27 +261,27 @@ EOT& inverse_deterministic_tournament(eoPop<EOT>& _pop, unsigned _t_size, eoRng&
} }
template <class It> template <class It>
It stochastic_tournament(It _begin, It _end, double _t_rate, eoRng& _gen = rng) It stochastic_tournament(It _begin, It _end, double _t_rate, eoRng& _gen = rng)
{ {
It i1 = _begin + _gen.random(_end - _begin); It i1 = _begin + _gen.random(_end - _begin);
It i2 = _begin + _gen.random(_end - _begin); It i2 = _begin + _gen.random(_end - _begin);
bool return_better = _gen.flip(_t_rate); bool return_better = _gen.flip(_t_rate);
if (*i1 < *i2) if (*i1 < *i2)
{ {
if (return_better) return i2; if (return_better) return i2;
// else // else
return i1; return i1;
} }
else else
{ {
if (return_better) return i1; if (return_better) return i1;
// else // else
} }
// else // else
return i2; return i2;
} }
@ -294,27 +298,27 @@ EOT& stochastic_tournament(eoPop<EOT>& _pop, double _t_rate, eoRng& _gen = rng)
} }
template <class It> template <class It>
It inverse_stochastic_tournament(It _begin, It _end, double _t_rate, eoRng& _gen = rng) It inverse_stochastic_tournament(It _begin, It _end, double _t_rate, eoRng& _gen = rng)
{ {
It i1 = _begin + _gen.random(_end - _begin); It i1 = _begin + _gen.random(_end - _begin);
It i2 = _begin + _gen.random(_end - _begin); It i2 = _begin + _gen.random(_end - _begin);
bool return_worse = _gen.flip(_t_rate); bool return_worse = _gen.flip(_t_rate);
if (*i1 < *i2) if (*i1 < *i2)
{ {
if (return_worse) return i1; if (return_worse) return i1;
// else // else
return i2; return i2;
} }
else else
{ {
if (return_worse) return i2; if (return_worse) return i2;
// else // else
} }
// else // else
return i1; return i1;
} }

View file

@ -29,25 +29,25 @@ int main()
unsigned i; unsigned i;
eoBooleanGenerator gen; eoBooleanGenerator gen;
// the populations: // the populations:
eoPop<Chrom> pop; eoPop<Chrom> pop;
// Evaluation // Evaluation
RoyalRoad<Chrom> rr( 8 ); RoyalRoad<Chrom> rr( 8 );
eoEvalFuncCounter<Chrom> eval( rr ); eoEvalFuncCounter<Chrom> eval( rr );
eoInitVirus1bit<float> random(CHROM_SIZE, gen); eoInitVirus1bit<float> random(CHROM_SIZE, gen);
for (i = 0; i < POP_SIZE; ++i) { for (i = 0; i < POP_SIZE; ++i) {
Chrom chrom; Chrom chrom;
random(chrom); random(chrom);
eval(chrom); eval(chrom);
pop.push_back(chrom); pop.push_back(chrom);
} }
std::cout << "population:" << std::endl; std::cout << "population:" << std::endl;
for (i = 0; i < pop.size(); ++i) for (i = 0; i < pop.size(); ++i)
std::cout << "\t" << pop[i] << " " << pop[i].fitness() << std::endl; std::cout << "\t" << pop[i] << " " << pop[i].fitness() << std::endl;
// selection // selection
eoStochTournamentSelect<Chrom> lottery(0.9 ); eoStochTournamentSelect<Chrom> lottery(0.9 );
@ -62,14 +62,14 @@ int main()
propSel.add(vf, 0.05); propSel.add(vf, 0.05);
propSel.add(vt, 0.05); propSel.add(vt, 0.05);
propSel.add(xover, 0.1); propSel.add(xover, 0.1);
// Replace a single one // Replace a single one
eoCommaReplacement<Chrom> replace; eoCommaReplacement<Chrom> replace;
// Terminators // Terminators
eoGenContinue<Chrom> continuator1(10); eoGenContinue<Chrom> continuator1(10);
eoFitContinue<Chrom> continuator2(CHROM_SIZE); eoFitContinue<Chrom> continuator2(CHROM_SIZE);
eoCombinedContinue<Chrom> continuator(continuator1, continuator2); eoCombinedContinue<Chrom> continuator(continuator1, continuator2);
eoCheckPoint<Chrom> checkpoint(continuator); eoCheckPoint<Chrom> checkpoint(continuator);
eoStdoutMonitor monitor; eoStdoutMonitor monitor;
checkpoint.add(monitor); checkpoint.add(monitor);
@ -83,22 +83,26 @@ int main()
eoEasyEA<Chrom> ea(checkpoint, eval, breeder, replace); eoEasyEA<Chrom> ea(checkpoint, eval, breeder, replace);
// evolution // evolution
try try {
{
ea(pop); ea(pop);
} } catch (std::exception& e) {
catch (std::exception& e) std::cerr << "exception: " << e.what() << std::endl;;
{
std::cout << "exception: " << e.what() << std::endl;;
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
std::cout << "pop" << std::endl; std::cout << "pop" << std::endl;
for (i = 0; i < pop.size(); ++i) for (i = 0; i < pop.size(); ++i)
std::cout << "\t" << pop[i] << " " << pop[i].fitness() << std::endl; std::cout << "\t" << pop[i] << " " << pop[i].fitness() << std::endl;
std::cout << "\n --> Number of Evaluations = " << eval.getValue() << std::endl; std::cout << "\n --> Number of Evaluations = " << eval.getValue() << std::endl;
return 0; return EXIT_SUCCESS;
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Local Variables:
// mode: C++
// c-file-style: "Stroustrup"
// End:

View file

@ -79,17 +79,27 @@ class Init : public eoInit<eoDouble>
} }
}; };
// Trying out an elitist non-dominated sorted replacement scheme /** @brief An elitist non-dominated sorted replacement scheme.
Trying out an elitist non-dominated sorted replacement scheme.
*/
template <class EOT, class WorthT = double> template <class EOT, class WorthT = double>
class eoNDPlusReplacement : public eoReplacement<EOT> class eoNDPlusReplacement : public eoReplacement<EOT>
{ {
public: public:
eoNDPlusReplacement(eoPerf2Worth<EOT, WorthT>& _perf2worth) : perf2worth(_perf2worth) {}
struct WorthPair : public pair<WorthT, const EOT*> // using eoNDPlusReplacement< EOT, WorthT >::first;
{
bool operator<(const WorthPair& other) const { return other.first < first; } eoNDPlusReplacement(eoPerf2Worth<EOT, WorthT>& _perf2worth)
}; : perf2worth(_perf2worth)
{}
struct WorthPair : public pair<WorthT, const EOT*>
{
bool operator<(const WorthPair& other) const
{ return other.first < this->first; }
};
void operator()(eoPop<EOT>& _parents, eoPop<EOT>& _offspring) void operator()(eoPop<EOT>& _parents, eoPop<EOT>& _offspring)
{ {
@ -106,7 +116,7 @@ public:
} }
private : private :
eoPerf2Worth<EOT, WorthT>& perf2worth; eoPerf2Worth<EOT, WorthT>& perf2worth;
}; };
template <class EOT> template <class EOT>
@ -232,3 +242,9 @@ int main(int argc, char* argv[])
} }
} }
// Local Variables:
// mode: C++
// c-file-style: "Stroustrup"
// End: