Ok, made an eoParetoFitness class, which meant that I could roll back a few changes in EO.h (phew).
Also changed eoSelectFromWorth etc.
This commit is contained in:
parent
cf8f6b5c16
commit
d09c216b61
11 changed files with 215 additions and 110 deletions
|
|
@ -4,7 +4,7 @@
|
||||||
##
|
##
|
||||||
###############################################################################
|
###############################################################################
|
||||||
|
|
||||||
SUBDIRS = src test win tutorial app
|
SUBDIRS = src test win app tutorial
|
||||||
#Directory for documents
|
#Directory for documents
|
||||||
DOCDIR = ~/public_html/eodocs
|
DOCDIR = ~/public_html/eodocs
|
||||||
#Directory for indices -- not useful for the user
|
#Directory for indices -- not useful for the user
|
||||||
|
|
@ -17,10 +17,6 @@ EXTRA_DIST=LICENSE
|
||||||
lib:
|
lib:
|
||||||
pushd src; $(MAKE) all; popd
|
pushd src; $(MAKE) all; popd
|
||||||
|
|
||||||
# The test directory should be run explicitely, to check if nothing is broken
|
|
||||||
test: test/run_tests test/Makefile
|
|
||||||
pushd test; touch run_tests; $(MAKE) all; ./run_tests; popd
|
|
||||||
|
|
||||||
# so that make doc always compiles the doc ...
|
# so that make doc always compiles the doc ...
|
||||||
doc: doc/eo.cfg
|
doc: doc/eo.cfg
|
||||||
pushd doc; $(MAKE) doc; touch eo.cfg; popd
|
pushd doc; $(MAKE) doc; touch eo.cfg; popd
|
||||||
|
|
|
||||||
|
|
@ -56,8 +56,8 @@ echo
|
||||||
echo "Now type 'make' to compile $PROG."
|
echo "Now type 'make' to compile $PROG."
|
||||||
echo "And if you have Doxygen installed, type 'make doc' to generate $PROG documentation."
|
echo "And if you have Doxygen installed, type 'make doc' to generate $PROG documentation."
|
||||||
echo
|
echo
|
||||||
echo "WARNING: Compiling all test programs can take some time."
|
#echo "WARNING: Compiling all test programs can take some time."
|
||||||
echo "But you don't have to: you can simply type"
|
#echo "But you don't have to: you can simply type"
|
||||||
echo " 'make lib'"
|
#echo " 'make lib'"
|
||||||
echo "and then go in your application dir (or in the tutorial dir)"
|
#echo "and then go in your application dir (or in the tutorial dir)"
|
||||||
echo "and there type 'make'"
|
#echo "and there type 'make'"
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ dnl Process this file with autoconf to produce a configure script.
|
||||||
AC_INIT(src/eo)
|
AC_INIT(src/eo)
|
||||||
|
|
||||||
dnl Change the version number here
|
dnl Change the version number here
|
||||||
AM_INIT_AUTOMAKE(eo, 0.9.11)
|
AM_INIT_AUTOMAKE(eo, 0.9.2)
|
||||||
|
|
||||||
dnl Checks for maintainer mode
|
dnl Checks for maintainer mode
|
||||||
AM_MAINTAINER_MODE
|
AM_MAINTAINER_MODE
|
||||||
|
|
|
||||||
60
eo/src/EO.h
60
eo/src/EO.h
|
|
@ -31,61 +31,6 @@
|
||||||
#include <eoObject.h> // eoObject
|
#include <eoObject.h> // eoObject
|
||||||
#include <eoPersistent.h> // eoPersistent
|
#include <eoPersistent.h> // eoPersistent
|
||||||
|
|
||||||
/// Functions for reading and writing non-scalar fitnesses, should probably go to seperate file
|
|
||||||
template <class T>
|
|
||||||
ostream& print_fitness(ostream& _os, const std::vector<T>& vec)
|
|
||||||
{
|
|
||||||
_os << vec.size() << ' ';
|
|
||||||
std::copy(vec.begin(), vec.end(), ostream_iterator<T>(_os));
|
|
||||||
return _os;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Functions for reading and writing non-scalar fitnesses, should probably go to seperate file
|
|
||||||
template <class T, class U>
|
|
||||||
ostream& print_fitness(ostream& _os, const std::pair<T, U>& pair)
|
|
||||||
{
|
|
||||||
return _os << pair.first << ' ' << pair.second;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Functions for reading and writing non-scalar fitnesses, should probably go to seperate file
|
|
||||||
template <class T>
|
|
||||||
ostream& print_fitness(ostream& _os, const T& t)
|
|
||||||
{ // general, try operator<<
|
|
||||||
return _os << t;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Functions for reading and writing non-scalar fitnesses, should probably go to seperate file
|
|
||||||
template <class T>
|
|
||||||
istream& read_fitness(istream& _is, vector<T>& vec)
|
|
||||||
{
|
|
||||||
unsigned sz;
|
|
||||||
_is >> sz;
|
|
||||||
vec.resize(sz);
|
|
||||||
for (unsigned i = 0; i < vec.size(); ++i)
|
|
||||||
{
|
|
||||||
_is >> vec[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
return _is;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Functions for reading and writing non-scalar fitnesses, should probably go to seperate file
|
|
||||||
template <class T, class U>
|
|
||||||
istream& read_fitness(istream& _is, pair<T, U>& pair)
|
|
||||||
{
|
|
||||||
_is >> pair.first;
|
|
||||||
_is >> pair.second;
|
|
||||||
return _is;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Functions for reading and writing non-scalar fitnesses, should probably go to seperate file
|
|
||||||
template <class T>
|
|
||||||
istream& read_fitness(istream& _is, T& t)
|
|
||||||
{
|
|
||||||
_is >> t;
|
|
||||||
return _is;
|
|
||||||
}
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
/** EO is a base class for evolvable objects, that is, the subjects of
|
/** EO is a base class for evolvable objects, that is, the subjects of
|
||||||
evolution. EOs have only got a fitness, which at the same time needs to be
|
evolution. EOs have only got a fitness, which at the same time needs to be
|
||||||
|
|
@ -158,7 +103,7 @@ public:
|
||||||
* @throw runtime_exception If a valid object can't be read.
|
* @throw runtime_exception If a valid object can't be read.
|
||||||
*/
|
*/
|
||||||
virtual void readFrom(istream& _is) {
|
virtual void readFrom(istream& _is) {
|
||||||
read_fitness(_is, repFitness);
|
_is >> repFitness;
|
||||||
if (_is)
|
if (_is)
|
||||||
invalidFitness = false;
|
invalidFitness = false;
|
||||||
else
|
else
|
||||||
|
|
@ -173,7 +118,7 @@ public:
|
||||||
if (invalid())
|
if (invalid())
|
||||||
_os << "INVALID ";
|
_os << "INVALID ";
|
||||||
else
|
else
|
||||||
print_fitness(_os, repFitness) << ' '; // trailing space to make reading in that much easier
|
_os << repFitness << ' '; // trailing space to make reading in that much easier
|
||||||
}
|
}
|
||||||
|
|
||||||
//@}
|
//@}
|
||||||
|
|
@ -186,4 +131,3 @@ private:
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
#endif EO_H
|
#endif EO_H
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -62,6 +62,8 @@ class eoDominanceMap : public eoUF<const eoPop<EoType>&, void>, public std::vect
|
||||||
fitnesses.clear();
|
fitnesses.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool maximize(unsigned objective) const { return maximizes[objective]; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Update or create the dominance map
|
Update or create the dominance map
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -32,16 +32,25 @@
|
||||||
#include <eoDominanceMap.h>
|
#include <eoDominanceMap.h>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Non dominated sorting
|
Non dominated sorting, it *is a* vector of doubles, the integer part is the rank (to which front it belongs),
|
||||||
|
the fractional part the niching penalty or distance penalty or whatever penalty you want to squeeze into
|
||||||
|
the bits.
|
||||||
*/
|
*/
|
||||||
template <class EOT>
|
template <class EOT>
|
||||||
class eoNDSorting : public eoPerf2Worth<EOT, double>
|
class eoNDSorting : public eoPerf2Worth<EOT, double>
|
||||||
{
|
{
|
||||||
public :
|
public :
|
||||||
|
|
||||||
eoNDSorting(eoDominanceMap<EOT>& _dominanceMap, double _nicheSize) :
|
eoNDSorting(eoDominanceMap<EOT>& _dominanceMap) :
|
||||||
eoPerf2Worth<EOT, double>(), dominanceMap(_dominanceMap), nicheSize(_nicheSize) {}
|
eoPerf2Worth<EOT, double>(), dominanceMap(_dominanceMap) {}
|
||||||
|
|
||||||
|
/** Pure virtual function that calculates the 'distance' for each element to the current front
|
||||||
|
Implement to create your own nondominated sorting algorithm. The size of the returned vector
|
||||||
|
should be equal to the size of the current_front.
|
||||||
|
*/
|
||||||
|
virtual vector<double> niche_penalty(const vector<unsigned>& current_front, const eoPop<EOT>& _pop) = 0;
|
||||||
|
|
||||||
|
/// Do the work
|
||||||
void operator()(const eoPop<EOT>& _pop)
|
void operator()(const eoPop<EOT>& _pop)
|
||||||
{
|
{
|
||||||
dominanceMap(_pop);
|
dominanceMap(_pop);
|
||||||
|
|
@ -83,20 +92,20 @@ class eoNDSorting : public eoPerf2Worth<EOT, double>
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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
|
||||||
|
vector<double> niche_count = niche_penalty(current_front, _pop);
|
||||||
|
|
||||||
// As I don't have my reference text with me some homespun savagery
|
if (niche_count.size() != current_front.size())
|
||||||
|
{
|
||||||
|
throw logic_error("eoNDSorting: niche and front should have the same size");
|
||||||
|
}
|
||||||
|
|
||||||
ranks = dominanceMap.sum_dominants(); // how many do you dominate
|
double max_niche = *max_element(niche_count.begin(), niche_count.end());
|
||||||
|
|
||||||
double max_rank = *std::max_element(ranks.begin(), ranks.end());
|
|
||||||
|
|
||||||
for (unsigned i = 0; i < current_front.size(); ++i)
|
for (unsigned i = 0; i < current_front.size(); ++i)
|
||||||
{
|
{
|
||||||
// punish the ones that dominate the most individuals (sounds strange huh?)
|
value()[current_front[i]] = dominance_level + niche_count[i] / (max_niche + 1);
|
||||||
value()[current_front[i]] = dominance_level + ranks[i] / (max_rank + 1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
dominance_level++; // go to the next front
|
dominance_level++; // go to the next front
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -110,10 +119,123 @@ class eoNDSorting : public eoPerf2Worth<EOT, double>
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const eoDominanceMap<EOT>& map() const;
|
||||||
|
|
||||||
private :
|
private :
|
||||||
|
|
||||||
eoDominanceMap<EOT>& dominanceMap;
|
eoDominanceMap<EOT>& dominanceMap;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
The original Non Dominated Sorting algorithm from Srinivas and Deb
|
||||||
|
*/
|
||||||
|
template <class EOT>
|
||||||
|
class eoNDSorting_I : public eoNDSorting<EOT>
|
||||||
|
{
|
||||||
|
public :
|
||||||
|
eoNDSorting_I(eoDominanceMap<EOT>& _map, double _nicheSize) : eoNDSorting<EOT>(_map), nicheSize(_nicheSize) {}
|
||||||
|
|
||||||
|
vector<double> niche_penalty(const vector<unsigned>& current_front, const eoPop<EOT>& _pop)
|
||||||
|
{
|
||||||
|
vector<double> niche_count(current_front.size(), 0.);
|
||||||
|
|
||||||
|
for (unsigned i = 0; i < current_front.size(); ++i)
|
||||||
|
{ // calculate whether the other points lie within the nice
|
||||||
|
for (unsigned j = 0; j < current_front.size(); ++j)
|
||||||
|
{
|
||||||
|
if (i == j)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
double dist = 0.0;
|
||||||
|
|
||||||
|
for (unsigned k = 0; k < _pop[current_front[j]].fitness().size(); ++k)
|
||||||
|
{
|
||||||
|
double d = _pop[current_front[i]].fitness()[k] - _pop[current_front[j]].fitness()[k];
|
||||||
|
dist += d*d;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dist < nicheSize)
|
||||||
|
{
|
||||||
|
niche_count[i] += 1.0 - pow(dist / nicheSize,2.);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return niche_count;
|
||||||
|
}
|
||||||
|
|
||||||
|
private :
|
||||||
|
|
||||||
double nicheSize;
|
double nicheSize;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
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_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>
|
||||||
|
class eoNDSorting_II : public eoNDSorting<EOT>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
eoNDSorting_II(eoDominanceMap<EOT>& _map) : eoNDSorting<EOT>(_map) {}
|
||||||
|
|
||||||
|
typedef std::pair<double, unsigned> double_index_pair;
|
||||||
|
|
||||||
|
class compare_nodes
|
||||||
|
{
|
||||||
|
public :
|
||||||
|
bool operator()(const double_index_pair& a, const double_index_pair& b) const
|
||||||
|
{
|
||||||
|
return a.first < b.first;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
vector<double> niche_penalty(const vector<unsigned>& _cf, const eoPop<EOT>& _pop)
|
||||||
|
{
|
||||||
|
vector<double> niche_count(_cf.size(), 0.);
|
||||||
|
|
||||||
|
unsigned nObjectives = _pop[_cf[0]].fitness().size();
|
||||||
|
|
||||||
|
for (unsigned o = 0; o < nObjectives; ++o)
|
||||||
|
{
|
||||||
|
|
||||||
|
vector<pair<double, unsigned> > performance(_cf.size());
|
||||||
|
for (unsigned i =0; i < _cf.size(); ++i)
|
||||||
|
{
|
||||||
|
performance[i].first = _pop[_cf[i]].fitness()[o];
|
||||||
|
performance[i].second = i;
|
||||||
|
}
|
||||||
|
|
||||||
|
sort(performance.begin(), performance.end(), compare_nodes()); // a lambda operator would've been nice here
|
||||||
|
|
||||||
|
vector<double> nc(niche_count.size(), 0.0);
|
||||||
|
|
||||||
|
for (unsigned i = 1; i < _cf.size()-1; ++i)
|
||||||
|
{ // and yet another level of indirection
|
||||||
|
nc[performance[i].second] = performance[i+1].first - performance[i-1].first;
|
||||||
|
}
|
||||||
|
|
||||||
|
double max_dist = *max_element(nc.begin(), nc.end());
|
||||||
|
|
||||||
|
// set boundary penalty at 0 (so it will get chosen over all the others
|
||||||
|
nc[performance[0].second] = 0;
|
||||||
|
nc[performance.back().second] = 0;
|
||||||
|
|
||||||
|
for (unsigned i = 0; i < nc.size(); ++i)
|
||||||
|
{
|
||||||
|
niche_count[i] += (max_dist + 1) - nc[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return niche_count;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -74,8 +74,7 @@ protected:
|
||||||
eoPerf2Worth<EOT, WorthType> & perf2Worth;
|
eoPerf2Worth<EOT, WorthType> & perf2Worth;
|
||||||
|
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
vector<typename EOT::Fitness> fitness; // for debugging purposes, to check that the perf2worth and pop are in sync
|
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())
|
||||||
|
|
|
||||||
|
|
@ -58,13 +58,15 @@ class eoGnuplot1DSnapshot: public eoFileSnapshot, public eoGnuplot
|
||||||
eoGnuplot1DSnapshot(std::string _dirname, unsigned _frequency = 1,
|
eoGnuplot1DSnapshot(std::string _dirname, unsigned _frequency = 1,
|
||||||
std::string _filename = "gen", std::string _delim = " ") :
|
std::string _filename = "gen", std::string _delim = " ") :
|
||||||
eoFileSnapshot(_dirname, _frequency, _filename, _delim),
|
eoFileSnapshot(_dirname, _frequency, _filename, _delim),
|
||||||
eoGnuplot(_filename,"set data style points")
|
eoGnuplot(_filename,"set data style points"),
|
||||||
|
pointSize(5)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
// Ctor
|
// Ctor
|
||||||
eoGnuplot1DSnapshot(eoFileSnapshot & _fSnapshot) :
|
eoGnuplot1DSnapshot(eoFileSnapshot & _fSnapshot) :
|
||||||
eoFileSnapshot(_fSnapshot),
|
eoFileSnapshot(_fSnapshot),
|
||||||
eoGnuplot(_fSnapshot.baseFileName(),"set data style points")
|
eoGnuplot(_fSnapshot.baseFileName(),"set data style points"),
|
||||||
|
pointSize(5)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
// Dtor
|
// Dtor
|
||||||
|
|
@ -75,7 +77,9 @@ class eoGnuplot1DSnapshot: public eoFileSnapshot, public eoGnuplot
|
||||||
/// Class name.
|
/// Class name.
|
||||||
virtual string className() const { return "eoGnuplot1DSnapshot"; }
|
virtual string className() const { return "eoGnuplot1DSnapshot"; }
|
||||||
|
|
||||||
|
unsigned pointSize;
|
||||||
private:
|
private:
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// the following should be placed in a separate eoGnuplot1DMonitor.cpp
|
// the following should be placed in a separate eoGnuplot1DMonitor.cpp
|
||||||
|
|
@ -96,7 +100,7 @@ inline eoMonitor& eoGnuplot1DSnapshot::operator() (void)
|
||||||
os << "plot";
|
os << "plot";
|
||||||
|
|
||||||
os << " '" << getFileName().c_str() <<
|
os << " '" << getFileName().c_str() <<
|
||||||
"' notitle with points ps 5" ;
|
"' notitle with points ps " << pointSize ;
|
||||||
os << "\n";
|
os << "\n";
|
||||||
os << '\0';
|
os << '\0';
|
||||||
PipeComSend( gpCom, buff );
|
PipeComSend( gpCom, buff );
|
||||||
|
|
|
||||||
|
|
@ -13,9 +13,9 @@ LDADDS = $(top_builddir)/src/utils/libeoutils.a $(top_builddir)/src/libeo.a
|
||||||
CXXFLAGS = -g -Wall
|
CXXFLAGS = -g -Wall
|
||||||
###############################################################################
|
###############################################################################
|
||||||
|
|
||||||
check_PROGRAMS = t-eoPareto t-eofitness t-eoRandom t-eobin t-eoStateAndParser t-eoCheckpointing t-eoSSGA \
|
check_PROGRAMS = t-eoParetoFitness t-eoPareto t-eofitness t-eoRandom t-eobin t-eoStateAndParser t-eoCheckpointing t-eoSSGA \
|
||||||
t-eoExternalEO t-eoSymreg t-eo t-eoReplacement t-eoSelect t-eoGenOp t-eoGA t-eoVector
|
t-eoExternalEO t-eoSymreg t-eo t-eoReplacement t-eoSelect t-eoGenOp t-eoGA t-eoVector
|
||||||
TESTS=run_tests t-eoVector t-eoRandom t-eoSSGA t-eoPareto
|
TESTS=run_tests t-eoVector t-eoRandom t-eoSSGA t-eoPareto t-eoParetoFitness
|
||||||
# removing temporarily t-eoESFull
|
# removing temporarily t-eoESFull
|
||||||
#noinst_PROGRAMS = t-eofitness t-eobin t-eoStateAndParser t-eoCheckpointing t-eoExternalEO t-eoESFull t-eoSymreg t-eo t-eoReplacement t-eoSelect t-eoGenOp t-eoGA
|
#noinst_PROGRAMS = t-eofitness t-eobin t-eoStateAndParser t-eoCheckpointing t-eoExternalEO t-eoESFull t-eoSymreg t-eo t-eoReplacement t-eoSelect t-eoGenOp t-eoGA
|
||||||
|
|
||||||
|
|
@ -128,3 +128,8 @@ t_eoPareto_LDFLAGS = -lm
|
||||||
t_eoPareto_LDADD = $(LDADDS)
|
t_eoPareto_LDADD = $(LDADDS)
|
||||||
###############################################################################
|
###############################################################################
|
||||||
|
|
||||||
|
t_eoParetoFitness_SOURCES = t-eoParetoFitness.cpp
|
||||||
|
t_eoParetoFitness_DEPENDENCIES = $(DEPS) $(top_builddir)/src/ga/libga.a
|
||||||
|
t_eoParetoFitness_LDFLAGS = -lm
|
||||||
|
t_eoParetoFitness_LDADD = $(LDADDS)
|
||||||
|
###############################################################################
|
||||||
|
|
|
||||||
|
|
@ -3,20 +3,42 @@
|
||||||
|
|
||||||
//#include <utils/eoMOFitnessStat.h>
|
//#include <utils/eoMOFitnessStat.h>
|
||||||
#include <eoNDSorting.h>
|
#include <eoNDSorting.h>
|
||||||
|
#include <eoParetoFitness.h>
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
typedef vector<double> fitness_type;
|
|
||||||
|
class MinimizingFitnessTraits : public eoParetoFitnessTraits
|
||||||
|
{
|
||||||
|
public :
|
||||||
|
static bool maximizing(int) { return false; }
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef eoParetoFitness<MinimizingFitnessTraits> fitness_type;
|
||||||
|
|
||||||
|
const unsigned chromsize=3;
|
||||||
|
const double minval = -5;
|
||||||
|
const double maxval = 5;
|
||||||
|
|
||||||
struct eoDouble : public EO<fitness_type>
|
struct eoDouble : public EO<fitness_type>
|
||||||
{
|
{
|
||||||
double value;
|
double value[chromsize];
|
||||||
};
|
};
|
||||||
|
|
||||||
class Mutate : public eoMonOp<eoDouble>
|
class Mutate : public eoMonOp<eoDouble>
|
||||||
{
|
{
|
||||||
bool operator()(eoDouble& _eo)
|
bool operator()(eoDouble& _eo)
|
||||||
{
|
{
|
||||||
_eo.value += rng.normal() * 0.1 * _eo.value;
|
for (unsigned i = 0; i < chromsize; ++i)
|
||||||
|
{
|
||||||
|
if (rng.flip(1./10.))
|
||||||
|
_eo.value[i] += rng.normal() * 0.05 * _eo.value[i];
|
||||||
|
|
||||||
|
if (_eo.value[i] < minval)
|
||||||
|
_eo.value[i] = minval;
|
||||||
|
else if (_eo.value[i] > maxval)
|
||||||
|
_eo.value[i] = maxval;
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
@ -25,10 +47,18 @@ class Eval : public eoEvalFunc<eoDouble>
|
||||||
{
|
{
|
||||||
void operator()(eoDouble& _eo)
|
void operator()(eoDouble& _eo)
|
||||||
{
|
{
|
||||||
double v = _eo.value;
|
vector<double> x(_eo.value, _eo.value + chromsize);
|
||||||
fitness_type f(2);
|
fitness_type f;
|
||||||
f[1] = v * v;
|
|
||||||
f[0] = (v - 1.) * (v - 1.);
|
for (unsigned i = 0; i < chromsize; ++i)
|
||||||
|
{
|
||||||
|
if (i < chromsize-1)
|
||||||
|
{
|
||||||
|
f[0] += -10.0 * exp(-0.2 * sqrt(x[i]*x[i] + x[i+1]*x[i+1]));
|
||||||
|
}
|
||||||
|
|
||||||
|
f[1] += pow(fabs(x[i]), 0.8) + 5 * pow(sin(x[i]),3.);
|
||||||
|
}
|
||||||
|
|
||||||
_eo.fitness(f);
|
_eo.fitness(f);
|
||||||
}
|
}
|
||||||
|
|
@ -38,7 +68,10 @@ class Init : public eoInit<eoDouble>
|
||||||
{
|
{
|
||||||
void operator()(eoDouble& _eo)
|
void operator()(eoDouble& _eo)
|
||||||
{
|
{
|
||||||
_eo.value = rng.normal() * 10.;
|
_eo.value[0] = rng.uniform();
|
||||||
|
|
||||||
|
for (unsigned i = 1; i < chromsize; ++i)
|
||||||
|
_eo.value[i] = rng.uniform() * 10. - 5;
|
||||||
_eo.invalidate();
|
_eo.invalidate();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
@ -51,8 +84,8 @@ void the_main()
|
||||||
Eval eval;
|
Eval eval;
|
||||||
Mutate mutate;
|
Mutate mutate;
|
||||||
|
|
||||||
unsigned num_gen = 10;
|
unsigned num_gen = 500;
|
||||||
unsigned pop_size = 50;
|
unsigned pop_size = 100;
|
||||||
eoPop<eoDouble> pop(pop_size, init);
|
eoPop<eoDouble> pop(pop_size, init);
|
||||||
|
|
||||||
vector<bool> maximizes(2, false); // minimize both objectives
|
vector<bool> maximizes(2, false); // minimize both objectives
|
||||||
|
|
@ -62,7 +95,8 @@ void the_main()
|
||||||
|
|
||||||
// Pareto ranking needs a dominance map
|
// Pareto ranking needs a dominance map
|
||||||
//eoParetoRanking<eoDouble> perf2worth(dominance);
|
//eoParetoRanking<eoDouble> perf2worth(dominance);
|
||||||
eoNDSorting<eoDouble> perf2worth(dominance, 0.0);
|
//eoNDSorting_I<eoDouble> perf2worth(dominance, 0.5);
|
||||||
|
eoNDSorting_II<eoDouble> perf2worth(dominance);
|
||||||
|
|
||||||
// Three selectors
|
// Three selectors
|
||||||
eoDetTournamentWorthSelect<eoDouble> select1(perf2worth, 3);
|
eoDetTournamentWorthSelect<eoDouble> select1(perf2worth, 3);
|
||||||
|
|
@ -78,7 +112,7 @@ void the_main()
|
||||||
eoGeneralBreeder<eoDouble> breeder2(select2, opsel);
|
eoGeneralBreeder<eoDouble> breeder2(select2, opsel);
|
||||||
eoGeneralBreeder<eoDouble> breeder3(select3, opsel);
|
eoGeneralBreeder<eoDouble> breeder3(select3, opsel);
|
||||||
|
|
||||||
// Comma replacement
|
// replacement
|
||||||
eoCommaReplacement<eoDouble> replace;
|
eoCommaReplacement<eoDouble> replace;
|
||||||
|
|
||||||
unsigned long generation = 0;
|
unsigned long generation = 0;
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,4 @@
|
||||||
|
|
||||||
EXTRA_DIST=eo_win.dsw eo.dsp esfull.dsp t_eobin.dsp t_eoCheckpointing.dsp t_eofitness.dsp \
|
EXTRA_DIST=eo.dsw eo.dsp
|
||||||
t_eoFunctor.dsp t_externalEO.dsp t_StateAndParser.dsp t_eoSymreg.dsp
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
Reference in a new issue