Changed a few things in the eoPerf2Worth classes, EO.h and eoSelectOne.h are functionally unchanged
This commit is contained in:
parent
9bbac485f9
commit
665e20b0f8
10 changed files with 331 additions and 80 deletions
|
|
@ -1,9 +1,9 @@
|
|||
/** -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*-
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
eoPerf2Worth.h
|
||||
eoPerf2Worth.h
|
||||
(c) Maarten Keijzer, Marc Schoenauer, 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
|
||||
|
|
@ -27,22 +27,198 @@
|
|||
#ifndef eoPerf2Worth_h
|
||||
#define eoPerf2Worth_h
|
||||
|
||||
#include <utils/eoStat.h>
|
||||
#include <utils/eoParam.h>
|
||||
#include <algorithm>
|
||||
|
||||
/** Base class to transform raw fitnesses into fitness for selection
|
||||
|
||||
It is an eoStat so
|
||||
- it is updated inside a checkpoint (i.e. at start of every generation)
|
||||
- it can be monitored or whatever else you wish through its value()
|
||||
|
||||
@see eoSelectFromWorth
|
||||
*/
|
||||
template <class EOT, class WorthT = typename EOT::Fitness>
|
||||
class eoPerf2Worth : public eoStat<EOT, vector<WorthT> >
|
||||
template <class EOT, class WorthT = double>
|
||||
class eoPerf2Worth : public eoUF<const eoPop<EOT>&, void>, public eoValueParam<vector<WorthT> >
|
||||
{
|
||||
public:
|
||||
eoPerf2Worth(std::string _description = "Worths"):eoStat<EOT, vector<WorthT> >(vector<WorthT>(0),
|
||||
eoPerf2Worth(std::string _description = "Worths"):eoValueParam<vector<WorthT> >(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)
|
||||
{ // start with a vector of indices
|
||||
vector<unsigned> indices(_pop.size());
|
||||
|
||||
for (unsigned i = 0; i < _pop.size();++i)
|
||||
{ // could use generate, but who cares
|
||||
indices[i] = i;
|
||||
}
|
||||
|
||||
sort(indices.begin(), indices.end(), compare_worth(value()));
|
||||
|
||||
eoPop<EOT> tmp_pop;
|
||||
tmp_pop.resize(_pop.size());
|
||||
vector<WorthT> tmp_worths(value().size());
|
||||
|
||||
for (unsigned i = 0; i < _pop.size(); ++i)
|
||||
{
|
||||
tmp_pop[i] = _pop[indices[i]];
|
||||
tmp_worths[i] = value()[indices[i]];
|
||||
}
|
||||
|
||||
swap(_pop, tmp_pop);
|
||||
swap(value(), tmp_worths);
|
||||
}
|
||||
|
||||
/** helper class used to sort indices into populations/worths
|
||||
*/
|
||||
class compare_worth
|
||||
{
|
||||
public :
|
||||
compare_worth(const vector<WorthT>& _worths) : worths(_worths) {}
|
||||
|
||||
bool operator()(unsigned a, unsigned b) const
|
||||
{
|
||||
return worths[b] < worths[a]; // sort in descending (!) order
|
||||
}
|
||||
|
||||
private :
|
||||
|
||||
const vector<WorthT>& worths;
|
||||
};
|
||||
|
||||
virtual void resize(eoPop<EOT>& _pop, unsigned sz)
|
||||
{
|
||||
_pop.resize(sz);
|
||||
value().resize(sz);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
Perf2Worth with fitness cache
|
||||
*/
|
||||
template <class EOT, class WorthT = typename EOT::Fitness>
|
||||
class eoPerf2WorthCached : public eoPerf2Worth<EOT, WorthT>
|
||||
{
|
||||
public:
|
||||
eoPerf2WorthCached(std::string _description = "Worths") : eoPerf2Worth<EOT, WorthT>(_description) {}
|
||||
|
||||
|
||||
/**
|
||||
Implementation of the operator(), updating a cache of fitnesses. Calls the virtual function
|
||||
calculate_worths when one of the fitnesses has changed. It is not virtual, but derived classes
|
||||
can remove the fitness caching trough the third template element
|
||||
*/
|
||||
void operator()(const eoPop<EOT>& _pop)
|
||||
{
|
||||
if (fitness_cache.size() == _pop.size())
|
||||
{
|
||||
bool in_sync = true;
|
||||
for (unsigned i = 0; i < _pop.size(); ++i)
|
||||
{
|
||||
if (fitness_cache[i] != _pop[i].fitness())
|
||||
{
|
||||
in_sync = false;
|
||||
fitness_cache[i] = _pop[i].fitness();
|
||||
}
|
||||
}
|
||||
|
||||
if (in_sync)
|
||||
{ // worths are up to date
|
||||
return;
|
||||
}
|
||||
}
|
||||
else // just cache the fitness
|
||||
{
|
||||
fitness_cache.resize(_pop.size());
|
||||
for (unsigned i = 0; i < _pop.size(); ++i)
|
||||
{
|
||||
fitness_cache[i] = _pop[i].fitness();
|
||||
}
|
||||
}
|
||||
|
||||
// call derived implementation of perf2worth mapping
|
||||
calculate_worths(_pop);
|
||||
}
|
||||
|
||||
/** The actual virtual function the derived classes should implement*/
|
||||
virtual void calculate_worths(const eoPop<EOT>& _pop) = 0;
|
||||
|
||||
/**
|
||||
Sort population according to worth, will keep the worths and fitness_cache in sync with the population.
|
||||
*/
|
||||
virtual void sort_pop(eoPop<EOT>& _pop)
|
||||
{ // start with a vector of indices
|
||||
vector<unsigned> indices(_pop.size());
|
||||
|
||||
for (unsigned i = 0; i < _pop.size();++i)
|
||||
{ // could use generate, but who cares
|
||||
indices[i] = i;
|
||||
}
|
||||
|
||||
sort(indices.begin(), indices.end(), eoPerf2Worth<EOT,WorthT>::compare_worth(value()));
|
||||
|
||||
eoPop<EOT> tmp_pop;
|
||||
tmp_pop.resize(_pop.size());
|
||||
vector<WorthT> tmp_worths(value().size());
|
||||
vector<typename EOT::Fitness> tmp_cache(_pop.size());
|
||||
|
||||
for (unsigned i = 0; i < _pop.size(); ++i)
|
||||
{
|
||||
tmp_pop[i] = _pop[indices[i]];
|
||||
tmp_worths[i] = value()[indices[i]];
|
||||
|
||||
tmp_cache[i] = fitness_cache[indices[i]];
|
||||
}
|
||||
|
||||
swap(_pop, tmp_pop);
|
||||
swap(value(), tmp_worths);
|
||||
swap(fitness_cache, tmp_cache);
|
||||
}
|
||||
|
||||
/** helper class used to sort indices into populations/worths
|
||||
*/
|
||||
class compare_worth
|
||||
{
|
||||
public :
|
||||
compare_worth(const vector<WorthT>& _worths) : worths(_worths) {}
|
||||
|
||||
bool operator()(unsigned a, unsigned b) const
|
||||
{
|
||||
return worths[b] < worths[a]; // sort in descending (!) order
|
||||
}
|
||||
|
||||
private :
|
||||
|
||||
const vector<WorthT>& worths;
|
||||
};
|
||||
|
||||
virtual void resize(eoPop<EOT>& _pop, unsigned sz)
|
||||
{
|
||||
_pop.resize(sz);
|
||||
value().resize(sz);
|
||||
fitness_cache.resize(sz);
|
||||
}
|
||||
|
||||
private :
|
||||
vector <typename EOT::Fitness> fitness_cache;
|
||||
};
|
||||
|
||||
/**
|
||||
A dummy perf2worth, just in case you need it
|
||||
*/
|
||||
template <class EOT>
|
||||
class eoNoPerf2Worth : public eoPerf2Worth<EOT, typename EOT::Fitness>
|
||||
{
|
||||
public:
|
||||
|
||||
// default behaviour, just copy fitnesses
|
||||
void operator()(const eoPop<EOT>& _pop)
|
||||
{
|
||||
value.resize(_pop.size());
|
||||
for (unsigned i = 0; i < _pop.size(); ++i)
|
||||
value()[i]=_pop[i];
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue