Changed some files for compatibility with MSVC 2003 and 2005
This commit is contained in:
parent
359c5ba8ec
commit
219e9bd648
7 changed files with 890 additions and 876 deletions
|
|
@ -1,91 +1,91 @@
|
|||
// -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*-
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// eoFitnessStat.h
|
||||
// (c) Marc Schoenauer, Maarten Keijzer and GeNeura Team, 2000, 2001
|
||||
/*
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
Contact: todos@geneura.ugr.es, http://geneura.ugr.es
|
||||
Marc.Schoenauer@polytechnique.fr
|
||||
mkeijzer@dhi.dk
|
||||
*/
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef _eoFitnessStat_h
|
||||
#define _eoFitnessStat_h
|
||||
|
||||
#include <utils/eoStat.h>
|
||||
|
||||
/**
|
||||
The fitnesses of a whole population, as a vector
|
||||
*/
|
||||
template <class EOT, class FitT = typename EOT::Fitness>
|
||||
class eoFitnessStat : public eoSortedStat<EOT, std::vector<FitT> >
|
||||
{
|
||||
public :
|
||||
|
||||
using eoSortedStat<EOT, std::vector<FitT> >::value;
|
||||
|
||||
eoFitnessStat(std::string _description = "AllFitnesses") :
|
||||
eoSortedStat<EOT,std::vector<FitT> >(std::vector<FitT>(0), _description) {}
|
||||
|
||||
virtual void operator()(const std::vector<const EOT*>& _popPters)
|
||||
{
|
||||
value().resize(_popPters.size());
|
||||
for (unsigned i=0; i<_popPters.size(); i++)
|
||||
value()[i] = _popPters[i]->fitness();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/** For multi-objective fitness, we need to translate a stat<vector<double> >
|
||||
into a vector<stat>, so each objective gets a seperate stat
|
||||
*/
|
||||
#ifdef _MSC_VER
|
||||
// The follownig is needed to avoid some bug in Visual Studio 6.0
|
||||
typedef double PartFitDefault;
|
||||
template <class EOT, class PartFitT = PartFitDefault>
|
||||
class eoMOFitnessStat : public eoSortedStat<EOT, std::vector<PartFitT> >
|
||||
#else
|
||||
template <class EOT, class PartFitT = double>
|
||||
class eoMOFitnessStat : public eoSortedStat<EOT, std::vector<PartFitT> >
|
||||
#endif
|
||||
|
||||
{
|
||||
public:
|
||||
|
||||
using eoSortedStat<EOT, std::vector<PartFitT> >::value;
|
||||
|
||||
/** Ctor: say what component you want
|
||||
*/
|
||||
eoMOFitnessStat(unsigned _objective, std::string _description = "MO-Fitness") :
|
||||
eoSortedStat<EOT, std::vector<PartFitT> >(std::vector<PartFitT>(0), _description),
|
||||
objective(_objective) {}
|
||||
|
||||
virtual void operator()(const std::vector<const EOT*>& _popPters)
|
||||
{
|
||||
value().resize(_popPters.size());
|
||||
|
||||
for (unsigned i=0; i<_popPters.size(); i++)
|
||||
{
|
||||
value()[i] = _popPters[i]->fitness()[objective];
|
||||
}
|
||||
}
|
||||
private:
|
||||
unsigned int objective; // The objective we're storing
|
||||
|
||||
};
|
||||
#endif
|
||||
// -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*-
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// eoFitnessStat.h
|
||||
// (c) Marc Schoenauer, Maarten Keijzer and GeNeura Team, 2000, 2001
|
||||
/*
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
Contact: todos@geneura.ugr.es, http://geneura.ugr.es
|
||||
Marc.Schoenauer@polytechnique.fr
|
||||
mkeijzer@dhi.dk
|
||||
*/
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef _eoFitnessStat_h
|
||||
#define _eoFitnessStat_h
|
||||
|
||||
#include <utils/eoStat.h>
|
||||
|
||||
/**
|
||||
The fitnesses of a whole population, as a vector
|
||||
*/
|
||||
template <class EOT, class FitT = typename EOT::Fitness>
|
||||
class eoFitnessStat : public eoSortedStat<EOT, std::vector<FitT> >
|
||||
{
|
||||
public :
|
||||
|
||||
using eoSortedStat<EOT, std::vector<FitT> >::value;
|
||||
|
||||
eoFitnessStat(std::string _description = "AllFitnesses") :
|
||||
eoSortedStat<EOT,std::vector<FitT> >(std::vector<FitT>(0), _description) {}
|
||||
|
||||
virtual void operator()(const std::vector<const EOT*>& _popPters)
|
||||
{
|
||||
value().resize(_popPters.size());
|
||||
for (unsigned i=0; i<_popPters.size(); i++)
|
||||
value()[i] = _popPters[i]->fitness();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/** For multi-objective fitness, we need to translate a stat<vector<double> >
|
||||
into a vector<stat>, so each objective gets a seperate stat
|
||||
*/
|
||||
#ifdef _MSC_VER
|
||||
// The follownig is needed to avoid some bug in Visual Studio 6.0
|
||||
typedef double PartFitDefault;
|
||||
template <class EOT, class PartFitT = PartFitDefault>
|
||||
class eoMOFitnessStat : public eoSortedStat<EOT, std::vector<PartFitT> >
|
||||
#else
|
||||
template <class EOT, class PartFitT = double>
|
||||
class eoMOFitnessStat : public eoSortedStat<EOT, std::vector<PartFitT> >
|
||||
#endif
|
||||
|
||||
{
|
||||
public:
|
||||
|
||||
using eoSortedStat<EOT, std::vector<PartFitT> >::value;
|
||||
|
||||
/** Ctor: say what component you want
|
||||
*/
|
||||
eoMOFitnessStat(unsigned _objective, std::string _description = "MO-Fitness") :
|
||||
eoSortedStat<EOT, std::vector<PartFitT> >(std::vector<PartFitT>(0), _description),
|
||||
objective(_objective) {}
|
||||
|
||||
virtual void operator()(const std::vector<const EOT*>& _popPters)
|
||||
{
|
||||
value().resize(_popPters.size());
|
||||
|
||||
for (unsigned i=0; i<_popPters.size(); i++)
|
||||
{
|
||||
value()[i] = _popPters[i]->fitness()[objective];
|
||||
}
|
||||
}
|
||||
private:
|
||||
unsigned int objective; // The objective we're storing
|
||||
|
||||
};
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -32,11 +32,19 @@ Contact: todos@geneura.ugr.es, http://geneura.ugr.es
|
|||
//
|
||||
// The C99-standard defines uint32_t to be declared in stdint.h, but some
|
||||
// systmes don't have that and implement it in inttypes.h.
|
||||
|
||||
// first if check added for MSVC by Jeroen Eggermont 20-11-2006, needed for MSVC 2003 (and 2005)
|
||||
# if (defined _MSC_VER)
|
||||
typedef unsigned long uint32_t;
|
||||
#include <cmath>
|
||||
#else
|
||||
#if (! defined __sun)
|
||||
#include <stdint.h>
|
||||
#else
|
||||
#include <inttypes.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
#include <vector>
|
||||
#include "eoPersistent.h"
|
||||
|
|
|
|||
|
|
@ -102,7 +102,7 @@ public :
|
|||
|
||||
( For eoScalarFitnessAssembled user eoAssembledFitnessStat classes.)
|
||||
*/
|
||||
#ifdef _MSC_VER
|
||||
#if defined(_MSC_VER) && (_MSC_VER < 1300)
|
||||
template <class EOT> class eoAverageStat : public eoStat<EOT, EOT::Fitness>
|
||||
#else
|
||||
template <class EOT> class eoAverageStat : public eoStat<EOT, typename EOT::Fitness>
|
||||
|
|
@ -203,7 +203,7 @@ public :
|
|||
/**
|
||||
The n_th element fitness in the population (see eoBestFitnessStat)
|
||||
*/
|
||||
#ifdef _MSC_VER
|
||||
#if defined(_MSC_VER) && (_MSC_VER < 1300)
|
||||
template <class EOT>
|
||||
class eoNthElementFitnessStat : public eoSortedStat<EOT, EOT::Fitness >
|
||||
#else
|
||||
|
|
@ -308,7 +308,7 @@ public :
|
|||
( For eoScalarFitnessAssembled look at eoAssembledFitnessStat )
|
||||
*/
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#if defined(_MSC_VER) && (_MSC_VER < 1300)
|
||||
template <class EOT>
|
||||
class eoBestFitnessStat : public eoStat<EOT, EOT::Fitness>
|
||||
#else
|
||||
|
|
|
|||
|
|
@ -1,338 +1,338 @@
|
|||
/* -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*-
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
selectors.h
|
||||
A bunch of useful selector functions. They generally have three forms:
|
||||
|
||||
template <class It>
|
||||
It select(It begin, It end, params, eoRng& gen = rng);
|
||||
|
||||
template <class EOT>
|
||||
const EOT& select(const eoPop<EOT>& pop, params, eoRng& gen = rng);
|
||||
|
||||
template <class EOT>
|
||||
EOT& select(eoPop<EOT>& pop, params, eoRng& gen = rng);
|
||||
|
||||
where select is one of: roulette_wheel, deterministic_tournament
|
||||
and stochastic_tournament (at the moment).
|
||||
|
||||
(c) Maarten Keijzer (mak@dhi.dk) and GeNeura Team, 1999, 2000
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
Contact: todos@geneura.ugr.es, http://geneura.ugr.es
|
||||
*/
|
||||
|
||||
#ifndef SELECT__H
|
||||
#define SELECT__H
|
||||
|
||||
#include <stdexcept>
|
||||
|
||||
#include "eoRNG.h"
|
||||
#include <eoPop.h>
|
||||
/**
|
||||
\defgroup selectors
|
||||
*/
|
||||
|
||||
template <class EOT>
|
||||
bool minimizing_fitness()
|
||||
{
|
||||
EOT eo1; // Assuming people don't do anything fancy in the default constructor!
|
||||
EOT eo2;
|
||||
|
||||
/* 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
|
||||
but you cannot use lottery or roulette_wheel selection...
|
||||
*/
|
||||
|
||||
#ifdef _MSC_VER
|
||||
eo1.fitness( EOT::Fitness(0.0) );
|
||||
eo2.fitness( EOT::Fitness(1.0) );
|
||||
#else
|
||||
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) );
|
||||
#endif
|
||||
|
||||
return eo2 < eo1; // check whether we have a minimizing fitness
|
||||
}
|
||||
|
||||
inline double scale_fitness(const std::pair<double, double>& _minmax, double _value)
|
||||
{
|
||||
if (_minmax.first == _minmax.second)
|
||||
{
|
||||
return 0.0; // no differences in fitness, population converged!
|
||||
}
|
||||
// else
|
||||
|
||||
return (_value - _minmax.first) / (_minmax.second - _minmax.first);
|
||||
}
|
||||
|
||||
template <class It>
|
||||
double sum_fitness(It begin, It end)
|
||||
{
|
||||
double sum = 0.0;
|
||||
|
||||
for (; begin != end; ++begin)
|
||||
{
|
||||
double v = static_cast<double>(begin->fitness());
|
||||
if (v < 0.0)
|
||||
throw std::logic_error("sum_fitness: negative fitness value encountered");
|
||||
sum += v;
|
||||
}
|
||||
|
||||
return sum;
|
||||
}
|
||||
|
||||
template <class EOT>
|
||||
double sum_fitness(const eoPop<EOT>& _pop)
|
||||
{
|
||||
return sum_fitness(_pop.begin(), _pop.end());
|
||||
}
|
||||
|
||||
template <class EOT>
|
||||
double sum_fitness(const eoPop<EOT>& _pop, std::pair<double, double>& _minmax)
|
||||
{
|
||||
double rawTotal, scaledTotal;
|
||||
|
||||
typename eoPop<EOT>::const_iterator it = _pop.begin();
|
||||
|
||||
_minmax.first = it->fitness();
|
||||
_minmax.second = it++->fitness();
|
||||
|
||||
for(; it != _pop.end(); ++it)
|
||||
{
|
||||
double v = static_cast<double>(it->fitness());
|
||||
|
||||
_minmax.first = std::min(_minmax.first, v);
|
||||
_minmax.second = std::max(_minmax.second, v);
|
||||
|
||||
rawTotal += v;
|
||||
}
|
||||
|
||||
if (minimizing_fitness<EOT>())
|
||||
{
|
||||
std::swap(_minmax.first, _minmax.second);
|
||||
}
|
||||
|
||||
scaledTotal = 0.0;
|
||||
|
||||
// unfortunately a second loop is neccessary to scale the fitness
|
||||
for (it = _pop.begin(); it != _pop.end(); ++it)
|
||||
{
|
||||
double v = scale_fitness(_minmax, static_cast<double>(it->fitness()));
|
||||
|
||||
scaledTotal += v;
|
||||
}
|
||||
|
||||
return scaledTotal;
|
||||
}
|
||||
|
||||
template <class It>
|
||||
It roulette_wheel(It _begin, It _end, double total, eoRng& _gen = rng)
|
||||
{
|
||||
|
||||
float roulette = _gen.uniform(total);
|
||||
|
||||
if (roulette == 0.0) // covers the case where total==0.0
|
||||
return _begin + _gen.random(_end - _begin); // uniform choice
|
||||
|
||||
It i = _begin;
|
||||
|
||||
while (roulette > 0.0)
|
||||
{
|
||||
roulette -= static_cast<double>(*(i++));
|
||||
}
|
||||
|
||||
return --i;
|
||||
}
|
||||
|
||||
template <class EOT>
|
||||
const EOT& roulette_wheel(const eoPop<EOT>& _pop, double total, eoRng& _gen = rng)
|
||||
{
|
||||
float roulette = _gen.uniform(total);
|
||||
|
||||
if (roulette == 0.0) // covers the case where total==0.0
|
||||
return _pop[_gen.random(_pop.size())]; // uniform choice
|
||||
|
||||
typename eoPop<EOT>::const_iterator i = _pop.begin();
|
||||
|
||||
while (roulette > 0.0)
|
||||
{
|
||||
roulette -= static_cast<double>((i++)->fitness());
|
||||
}
|
||||
|
||||
return *--i;
|
||||
}
|
||||
|
||||
template <class EOT>
|
||||
EOT& roulette_wheel(eoPop<EOT>& _pop, double total, eoRng& _gen = rng)
|
||||
{
|
||||
float roulette = _gen.uniform(total);
|
||||
|
||||
if (roulette == 0.0) // covers the case where total==0.0
|
||||
return _pop[_gen.random(_pop.size())]; // uniform choice
|
||||
|
||||
typename eoPop<EOT>::iterator i = _pop.begin();
|
||||
|
||||
while (roulette > 0.0)
|
||||
{
|
||||
roulette -= static_cast<double>((i++)->fitness());
|
||||
}
|
||||
|
||||
return *--i;
|
||||
}
|
||||
|
||||
template <class It>
|
||||
It deterministic_tournament(It _begin, It _end, unsigned _t_size, eoRng& _gen = rng)
|
||||
{
|
||||
It best = _begin + _gen.random(_end - _begin);
|
||||
|
||||
for (unsigned i = 0; i < _t_size - 1; ++i)
|
||||
{
|
||||
It competitor = _begin + _gen.random(_end - _begin);
|
||||
|
||||
if (*best < *competitor)
|
||||
{
|
||||
best = competitor;
|
||||
}
|
||||
}
|
||||
|
||||
return best;
|
||||
}
|
||||
|
||||
template <class EOT>
|
||||
const EOT& deterministic_tournament(const eoPop<EOT>& _pop, unsigned _t_size, eoRng& _gen = rng)
|
||||
{
|
||||
return *deterministic_tournament(_pop.begin(), _pop.end(), _t_size, _gen);
|
||||
}
|
||||
|
||||
template <class EOT>
|
||||
EOT& deterministic_tournament(eoPop<EOT>& _pop, unsigned _t_size, eoRng& _gen = rng)
|
||||
{
|
||||
return *deterministic_tournament(_pop.begin(), _pop.end(), _t_size, _gen);
|
||||
}
|
||||
|
||||
template <class It>
|
||||
It inverse_deterministic_tournament(It _begin, It _end, unsigned _t_size, eoRng& _gen = rng)
|
||||
{
|
||||
It worst = _begin + _gen.random(_end - _begin);
|
||||
|
||||
for (unsigned i = 1; i < _t_size; ++i)
|
||||
{
|
||||
It competitor = _begin + _gen.random(_end - _begin);
|
||||
|
||||
if (competitor == worst)
|
||||
{
|
||||
--i;
|
||||
continue; // try again
|
||||
}
|
||||
|
||||
if (*competitor < *worst)
|
||||
{
|
||||
worst = competitor;
|
||||
}
|
||||
}
|
||||
|
||||
return worst;
|
||||
}
|
||||
|
||||
template <class EOT>
|
||||
const EOT& inverse_deterministic_tournament(const eoPop<EOT>& _pop, unsigned _t_size, eoRng& _gen = rng)
|
||||
{
|
||||
return *inverse_deterministic_tournament<EOT>(_pop.begin(), _pop.end(), _t_size, _gen);
|
||||
}
|
||||
|
||||
template <class EOT>
|
||||
EOT& inverse_deterministic_tournament(eoPop<EOT>& _pop, unsigned _t_size, eoRng& _gen = rng)
|
||||
{
|
||||
return *inverse_deterministic_tournament(_pop.begin(), _pop.end(), _t_size, _gen);
|
||||
}
|
||||
|
||||
template <class It>
|
||||
It stochastic_tournament(It _begin, It _end, double _t_rate, eoRng& _gen = rng)
|
||||
{
|
||||
It i1 = _begin + _gen.random(_end - _begin);
|
||||
It i2 = _begin + _gen.random(_end - _begin);
|
||||
|
||||
bool return_better = _gen.flip(_t_rate);
|
||||
|
||||
if (*i1 < *i2)
|
||||
{
|
||||
if (return_better) return i2;
|
||||
// else
|
||||
|
||||
return i1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (return_better) return i1;
|
||||
// else
|
||||
}
|
||||
// else
|
||||
|
||||
return i2;
|
||||
}
|
||||
|
||||
template <class EOT>
|
||||
const EOT& stochastic_tournament(const eoPop<EOT>& _pop, double _t_rate, eoRng& _gen = rng)
|
||||
{
|
||||
return *stochastic_tournament(_pop.begin(), _pop.end(), _t_rate, _gen);
|
||||
}
|
||||
|
||||
template <class EOT>
|
||||
EOT& stochastic_tournament(eoPop<EOT>& _pop, double _t_rate, eoRng& _gen = rng)
|
||||
{
|
||||
return *stochastic_tournament(_pop.begin(), _pop.end(), _t_rate, _gen);
|
||||
}
|
||||
|
||||
template <class It>
|
||||
It inverse_stochastic_tournament(It _begin, It _end, double _t_rate, eoRng& _gen = rng)
|
||||
{
|
||||
It i1 = _begin + _gen.random(_end - _begin);
|
||||
It i2 = _begin + _gen.random(_end - _begin);
|
||||
|
||||
bool return_worse = _gen.flip(_t_rate);
|
||||
|
||||
if (*i1 < *i2)
|
||||
{
|
||||
if (return_worse) return i1;
|
||||
// else
|
||||
|
||||
return i2;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (return_worse) return i2;
|
||||
// else
|
||||
}
|
||||
// else
|
||||
|
||||
return i1;
|
||||
}
|
||||
|
||||
template <class EOT>
|
||||
const EOT& inverse_stochastic_tournament(const eoPop<EOT>& _pop, double _t_rate, eoRng& _gen = rng)
|
||||
{
|
||||
return *inverse_stochastic_tournament(_pop.begin(), _pop.end(), _t_rate, _gen);
|
||||
}
|
||||
|
||||
template <class EOT>
|
||||
EOT& inverse_stochastic_tournament(eoPop<EOT>& _pop, double _t_rate, eoRng& _gen = rng)
|
||||
{
|
||||
return *inverse_stochastic_tournament(_pop.begin(), _pop.end(), _t_rate, _gen);
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
/* -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*-
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
selectors.h
|
||||
A bunch of useful selector functions. They generally have three forms:
|
||||
|
||||
template <class It>
|
||||
It select(It begin, It end, params, eoRng& gen = rng);
|
||||
|
||||
template <class EOT>
|
||||
const EOT& select(const eoPop<EOT>& pop, params, eoRng& gen = rng);
|
||||
|
||||
template <class EOT>
|
||||
EOT& select(eoPop<EOT>& pop, params, eoRng& gen = rng);
|
||||
|
||||
where select is one of: roulette_wheel, deterministic_tournament
|
||||
and stochastic_tournament (at the moment).
|
||||
|
||||
(c) Maarten Keijzer (mak@dhi.dk) and GeNeura Team, 1999, 2000
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
Contact: todos@geneura.ugr.es, http://geneura.ugr.es
|
||||
*/
|
||||
|
||||
#ifndef SELECT__H
|
||||
#define SELECT__H
|
||||
|
||||
#include <stdexcept>
|
||||
|
||||
#include "eoRNG.h"
|
||||
#include <eoPop.h>
|
||||
/**
|
||||
\defgroup selectors
|
||||
*/
|
||||
|
||||
template <class EOT>
|
||||
bool minimizing_fitness()
|
||||
{
|
||||
EOT eo1; // Assuming people don't do anything fancy in the default constructor!
|
||||
EOT eo2;
|
||||
|
||||
/* 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
|
||||
but you cannot use lottery or roulette_wheel selection...
|
||||
*/
|
||||
|
||||
#ifdef _MSC_VER
|
||||
eo1.fitness( EOT::Fitness(0.0) );
|
||||
eo2.fitness( EOT::Fitness(1.0) );
|
||||
#else
|
||||
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) );
|
||||
#endif
|
||||
|
||||
return eo2 < eo1; // check whether we have a minimizing fitness
|
||||
}
|
||||
|
||||
inline double scale_fitness(const std::pair<double, double>& _minmax, double _value)
|
||||
{
|
||||
if (_minmax.first == _minmax.second)
|
||||
{
|
||||
return 0.0; // no differences in fitness, population converged!
|
||||
}
|
||||
// else
|
||||
|
||||
return (_value - _minmax.first) / (_minmax.second - _minmax.first);
|
||||
}
|
||||
|
||||
template <class It>
|
||||
double sum_fitness(It begin, It end)
|
||||
{
|
||||
double sum = 0.0;
|
||||
|
||||
for (; begin != end; ++begin)
|
||||
{
|
||||
double v = static_cast<double>(begin->fitness());
|
||||
if (v < 0.0)
|
||||
throw std::logic_error("sum_fitness: negative fitness value encountered");
|
||||
sum += v;
|
||||
}
|
||||
|
||||
return sum;
|
||||
}
|
||||
|
||||
template <class EOT>
|
||||
double sum_fitness(const eoPop<EOT>& _pop)
|
||||
{
|
||||
return sum_fitness(_pop.begin(), _pop.end());
|
||||
}
|
||||
|
||||
template <class EOT>
|
||||
double sum_fitness(const eoPop<EOT>& _pop, std::pair<double, double>& _minmax)
|
||||
{
|
||||
double rawTotal, scaledTotal;
|
||||
|
||||
typename eoPop<EOT>::const_iterator it = _pop.begin();
|
||||
|
||||
_minmax.first = it->fitness();
|
||||
_minmax.second = it++->fitness();
|
||||
|
||||
for(; it != _pop.end(); ++it)
|
||||
{
|
||||
double v = static_cast<double>(it->fitness());
|
||||
|
||||
_minmax.first = std::min(_minmax.first, v);
|
||||
_minmax.second = std::max(_minmax.second, v);
|
||||
|
||||
rawTotal += v;
|
||||
}
|
||||
|
||||
if (minimizing_fitness<EOT>())
|
||||
{
|
||||
std::swap(_minmax.first, _minmax.second);
|
||||
}
|
||||
|
||||
scaledTotal = 0.0;
|
||||
|
||||
// unfortunately a second loop is neccessary to scale the fitness
|
||||
for (it = _pop.begin(); it != _pop.end(); ++it)
|
||||
{
|
||||
double v = scale_fitness(_minmax, static_cast<double>(it->fitness()));
|
||||
|
||||
scaledTotal += v;
|
||||
}
|
||||
|
||||
return scaledTotal;
|
||||
}
|
||||
|
||||
template <class It>
|
||||
It roulette_wheel(It _begin, It _end, double total, eoRng& _gen = rng)
|
||||
{
|
||||
|
||||
float roulette = _gen.uniform(total);
|
||||
|
||||
if (roulette == 0.0) // covers the case where total==0.0
|
||||
return _begin + _gen.random(_end - _begin); // uniform choice
|
||||
|
||||
It i = _begin;
|
||||
|
||||
while (roulette > 0.0)
|
||||
{
|
||||
roulette -= static_cast<double>(*(i++));
|
||||
}
|
||||
|
||||
return --i;
|
||||
}
|
||||
|
||||
template <class EOT>
|
||||
const EOT& roulette_wheel(const eoPop<EOT>& _pop, double total, eoRng& _gen = rng)
|
||||
{
|
||||
float roulette = _gen.uniform(total);
|
||||
|
||||
if (roulette == 0.0) // covers the case where total==0.0
|
||||
return _pop[_gen.random(_pop.size())]; // uniform choice
|
||||
|
||||
typename eoPop<EOT>::const_iterator i = _pop.begin();
|
||||
|
||||
while (roulette > 0.0)
|
||||
{
|
||||
roulette -= static_cast<double>((i++)->fitness());
|
||||
}
|
||||
|
||||
return *--i;
|
||||
}
|
||||
|
||||
template <class EOT>
|
||||
EOT& roulette_wheel(eoPop<EOT>& _pop, double total, eoRng& _gen = rng)
|
||||
{
|
||||
float roulette = _gen.uniform(total);
|
||||
|
||||
if (roulette == 0.0) // covers the case where total==0.0
|
||||
return _pop[_gen.random(_pop.size())]; // uniform choice
|
||||
|
||||
typename eoPop<EOT>::iterator i = _pop.begin();
|
||||
|
||||
while (roulette > 0.0)
|
||||
{
|
||||
roulette -= static_cast<double>((i++)->fitness());
|
||||
}
|
||||
|
||||
return *--i;
|
||||
}
|
||||
|
||||
template <class It>
|
||||
It deterministic_tournament(It _begin, It _end, unsigned _t_size, eoRng& _gen = rng)
|
||||
{
|
||||
It best = _begin + _gen.random(_end - _begin);
|
||||
|
||||
for (unsigned i = 0; i < _t_size - 1; ++i)
|
||||
{
|
||||
It competitor = _begin + _gen.random(_end - _begin);
|
||||
|
||||
if (*best < *competitor)
|
||||
{
|
||||
best = competitor;
|
||||
}
|
||||
}
|
||||
|
||||
return best;
|
||||
}
|
||||
|
||||
template <class EOT>
|
||||
const EOT& deterministic_tournament(const eoPop<EOT>& _pop, unsigned _t_size, eoRng& _gen = rng)
|
||||
{
|
||||
return *deterministic_tournament(_pop.begin(), _pop.end(), _t_size, _gen);
|
||||
}
|
||||
|
||||
template <class EOT>
|
||||
EOT& deterministic_tournament(eoPop<EOT>& _pop, unsigned _t_size, eoRng& _gen = rng)
|
||||
{
|
||||
return *deterministic_tournament(_pop.begin(), _pop.end(), _t_size, _gen);
|
||||
}
|
||||
|
||||
template <class It>
|
||||
It inverse_deterministic_tournament(It _begin, It _end, unsigned _t_size, eoRng& _gen = rng)
|
||||
{
|
||||
It worst = _begin + _gen.random(_end - _begin);
|
||||
|
||||
for (unsigned i = 1; i < _t_size; ++i)
|
||||
{
|
||||
It competitor = _begin + _gen.random(_end - _begin);
|
||||
|
||||
if (competitor == worst)
|
||||
{
|
||||
--i;
|
||||
continue; // try again
|
||||
}
|
||||
|
||||
if (*competitor < *worst)
|
||||
{
|
||||
worst = competitor;
|
||||
}
|
||||
}
|
||||
|
||||
return worst;
|
||||
}
|
||||
|
||||
template <class EOT>
|
||||
const EOT& inverse_deterministic_tournament(const eoPop<EOT>& _pop, unsigned _t_size, eoRng& _gen = rng)
|
||||
{
|
||||
return *inverse_deterministic_tournament<EOT>(_pop.begin(), _pop.end(), _t_size, _gen);
|
||||
}
|
||||
|
||||
template <class EOT>
|
||||
EOT& inverse_deterministic_tournament(eoPop<EOT>& _pop, unsigned _t_size, eoRng& _gen = rng)
|
||||
{
|
||||
return *inverse_deterministic_tournament(_pop.begin(), _pop.end(), _t_size, _gen);
|
||||
}
|
||||
|
||||
template <class It>
|
||||
It stochastic_tournament(It _begin, It _end, double _t_rate, eoRng& _gen = rng)
|
||||
{
|
||||
It i1 = _begin + _gen.random(_end - _begin);
|
||||
It i2 = _begin + _gen.random(_end - _begin);
|
||||
|
||||
bool return_better = _gen.flip(_t_rate);
|
||||
|
||||
if (*i1 < *i2)
|
||||
{
|
||||
if (return_better) return i2;
|
||||
// else
|
||||
|
||||
return i1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (return_better) return i1;
|
||||
// else
|
||||
}
|
||||
// else
|
||||
|
||||
return i2;
|
||||
}
|
||||
|
||||
template <class EOT>
|
||||
const EOT& stochastic_tournament(const eoPop<EOT>& _pop, double _t_rate, eoRng& _gen = rng)
|
||||
{
|
||||
return *stochastic_tournament(_pop.begin(), _pop.end(), _t_rate, _gen);
|
||||
}
|
||||
|
||||
template <class EOT>
|
||||
EOT& stochastic_tournament(eoPop<EOT>& _pop, double _t_rate, eoRng& _gen = rng)
|
||||
{
|
||||
return *stochastic_tournament(_pop.begin(), _pop.end(), _t_rate, _gen);
|
||||
}
|
||||
|
||||
template <class It>
|
||||
It inverse_stochastic_tournament(It _begin, It _end, double _t_rate, eoRng& _gen = rng)
|
||||
{
|
||||
It i1 = _begin + _gen.random(_end - _begin);
|
||||
It i2 = _begin + _gen.random(_end - _begin);
|
||||
|
||||
bool return_worse = _gen.flip(_t_rate);
|
||||
|
||||
if (*i1 < *i2)
|
||||
{
|
||||
if (return_worse) return i1;
|
||||
// else
|
||||
|
||||
return i2;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (return_worse) return i2;
|
||||
// else
|
||||
}
|
||||
// else
|
||||
|
||||
return i1;
|
||||
}
|
||||
|
||||
template <class EOT>
|
||||
const EOT& inverse_stochastic_tournament(const eoPop<EOT>& _pop, double _t_rate, eoRng& _gen = rng)
|
||||
{
|
||||
return *inverse_stochastic_tournament(_pop.begin(), _pop.end(), _t_rate, _gen);
|
||||
}
|
||||
|
||||
template <class EOT>
|
||||
EOT& inverse_stochastic_tournament(eoPop<EOT>& _pop, double _t_rate, eoRng& _gen = rng)
|
||||
{
|
||||
return *inverse_stochastic_tournament(_pop.begin(), _pop.end(), _t_rate, _gen);
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
|
|
|||
Reference in a new issue