From 4c4ce70c0468f6fb0c490d2e15f2ff9b5fa62f9b Mon Sep 17 00:00:00 2001 From: mac Date: Mon, 12 Jun 2000 20:09:59 +0000 Subject: [PATCH] New ES routines --- eo/src/es/eoEsBase.h | 59 +++++++ eo/src/es/eoEsChromInit.h | 134 +++++++++++++++ eo/src/es/eoEsFull.h | 92 +++++++++++ eo/src/es/eoEsMutate.h | 282 ++++++++++++++++++++++++++++++++ eo/src/es/eoEsMutationInit.h | 105 ++++++++++++ eo/src/es/eoEsObjectiveBounds.h | 81 +++++++++ eo/src/es/eoEsSimple.h | 81 +++++++++ eo/src/es/eoEsStdev.h | 81 +++++++++ eo/src/es/evolution_strategies | 15 ++ eo/test/Makefile.am | 9 +- eo/test/real_value.h | 13 +- eo/test/t-eoESFull.cpp | 181 +++++++++++--------- eo/win/.cvsignore | 1 + eo/win/eo.dsp | 4 + eo/win/eo_win.dsw | 3 + eo/win/esfull.dsp | 37 +++-- eo/win/t_externalEO.dsp | 24 ++- 17 files changed, 1102 insertions(+), 100 deletions(-) create mode 100644 eo/src/es/eoEsBase.h create mode 100644 eo/src/es/eoEsChromInit.h create mode 100644 eo/src/es/eoEsFull.h create mode 100644 eo/src/es/eoEsMutate.h create mode 100644 eo/src/es/eoEsMutationInit.h create mode 100644 eo/src/es/eoEsObjectiveBounds.h create mode 100644 eo/src/es/eoEsSimple.h create mode 100644 eo/src/es/eoEsStdev.h create mode 100644 eo/src/es/evolution_strategies diff --git a/eo/src/es/eoEsBase.h b/eo/src/es/eoEsBase.h new file mode 100644 index 000000000..5bca18a2d --- /dev/null +++ b/eo/src/es/eoEsBase.h @@ -0,0 +1,59 @@ +// -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*- + +//----------------------------------------------------------------------------- +// eoEsBase.h +// (c) GeNeura Team, 2000 - EEAAX 1999 - Maarten Keijzer 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 + Marc.Schoenauer@polytechnique.fr + mak@dhi.dk + */ +//----------------------------------------------------------------------------- + +#ifndef _eoEsBase_h +#define _eoEsBase_h + +/** +\ingroup EvolutionStrategies + + Base class for evolution strategies, just derives from EO and vector and + redirects the operator< to EO (fitness based comparison) +*/ + +template +class eoEsBase : public EO, public std::vector +{ + public : + + typedef double Type; + + /// to avoid conflicts between EO::operator< and vector::operator< + bool operator<(const eoEsBase& _eo) const + { + return EO::operator<(_eo); + } + +}; + +/// to avoid conflicts between EO::operator< and vector::operator< +template +bool operator<(const eoEsBase& _eo1, const eoEsBase& _eo2) +{ + return _eo1.operator<(_eo2); +} + +#endif \ No newline at end of file diff --git a/eo/src/es/eoEsChromInit.h b/eo/src/es/eoEsChromInit.h new file mode 100644 index 000000000..872fc8ed5 --- /dev/null +++ b/eo/src/es/eoEsChromInit.h @@ -0,0 +1,134 @@ +// -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*- + +//----------------------------------------------------------------------------- +// eoEsChromInit.h +// (c) Maarten Keijzer 2000, GeNeura Team, 1998 - EEAAX 1999 +/* + 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 + mak@dhi.dk + */ +//----------------------------------------------------------------------------- + +#ifndef _eoEsChromInit_H +#define _eoEsChromInit_H + +#include +#include +#include +#include +#include + +#include + +#ifndef M_PI +#define M_PI 3.1415926535897932384626433832795 +#endif + +/** +\ingroup EvolutionStrategies + + Random Es-chromosome initializer (therefore derived from eoRnd) + + This class can initialize three types of Es's: + + eoEsSimple + eoEsStdev + eoEsFull + + @see eoEsSimple eoEsStdev eoEsFull eoInit +*/ + +template +class eoEsChromInit : public eoInit +{ +public : + typedef typename EOT::Fitness FitT; + + eoEsChromInit(eoEsObjectiveBounds& _bounds) : bounds(_bounds) + {} + + EOT operator()() + { + return create(EOT()); + } + +private : + + eoEsSimple& create(eoEsSimple& result) + { + result.resize(bounds.chromSize()); + + for (unsigned i = 0; i < result.size(); ++i) + { + result[i] = bounds.minimum(i) + rng.uniform(bounds.maximum(i) - bounds.minimum(i)); + } + + return result; + } + + eoEsStdev create(eoEsStdev& result) + { + unsigned chromSize = bounds.chromSize(); + result.resize(chromSize); + result.stdevs.resize(chromSize); + + for (unsigned i = 0; i < chromSize; ++i) + { + double length = bounds.maximum(i) - bounds.minimum(i); + result[i] = bounds.minimum(i) + rng.uniform(length); + + // Just a guess at the stdevs (anyone a better idea?) + result.stdevs[i] = rng.uniform(length); + } + + return result; + } + + eoEsFull create(eoEsFull& result) + { + unsigned chromSize = bounds.chromSize(); + result.resize(chromSize); + result.stdevs.resize(chromSize); + + unsigned i; + + for (i = 0; i < chromSize; ++i) + { + double length = bounds.maximum(i) - bounds.minimum(i); + result[i] = bounds.minimum(i) + rng.uniform(length); + + // Just a guess at the stdevs (anyone a better idea?) + result.stdevs[i] = rng.uniform(length); + } + + // nb of rotation angles: N*(N-1)/2 (in general!) + result.correlations.resize(chromSize*(chromSize - 1) / 2); + + for (i = 0; i < result.correlations.size(); ++i) + { + // And another random guess for random initialization + result.correlations[i] = rng.uniform(2 * M_PI) - M_PI; + } + + return result; + } + + eoEsObjectiveBounds& bounds; +}; + +#endif \ No newline at end of file diff --git a/eo/src/es/eoEsFull.h b/eo/src/es/eoEsFull.h new file mode 100644 index 000000000..7f154ad2b --- /dev/null +++ b/eo/src/es/eoEsFull.h @@ -0,0 +1,92 @@ +// -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*- + +//----------------------------------------------------------------------------- +// eoEsFull.h +// (c) GeNeura Team, 2000 - EEAAX 1999 - Maarten Keijzer 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 + Marc.Schoenauer@polytechnique.fr + mak@dhi.dk + */ +//----------------------------------------------------------------------------- + +#ifndef _eoEsFull_h +#define _eoEsFull_h + +#include + +/** +\ingroup EvolutionStrategies + + The most complex evolutionary strategy representation. Co-evolving mutation +rates and correlated mutations. +*/ + +template +class eoEsFull : public eoEsBase +{ + public : + + eoEsFull(void) : eoEsBase() {} + + std::string className(void) const { return "eoEsFull"; } + + void printOn(std::ostream& os) const + { + os << size() << ' '; + + std::copy(begin(), end(), std::ostream_iterator(os)); + + os << ' '; + std::copy(stdevs.begin(), stdevs.end(), std::ostream_iterator(os)); + + os << ' '; + + std::copy(correlations.begin(), correlations.end(), std::ostream_iterator(os)); + + os << ' '; + } + + void readFrom(istream& is) + { + unsigned sz; + is >> sz; + + resize(sz); + unsigned i; + + for (i = 0; i < sz; ++i) + is >> operator[](i); + + stdevs.resize(sz); + + for (i = 0; i < sz; ++i) + is >> stdevs[i]; + + correlations.resize(sz*(sz - 1) / 2); + + for (i = 0; i < correlations.size(); ++i) + is >> correlations[i]; + } + + vector stdevs; + vector correlations; +}; + + + +#endif \ No newline at end of file diff --git a/eo/src/es/eoEsMutate.h b/eo/src/es/eoEsMutate.h new file mode 100644 index 000000000..0a6138428 --- /dev/null +++ b/eo/src/es/eoEsMutate.h @@ -0,0 +1,282 @@ +// -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*- + +//----------------------------------------------------------------------------- +// eoESMute.h : ES mutation +// (c) Maarten Keijzer 2000 & GeNeura Team, 1998 for the EO part +// Th. Baeck 1994 and EEAAX 1999 for the ES part +/* + 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 + http://eeaax.cmap.polytchnique.fr/ + */ +//----------------------------------------------------------------------------- + + +#ifndef _EOESMUTATE_H +#define _EOESMUTATE_H + +#include +#include +#include // for exp + +#include +#include +#include +#include +#include + +#include + +#ifndef M_PI +#define M_PI 3.1415926535897932384626433832795 +#endif + +/** + +\ingroup EvolutionStrategies + + ES-style mutation in the large: Obviously, valid only for eoES* + + It is currently valid for three types of ES chromosomes: + + eoEsSimple: only 1 std deviation + eoEsStdev: as many standard deviations as object variables + eoEsFull: The whole guacemole: correlations, stdevs and object variables + + Each of these three variant has it's own operator() in eoEsMutate and intialization + is also split into three cases (that share some commonalities) +*/ + +template +class eoEsMutate: public eoMonOp< EOT > { +public: + + typedef EOT::Fitness FitT; + + /** Initialization + parameters: + + @param _init proxy class for initializating the three parameters eoEsMutate needs + @param _bounds the bounds for the objective variables + */ + eoEsMutate(eoEsMutationInit& _init, eoEsObjectiveBounds& _bounds) : bounds(_bounds) + { + init(EOT(), _init); // initialize on actual type used + } + + /// needed virtual dtor + virtual ~eoEsMutate() {}; + + /** Inherited from eoObject + @see eoObject + */ + virtual string className() const {return "eoESMutate";}; + + /** + Mutate eoEsSimple + */ + virtual void operator()( eoEsSimple& _eo) const + { + _eo.stdev *= exp(TauLcl * rng.normal()); + + if (_eo.stdev < stdev_eps) + _eo.stdev = stdev_eps; + + // now apply to all + + for (unsigned i = 0; i < _eo.size(); ++i) + { + _eo[i] += _eo.stdev * rng.normal(); + } + + keepInBounds(_eo); + } + + /// mutations - standard and correlated + // ========= + /* + * Standard mutation of object variables and standard + * deviations in ESs. + * If there are fewer different standard deviations available + * than the dimension of the objective function requires, the + * last standard deviation is responsible for ALL remaining + * object variables. + * Schwefel 1977: Numerische Optimierung von Computer-Modellen + * mittels der Evolutionsstrategie, pp. 165 ff. + */ + + virtual void operator()( eoEsStdev& _eo ) const + { + double global = exp(TauGlb * rng.normal()); + for (unsigned i = 0; i < _eo.size(); i++) + { + double stdev = _eo.stdevs[i]; + stdev *= global * exp(TauLcl * rng.normal()); + + if (stdev < stdev_eps) + stdev = stdev_eps; + + _eo.stdevs[i] = stdev; + _eo[i] += stdev * rng.normal(); + } + + keepInBounds(_eo); + } + + /* + * Correlated mutations in ESs, according to the following + * sources: + * H.-P. Schwefel: Internal Report of KFA Juelich, KFA-STE-IB-3/80 + * p. 43, 1980 + * G. Rudolph: Globale Optimierung mit parallelen Evolutions- + * strategien, Diploma Thesis, University of Dortmund, 1990 + */ + + // Code from Thomas Baeck + + virtual void operator()( eoEsFull & _eo ) const + { + + /* + * First: mutate standard deviations (as above). + */ + + double global = exp(TauGlb * rng.normal()); + for (unsigned i = 0; i < _eo.size(); i++) + { + double stdev = _eo.stdevs[i]; + stdev *= global * exp(TauLcl * rng.normal()); + + if (stdev < stdev_eps) + stdev = stdev_eps; + + _eo.stdevs[i] = stdev; + } + + + /* + * Mutate rotation angles. + */ + + for (i = 0; i < _eo.correlations.size(); i++) + { + _eo.correlations[i] += TauBeta * rng.normal(); + if ( fabs(_eo.correlations[i]) > M_PI ) + { + _eo.correlations[i] -= M_PI * (int) (_eo.correlations[i]/M_PI) ; + } + } + + /* + * Perform correlated mutations. + */ + unsigned k, n1, n2; + double d1,d2, S, C; + + vector VarStp(_eo.size()); + for (i = 0; i < _eo.size(); i++) + VarStp[i] = _eo.stdevs[i] * rng.normal(); + + unsigned nq = _eo.correlations.size() - 1; + + for (k = 0; k < _eo.size()-1; k++) + { + n1 = _eo.size() - k - 1; + n2 = _eo.size() - 1; + + for (i = 0; i < k; i++) + { + d1 = VarStp[n1]; + d2 = VarStp[n2]; + S = sin( _eo.correlations[nq] ); + C = cos( _eo.correlations[nq] ); + VarStp[n2] = d1 * S + d2 * C; + VarStp[n1] = d1 * C - d2 * S; + n2--; + nq--; + } + } + + for (i = 0; i < _eo.size(); i++) + _eo[i] += VarStp[i]; + + keepInBounds(_eo); + } + + void keepInBounds(eoEsBase& _eo) const + { + for (unsigned i = 0; i < _eo.size(); ++i) + { + if (_eo[i] < bounds.minimum(i)) + _eo[i] = bounds.minimum(i); + else if (_eo[i] > bounds.maximum(i)) + _eo[i] = bounds.maximum(i); + } + } + + private : + + void init(eoEsSimple&, eoEsMutationInit& _init) + { + unsigned size = bounds.chromSize(); + TauLcl = _init.TauLcl(); + TauLcl /= sqrt((double) size); + } + + void init(eoEsStdev&, eoEsMutationInit& _init) + { + unsigned size = bounds.chromSize(); + + TauLcl = _init.TauLcl(); + TauGlb = _init.TauGlb(); + + // renormalization + TauLcl /= sqrt( 2.0 * sqrt( (double)size ) ); + TauGlb /= sqrt( 2.0 * ( (double) size ) ); + } + + void init(eoEsFull&, eoEsMutationInit& _init) + { + init(eoEsStdev(), _init); + TauBeta = _init.TauBeta(); + } + + // the data + //========= + double TauLcl; /* Local factor for mutation of std deviations */ + double TauGlb; /* Global factor for mutation of std deviations */ + double TauBeta; /* Factor for mutation of correlation parameters */ + + eoEsObjectiveBounds& bounds; + + static const double stdev_eps; +}; + +template +const double eoEsMutate::stdev_eps = 1.0e-40; + +/* + * Correlated mutations in ESs, according to the following + * sources: + * H.-P. Schwefel: Internal Report of KFA Juelich, KFA-STE-IB-3/80 + * p. 43, 1980 + * G. Rudolph: Globale Optimierung mit parallelen Evolutions- + * strategien, Diploma Thesis, University of Dortmund, 1990 + */ + +#endif + diff --git a/eo/src/es/eoEsMutationInit.h b/eo/src/es/eoEsMutationInit.h new file mode 100644 index 000000000..b2f60b3d0 --- /dev/null +++ b/eo/src/es/eoEsMutationInit.h @@ -0,0 +1,105 @@ +// -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*- + +//----------------------------------------------------------------------------- +// eoEsMutationInit.h +// (c) GeNeura Team, 1998 - EEAAX 1999 - Maarten Keijzer 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 + Marc.Schoenauer@polytechnique.fr + mak@dhi.dk + */ +//----------------------------------------------------------------------------- + +#ifndef _eoEsInit_h +#define _eoEsInit_h + +#include + +/** +\ingroup EvolutionStrategies + + eoESMutationInit. Proxy class that is used for initializing the mutation + operator. It provides an interface between eoEsMutate and the abstract + parameterLoader. It also provides the names for the parameters in this + class as virtual protected member functions. + + If you have more than a single ES in a project that need different + names in the configuration files, you might consider overriding this class + to change the names. + + @see eoEsMutate +*/ +class eoEsMutationInit +{ + public : + + eoEsMutationInit(eoParameterLoader& _parser) : parser(_parser), TauLclParam(0), TauGlbParam(0), TauBetaParam(0) {} + + double TauLcl(void) + { + if (TauLclParam == 0) + { + TauLclParam = &parser.createParam(1.0, TauLclName(), "Local Tau", TauLclShort(), section()); + } + + return TauLclParam->value(); + } + + double TauGlb(void) + { + if (TauGlbParam == 0) + { + TauGlbParam = &parser.createParam(1.0, TauGlbName(), "Global Tau", TauGlbShort(), section()); + } + + return TauGlbParam->value(); + } + + double TauBeta(void) + { + if (TauBetaParam == 0) + { + TauBetaParam = &parser.createParam(0.0873, TauBetaName(), "Beta", TauBetaShort(), section()); + } + + return TauBetaParam->value(); + } + + protected : + + virtual std::string section(void) + { return "Parameters of ES mutation (before renormalization)"; } + + virtual std::string TauLclName(void) const { return "TauLcL"; } + virtual char TauLclShort(void) const { return 'l'; } + + virtual std::string TauGlbName(void) const { return "TauGlb"; } + virtual char TauGlbShort(void) const { return 'g'; } + + virtual std::string TauBetaName(void) const { return "Beta"; } + virtual char TauBetaShort(void) const { return 'b'; } + + private : + + eoParameterLoader& parser; + + eoValueParam* TauLclParam; + eoValueParam* TauGlbParam; + eoValueParam* TauBetaParam; +}; + +#endif \ No newline at end of file diff --git a/eo/src/es/eoEsObjectiveBounds.h b/eo/src/es/eoEsObjectiveBounds.h new file mode 100644 index 000000000..7f152ea48 --- /dev/null +++ b/eo/src/es/eoEsObjectiveBounds.h @@ -0,0 +1,81 @@ +// -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*- + +//----------------------------------------------------------------------------- +// eoEsObjectiveBounds.h +// (c) Maarten Keijzer 2000, GeNeura Team, 1998 - EEAAX 1999 +/* + 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 + mak@dhi.dk + */ +//----------------------------------------------------------------------------- + +#ifndef _eoEsObjectiveBounds_h +#define _eoEsObjectiveBounds_h + +/** +\defgroup EvolutionStrategies + + Various classes for the initialization and mutation of real valued vectors. + + Supports simple mutations and various more adaptable mutations, including + correlated mutations. + +*/ + + +/** +\class eoEsObjectiveBounds eoEsObjectiveBounds.h es/eoEsObjectiveBounds.h +\ingroup EvolutionStrategies + + Defines the minima and maxima of the object variables. Needed by eoEsChromInit + and eoEsMutate + + @see eoEsChromInit eoEsMutate +*/ +class eoEsObjectiveBounds +{ + public : + + /** + Objective bounds for a global minimum and maximum + */ + eoEsObjectiveBounds(int _nGenes, double _min, double _max) : repMinimum(_nGenes), repMaximum(_nGenes) + { + std::fill(repMinimum.begin(), repMinimum.end(), _min); + std::fill(repMaximum.begin(), repMaximum.end(), _max); + } + + /** + Objective bounds for a per gene minimum and maximum + */ + eoEsObjectiveBounds(const std::vector& _min, const std::vector& _max) + : repMinimum(_min), repMaximum(_max) {} + + typedef double doubleype; + + double minimum(size_t i) { return repMinimum[i]; } + double maximum(size_t i) { return repMaximum[i]; } + + unsigned chromSize(void) const { return repMinimum.size(); } + + private : + std::vector repMinimum; + std::vector repMaximum; +}; + +#endif \ No newline at end of file diff --git a/eo/src/es/eoEsSimple.h b/eo/src/es/eoEsSimple.h new file mode 100644 index 000000000..b93d0e58b --- /dev/null +++ b/eo/src/es/eoEsSimple.h @@ -0,0 +1,81 @@ +// -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*- + +//----------------------------------------------------------------------------- +// eoEsSimple.h +// (c) GeNeura Team, 2000 - EEAAX 1999, Maarten Keijzer 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 + Marc.Schoenauer@polytechnique.fr + mak@dhi.dk + */ +//----------------------------------------------------------------------------- + +#ifndef _eoEsSimple_h +#define _eoEsSimple_h + +#include +#include + +#include + +/** +\ingroup EvolutionStrategies + + One of the more simple evolution strategies, sporting just a single +stdeviation for the entire chromosome. For more advanced versions +see also eoEsStdev eoEsFull + + @see eoEsStdev eoEsFull + +*/ + +template +class eoEsSimple : public eoEsBase +{ +public : + + eoEsSimple(void) : eoEsBase() {} + + std::string className(void) const { return "eoEsSimple"; } + + void printOn(ostream& os) const + { + os << size() << ' '; + + std::copy(begin(), end(), ostream_iterator(os)); + + os << ' ' << stdev << ' '; + } + + void readFrom(istream& is) + { + unsigned sz; + is >> sz; + + resize(sz); + unsigned i; + + for (i = 0; i < sz; ++i) + is >> operator[](i); + + is >> stdev; + } + + double stdev; +}; + +#endif diff --git a/eo/src/es/eoEsStdev.h b/eo/src/es/eoEsStdev.h new file mode 100644 index 000000000..1699e02c2 --- /dev/null +++ b/eo/src/es/eoEsStdev.h @@ -0,0 +1,81 @@ +// -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*- + +//----------------------------------------------------------------------------- +// eoEsStdev.h +// (c) GeNeura Team, 2000 - EEAAX 1999 - Maarten Keijzer 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 + Marc.Schoenauer@polytechnique.fr + mak@dhi.dk + */ +//----------------------------------------------------------------------------- + +#ifndef _eoEsStdev_h +#define _eoEsStdev_h + +#include + +/** +\ingroup EvolutionStrategies + +Evolutionary strategie style representation, supporting co-evolving standard +deviations. +*/ + +template +class eoEsStdev : public eoEsBase +{ + public : + + eoEsStdev(void) : eoEsBase() {} + + std::string className(void) const { return "eoEsStdev"; } + + void printOn(std::ostream& os) const + { + os << size() << ' '; + + std::copy(begin(), end(), std::ostream_iterator(os)); + + os << ' '; + std::copy(stdevs.begin(), stdevs.end(), std::ostream_iterator(os)); + + os << ' '; + } + + void readFrom(istream& is) + { + unsigned sz; + is >> sz; + + resize(sz); + unsigned i; + + for (i = 0; i < sz; ++i) + is >> operator[](i); + + stdevs.resize(sz); + + for (i = 0; i < sz; ++i) + is >> stdevs[i]; + } + + + vector stdevs; +}; + +#endif \ No newline at end of file diff --git a/eo/src/es/evolution_strategies b/eo/src/es/evolution_strategies new file mode 100644 index 000000000..d1c729ba9 --- /dev/null +++ b/eo/src/es/evolution_strategies @@ -0,0 +1,15 @@ +#ifndef _eoEs_h +#define _eoEs_h + +#include +#include +#include +#include + +#include +#include + +#include + + +#endif diff --git a/eo/test/Makefile.am b/eo/test/Makefile.am index 5205b8765..9d12043f1 100644 --- a/eo/test/Makefile.am +++ b/eo/test/Makefile.am @@ -18,7 +18,7 @@ noinst_PROGRAMS = t-eobreeder t-eoinclusion t-eoinsertion t-eo t-eofitness \ t-eoproblem t-eobin t-eolottery t-eo2dVector t-eogeneration t-eoEasyEA\ t-eoNonUniform t-eoUniform t-eoRandom t-eoStateAndParser \ t-eoAtomOps t-selectOne t-eoGOpSel \ - t-eoVector t-eoCheckpointing t-eoExternalEO + t-eoVector t-eoCheckpointing t-eoExternalEO t-eoESFull ############################################################################### @@ -178,4 +178,11 @@ t_eoExternalEO_LDADD = $(LDADDS) ############################################################################### +t_eoESFull_SOURCES = t-eoESFull.cpp +t_eoESFull_DEPENDENCIES = $(DEPS) +t_eoESFull_LDFLAGS = -lm +t_eoESFull_LDADD = $(LDADDS) + +############################################################################### + diff --git a/eo/test/real_value.h b/eo/test/real_value.h index 324ecae8d..ed983bc2a 100644 --- a/eo/test/real_value.h +++ b/eo/test/real_value.h @@ -1,19 +1,18 @@ -#include - +#include //----------------------------------------------------------------------------- -typedef vector Vec; -/** Just a simple function that takes an eoVector and sets the fitnes - to -sphere (we'll see later how to minimize rather than maximize!) +/** Just a simple function that takes an eoEsBase and sets the fitnes + to sphere @param _ind A floatingpoint vector */ -float real_value(const eoESFullChrom& _ind) + +double real_value(const eoEsBase& _ind) { double sum = 0; /* compute in double format, even if return a float */ for (unsigned i = 0; i < _ind.size(); i++) sum += _ind[i] * _ind[i]; - return -sum; + return sum; } diff --git a/eo/test/t-eoESFull.cpp b/eo/test/t-eoESFull.cpp index eae0e9811..46372ea06 100644 --- a/eo/test/t-eoESFull.cpp +++ b/eo/test/t-eoESFull.cpp @@ -4,110 +4,145 @@ #pragma warning(disable:4786) #endif +#include #include #include #include +#include using namespace std; #include +#include -// evolution specific +#include +#include + +// population +#include + +// evaluation specific #include // representation specific -#include // though contained in following -//#include -//#include -//#include -// this fitness +#include + #include "real_value.h" // the sphere fitness // Now the main /////////////// -typedef eoESFullChrom Ind; - -main(int argc, char *argv[]) { -// unsigned mu, lambda; -// bool comma; +typedef double FitT; +template +void runAlgorithm(EOT, eoParser& _parser, eoEsObjectiveBounds& _bounds); + +main(int argc, char *argv[]) +{ // Create the command-line parser eoParser parser( argc, argv, "Basic EA for vector with adaptive mutations"); // Define Parameters and load them - eoValueParam& seed = parser.createParam(time(0), "seed", "Random number seed"); - eoValueParam& load_name = parser.createParam("", "Load","Load a state file",'L'); - eoValueParam& save_name = parser.createParam("", "Save","Saves a state file",'S'); - + eoValueParam& seed = parser.createParam(static_cast(time(0)), "seed", "Random number seed"); + eoValueParam& load_name = parser.createParam(string(), "Load","Load a state file",'L'); + eoValueParam& save_name = parser.createParam(string(), "Save","Saves a state file",'S'); + eoValueParam& stdevs = parser.createParam(true, "Stdev", "Use adaptive mutation rates", 's'); + eoValueParam& corr = parser.createParam(true, "Correl", "Use correlated mutations", 'c'); + eoValueParam& chromSize = parser.createParam(unsigned(1), "ChromSize", "Number of chromosomes", 'n'); + eoValueParam& minimum = parser.createParam(-1.e5, "Min", "Minimum for Objective Variables", 'l'); + eoValueParam& maximum = parser.createParam(1.e5, "Max", "Maximum for Objective Variables", 'h'); + eoState state; - state.registerObject(parser); - - if (load_name.value() != "") + state.registerObject(parser); + rng.reseed(seed.value()); + + if (!load_name.value().empty()) { // load the parser. This is only neccessary when the user wants to // be able to change the parameters in the state file by hand. state.load(load_name.value()); // load the parser } - - // Evaluation - eoEvalFuncPtr eval( real_value ); + state.registerObject(rng); - - - /* - // Evolution and population parameters - eoScheme the_scheme(parser); - - // recombination and mutation operators, reading their parameters from the parser - eoESReco MyReco(parser, FirstEO); - eoESMutate MyMut(parser, FirstEO); - - // termination conditions read by the parser - eoTermVector the_terms(parser); - - // Initialization of the population - // shoudl be called using the parser, in case you want to read from file(s) - eoESRandomize randomize; // an eoESInd randomnizer - eoPop pop(the_scheme.PopSize(), FirstEO, randomize); - // eval(pop); // shoudl we call it from inside the constructor??? - - // ALL parmeters have been read: write them out - // Writing the parameters on arv[0].status - // but of course this can be modified - see the example parser.cpp - parser.outputParam(); - // except the help parameter??? - if( parser.getBool("-h" , "--help" , "Shows this help")) { - parser.printHelp(); - exit(1); - } - - unsigned i, iind; - - - cout << "Initial population: \n" << endl; - for (i = 0; i < pop.size(); ++i) { - eval(pop[i]); - cout << pop[i].fitness() << "\t" << pop[i] << endl; + eoEsObjectiveBounds bounds(chromSize.value(), minimum.value(), maximum.value()); + + // Run the appropriate algorithm + if (stdevs.value() == false && corr.value == false) + { + runAlgorithm(eoEsSimple() ,parser, bounds); + } + else if (corr.value() == true) + { + runAlgorithm(eoEsFull(),parser, bounds); + } + else + { + runAlgorithm(eoEsStdev(), parser, bounds); } - // the Operators - eoSequentialOpHolder seqholder; - // seqholder.addOp(MyReco, 1.0); - seqholder.addOp(MyMut, 1.0); + // and save + if (!save_name.value().empty()) + { + string file_name = save_name.value(); + save_name.value() = ""; // so that it does not appear in the parser section of the state file + state.save(file_name); + } - // One generation - eoEvolStep evol_scheme(the_scheme, seqholder, eval); - - // the algorithm: - eoFullEA ea(evol_scheme, the_terms); - - ea(pop); - - cout << "Final population: \n" << endl; - for (i = 0; i < pop.size(); ++i) - cout << pop[i].fitness() << "\t" << pop[i] << endl; - */ return 0; } +template +void runAlgorithm(EOT, eoParser& _parser, eoEsObjectiveBounds& _bounds) +{ + // evaluation + eoEvalFuncPtr > eval( real_value ); + // population parameters, unfortunately these can not be altered in the state file + eoValueParam mu = _parser.createParam(unsigned(50), "mu","Size of the population"); + eoValueParamlambda = _parser.createParam(unsigned(250), "lambda", "No. of children to produce"); + + if (mu.value() > lambda.value()) + { + throw logic_error("Mu must be smaller than lambda in a comma strategy"); + } + + // Initialization + eoEsChromInit init(_bounds); + eoPop pop(mu.value(), init); + + // evaluate initial population + eval.range(pop.begin(), pop.end()); + + // Ok, time to set up the algorithm + // Proxy for the mutation parameters + eoEsMutationInit mutateInit(_parser); + + eoEsMutate mutate(mutateInit, _bounds); + + // monitoring, statistics etc. + eoAverageStat average; + eoFileMonitor monitor("test.csv"); + + monitor.add(average); + + // Okok, I'm lazy, here's the algorithm defined inline + + for (unsigned i = 0; i < 20; ++i) + { + pop.resize(pop.size() + lambda.value()); + + for (unsigned j = mu.value(); j < pop.size(); ++j) + { + pop[j] = pop[rng.random(mu.value())]; + mutate(pop[j]); + eval(pop[j]); + } + + // comma strategy + std::sort(pop.begin() + mu.value(), pop.end()); + copy(pop.begin() + mu.value(), pop.begin() + 2 * mu.value(), pop.begin()); + pop.resize(mu.value()); + + average(pop); + monitor(); + } +} diff --git a/eo/win/.cvsignore b/eo/win/.cvsignore index 69fb0bd82..880de1a77 100644 --- a/eo/win/.cvsignore +++ b/eo/win/.cvsignore @@ -4,3 +4,4 @@ .libs Makefile Makefile.in +eo.dsw diff --git a/eo/win/eo.dsp b/eo/win/eo.dsp index 3db96ed83..00c492e00 100644 --- a/eo/win/eo.dsp +++ b/eo/win/eo.dsp @@ -159,6 +159,10 @@ SOURCE=..\src\utils\eoRNG.h # End Source File # Begin Source File +SOURCE=..\src\utils\eoStat.h +# End Source File +# Begin Source File + SOURCE=..\src\utils\eoState.h # End Source File # Begin Source File diff --git a/eo/win/eo_win.dsw b/eo/win/eo_win.dsw index 4fdaee76b..9fe1b8c6b 100644 --- a/eo/win/eo_win.dsw +++ b/eo/win/eo_win.dsw @@ -173,6 +173,9 @@ Package=<5> Package=<4> {{{ + Begin Project Dependency + Project_Dep_Name eo + End Project Dependency }}} ############################################################################### diff --git a/eo/win/esfull.dsp b/eo/win/esfull.dsp index f52a4855d..ffa566ab9 100644 --- a/eo/win/esfull.dsp +++ b/eo/win/esfull.dsp @@ -75,7 +75,7 @@ BSC32=bscmake.exe # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept -# ADD LINK32 eo.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept !ENDIF @@ -89,15 +89,6 @@ LINK32=link.exe # Begin Source File SOURCE="..\test\t-eoESFull.cpp" - -!IF "$(CFG)" == "esfull - Win32 Release" - -!ELSEIF "$(CFG)" == "esfull - Win32 Debug" - -# PROP Exclude_From_Build 1 - -!ENDIF - # End Source File # End Group # Begin Group "Header Files" @@ -105,15 +96,35 @@ SOURCE="..\test\t-eoESFull.cpp" # PROP Default_Filter "h;hpp;hxx;hm;inl" # Begin Source File -SOURCE=..\src\es\eoESFullChrom.h +SOURCE=..\src\es\eoEsBase.h # End Source File # Begin Source File -SOURCE=..\src\es\eoESFullMut.h +SOURCE=..\src\es\eoEsChromInit.h # End Source File # Begin Source File -SOURCE=..\src\es\eoESInit.h +SOURCE=..\src\es\eoEsFull.h +# End Source File +# Begin Source File + +SOURCE=..\src\es\eoEsMutate.h +# End Source File +# Begin Source File + +SOURCE=..\src\es\eoEsMutationInit.h +# End Source File +# Begin Source File + +SOURCE=..\src\es\eoEsObjectiveBounds.h +# End Source File +# Begin Source File + +SOURCE=..\src\es\eoEsSimple.h +# End Source File +# Begin Source File + +SOURCE=..\src\es\eoEsStdev.h # End Source File # End Group # Begin Group "Resource Files" diff --git a/eo/win/t_externalEO.dsp b/eo/win/t_externalEO.dsp index a963505de..32c6cb728 100644 --- a/eo/win/t_externalEO.dsp +++ b/eo/win/t_externalEO.dsp @@ -48,8 +48,8 @@ BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 -# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 !ELSEIF "$(CFG)" == "t_externalEO - Win32 Debug" @@ -63,16 +63,16 @@ LINK32=link.exe # PROP Output_Dir "t_externalEO___Win32_Debug" # PROP Intermediate_Dir "t_externalEO___Win32_Debug" # PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c -# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "../src" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "../src" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c # ADD BASE RSC /l 0x409 /d "_DEBUG" # ADD RSC /l 0x409 /d "_DEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept -# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept !ENDIF @@ -91,6 +91,18 @@ SOURCE="..\test\t-eoExternalEO.cpp" # Begin Group "Header Files" # PROP Default_Filter "h;hpp;hxx;hm;inl" +# Begin Source File + +SOURCE=..\src\eoEvalFuncPtr.h +# End Source File +# Begin Source File + +SOURCE=..\src\other\eoExternalEO.h +# End Source File +# Begin Source File + +SOURCE=..\src\other\eoExternalOpFunctions.h +# End Source File # End Group # Begin Group "Resource Files"