diff --git a/eo/src/eo b/eo/src/eo index 5ee961e6..0e37aa9d 100644 --- a/eo/src/eo +++ b/eo/src/eo @@ -25,7 +25,7 @@ //----------------------------------------------------------------------------- -#include +#include #include #include #include @@ -33,13 +33,11 @@ #include #include -#include #include #include -#include -#include -#include +#include +#include #include #include @@ -58,7 +56,7 @@ #include #include #include -#include +#include // Evaluation functions #include diff --git a/eo/src/eoDetTournament.h b/eo/src/eoDetTournament.h index 687b3091..5af8bb8e 100644 --- a/eo/src/eoDetTournament.h +++ b/eo/src/eoDetTournament.h @@ -31,7 +31,7 @@ #include // #include // accumulate #include "eoPopOps.h" // eoPop eoSelect MINFLOAT -#include "selectors.h" +#include "utils/selectors.h" //----------------------------------------------------------------------------- /** eoDetTournament: a selection method that selects ONE individual by diff --git a/eo/src/eoLottery.h b/eo/src/eoLottery.h index 9cf584bf..de8d978d 100644 --- a/eo/src/eoLottery.h +++ b/eo/src/eoLottery.h @@ -30,7 +30,7 @@ #include // #include // accumulate -#include "selectors.h" +#include "utils/selectors.h" #include // eoPop eoSelect MINFLOAT //----------------------------------------------------------------------------- diff --git a/eo/src/eoNegExp.h b/eo/src/eoNegExp.h index 7829a3c5..3d6be5e2 100644 --- a/eo/src/eoNegExp.h +++ b/eo/src/eoNegExp.h @@ -30,7 +30,7 @@ #include #include // for base class -#include // for base class +#include // for base class //----------------------------------------------------------------------------- // Class eoNegExp diff --git a/eo/src/eoNormal.h b/eo/src/eoNormal.h index 63904efc..09a75d7f 100644 --- a/eo/src/eoNormal.h +++ b/eo/src/eoNormal.h @@ -29,7 +29,7 @@ #include #include // for base class -#include // for random number generator +#include // for random number generator //----------------------------------------------------------------------------- // Class eoNormal diff --git a/eo/src/eoObject.h b/eo/src/eoObject.h index 82724ac2..c46c8855 100644 --- a/eo/src/eoObject.h +++ b/eo/src/eoObject.h @@ -27,11 +27,11 @@ //----------------------------------------------------------------------------- -#include // For limits definition +#include // For limits definition #include // istream, ostream #include // string -#include "compatibility.h" +#include "utils/compatibility.h" using namespace std; @@ -57,11 +57,15 @@ class eoObject /// Virtual dtor. They are needed in virtual class hierarchies. virtual ~eoObject() {} - /** Return the class id. This should be redefined in each class; but - it's got code as an example of implementation. Only "leaf" classes - can be non-virtual. + /** Return the class id. This should be redefined in each class. + Only "leaf" classes can be non-virtual. + + Maarten: removed the default implementation as this proved to + be too error-prone: I found several classes that had a typo in + className (like classname), which would print eoObject instead of + their own... */ - virtual string className() const { return "eoObject"; } + virtual string className() const = 0; }; diff --git a/eo/src/eoStochTournament.h b/eo/src/eoStochTournament.h index 4ef6e0f7..215ca3a5 100644 --- a/eo/src/eoStochTournament.h +++ b/eo/src/eoStochTournament.h @@ -31,7 +31,7 @@ #include // #include // accumulate #include // eoPop eoSelect MINFLOAT -#include +#include //----------------------------------------------------------------------------- /** eoStochTournament: a selection method that selects ONE individual by diff --git a/eo/src/eoUniform.h b/eo/src/eoUniform.h index c824673f..90df59fe 100644 --- a/eo/src/eoUniform.h +++ b/eo/src/eoUniform.h @@ -29,7 +29,7 @@ //----------------------------------------------------------------------------- #include -#include +#include //----------------------------------------------------------------------------- // Class eoUniform diff --git a/eo/src/eoUniformSelect.h b/eo/src/eoUniformSelect.h index ab65a7f3..0c4707ee 100644 --- a/eo/src/eoUniformSelect.h +++ b/eo/src/eoUniformSelect.h @@ -32,7 +32,7 @@ #include // #include // accumulate #include // eoPop eoSelect MINFLOAT -#include +#include //----------------------------------------------------------------------------- /** eoUniformSelect: a selection method that selects ONE individual randomly diff --git a/eo/src/ga/eoBitOp.h b/eo/src/ga/eoBitOp.h index 78337fbb..754313e8 100644 --- a/eo/src/ga/eoBitOp.h +++ b/eo/src/ga/eoBitOp.h @@ -9,7 +9,7 @@ #include // swap_ranges #include // eoUniform -#include // eoBin +#include // eoBin #include // eoMonOp diff --git a/eo/src/other/eoExternalOpFunctions.cpp b/eo/src/other/eoExternalOpFunctions.cpp index 34efcf41..88f24654 100644 --- a/eo/src/other/eoExternalOpFunctions.cpp +++ b/eo/src/other/eoExternalOpFunctions.cpp @@ -33,7 +33,7 @@ #include "eoRnd.h" template -class eoExternalInitFunc +class eoExternalInitFunc { public : diff --git a/eo/src/utils/compatibility.h b/eo/src/utils/compatibility.h index 75479c14..353183f7 100644 --- a/eo/src/utils/compatibility.h +++ b/eo/src/utils/compatibility.h @@ -38,6 +38,7 @@ nasty habit of #define min and max in stdlib.h (and windows.h) I'm trying to undo this horrible macro magic (microsoft yet macrohard) here. Sure hope it works */ +#pragma warning(disable:4786) #include diff --git a/eo/src/utils/eoParser.cpp b/eo/src/utils/eoParser.cpp index b6402de8..2ef30b77 100644 --- a/eo/src/utils/eoParser.cpp +++ b/eo/src/utils/eoParser.cpp @@ -1,3 +1,7 @@ +#ifdef _MSC_VER +#pragma warning(disable:4786) +#endif + #include #include #include @@ -6,6 +10,11 @@ using namespace std; +void eoWarning(std::string str) +{ + cout << str << '\n'; +} + std::ostream& printSectionHeader(std::ostream& os, std::string section) { os << '\n' << setw(10) << "###### " << setw(20) << section << setw(10) << " ######\n"; diff --git a/eo/src/utils/eoParser.h b/eo/src/utils/eoParser.h index 17dddcae..bc3c09a2 100644 --- a/eo/src/utils/eoParser.h +++ b/eo/src/utils/eoParser.h @@ -56,11 +56,6 @@ public : virtual void processParam(eoParam& param, std::string section = "") = 0; }; -void eoWarning(std::string str) -{ - cout << str << '\n'; -} - /** eoParser: command line parser and configuration file reader This class is persistent, so it can be stored and reloaded to restore diff --git a/eo/src/utils/eoRNG.h b/eo/src/utils/eoRNG.h index 76f63166..5f2abb78 100644 --- a/eo/src/utils/eoRNG.h +++ b/eo/src/utils/eoRNG.h @@ -240,6 +240,7 @@ public : _is >> cacheValue; } + std::string className(void) const { return "Mersenne-Twister"; } private : uint32 restart(void); diff --git a/eo/src/utils/selectors.h b/eo/src/utils/selectors.h new file mode 100644 index 00000000..2b5290f5 --- /dev/null +++ b/eo/src/utils/selectors.h @@ -0,0 +1,314 @@ +/* -*- 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 + It select(It begin, It end, params, eoRng& gen = rng); + + template + const EOT& select(const eoPop& pop, params, eoRng& gen = rng); + + template + EOT& select(eoPop& 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 + +#include "eoRNG.h" + +template +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... + */ + eo1.fitness(0.0); // tried to cast it to an EOT::Fitness, but for some reason GNU barfs on this + eo2.fitness(1.0); + + return eo2 < eo1; // check whether we have a minimizing fitness +}; + +inline double scale_fitness(const std::pair& _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 +double sum_fitness(It begin, It end) +{ + double sum = 0.0; + + for (; begin != end; ++begin) + { + double v = static_cast(begin->fitness()); + if (v < 0.0) + throw std::logical_error("Negative Fitness Encountered"); + sum += v; + } + + return sum; +} + +template +double sum_fitness(const eoPop& _pop) +{ + return sum_fitness(_pop.begin(), _pop.end()); +} + +template +double sum_fitness(const eoPop& _pop, std::pair& _minmax) +{ + eoPop::const_iterator it = _pop.begin(); + + _minmax.first = it->fitness(); + _minmax.second = it++->fitness(); + + for(; it != _pop.end(); ++it) + { + double v = static_cast(it->fitness()); + + _minmax.first = std::min(_minmax.first, v); + _minmax.second = std::max(_minmax.second, v); + + rawTotal += v; + } + + if (minimizing_fitness()) + { + 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(static_cast(it->fitness())); + + scaledTotal += v; + } +} + +template +It roulette_wheel(It _begin, It _end, double total, eoRng& _gen = rng) +{ + float roulette = _gen.uniform(total); + + It i = _begin; + + while (roulette > 0.0) + { + roulette -= static_cast(*(i++)); + } + + return --i; +} + +template +const EOT& roulette_wheel(const eoPop& _pop, double total, eoRng& _gen = rng) +{ + float roulette = _gen.uniform(total); + + eoPop::const_iterator i = _pop.begin(); + + while (roulette > 0.0) + { + roulette -= static_cast((i++)->fitness()); + } + + return *--i; +} + +template +EOT& roulette_wheel(eoPop& _pop, double total, eoRng& _gen = rng) +{ + float roulette = _gen.uniform(total); + + eoPop::iterator i = _pop.begin(); + + while (roulette > 0.0) + { + roulette -= static_cast((i++)->fitness()); + } + + return *--i; +} + +template +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 +const EOT& deterministic_tournament(const eoPop& _pop, unsigned _t_size, eoRng& _gen = rng) +{ + return *deterministic_tournament(_pop.begin(), _pop.end(), _t_size, _gen); +} + +template +EOT& deterministic_tournament(eoPop& _pop, unsigned _t_size, eoRng& _gen = rng) +{ + return *deterministic_tournament(_pop.begin(), _pop.end(), _t_size, _gen); +} + +template +It inverse_deterministic_tournament(It _begin, It _end, unsigned _t_size, eoRng& _gen = rng) +{ + It worst = _begin + _gen.random(_end - _begin); + + for (unsigned i = 0; i < _t_size - 1; ++i) + { + It competitor = _begin + _gen.random(_end - _begin); + + if (competitor == worst) + { + --i; + continue; // try again + } + + if (*competitor < *worst) + { + worst = competitor; + } + } + + return worst; +} + +template +const EOT& inverse_deterministic_tournament(const eoPop& _pop, unsigned _t_size, eoRng& _gen = rng) +{ + return *inverse_deterministic_tournament(_pop.begin(), _pop.end(), _t_size, _gen); +} + +template +EOT& inverse_deterministic_tournament(eoPop& _pop, unsigned _t_size, eoRng& _gen = rng) +{ + return *inverse_deterministic_tournament(_pop.begin(), _pop.end(), _t_size, _gen); +} + +template +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 +const EOT& stochastic_tournament(const eoPop& _pop, double _t_rate, eoRng& _gen = rng) +{ + return *stochastic_tournament(_pop.begin(), _pop.end(), _t_rate, _gen); +} + +template +EOT& stochastic_tournament(eoPop& _pop, double _t_rate, eoRng& _gen = rng) +{ + return *stochastic_tournament(_pop.begin(), _pop.end(), _t_rate, _gen); +} + +template +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 +const EOT& inverse_stochastic_tournament(const eoPop& _pop, double _t_rate, eoRng& _gen = rng) +{ + return *inverse_stochastic_tournament(_pop.begin(), _pop.end(), _t_rate, _gen); +} + +template +EOT& inverse_stochastic_tournament(eoPop& _pop, double _t_rate, eoRng& _gen = rng) +{ + return *inverse_stochastic_tournament(_pop.begin(), _pop.end(), _t_rate, _gen); +} + + +#endif