This commit is contained in:
kuepper 2005-09-27 22:06:08 +00:00
commit 3735dbaac4

View file

@ -1,4 +1,4 @@
// -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*- // -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; fill-column: 80; -*-
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// eoESMute.h : ES mutation // eoESMute.h : ES mutation
@ -29,199 +29,171 @@
#ifndef _EOESMUTATE_H #ifndef _EOESMUTATE_H
#define _EOESMUTATE_H #define _EOESMUTATE_H
#include <utils/eoRNG.h> #include <cmath>
#include <eoInit.h> #include <eoInit.h>
#include <cmath> // for exp #include <eoOp.h>
#include <es/eoEsMutationInit.h> #include <es/eoEsMutationInit.h>
#include <es/eoEsSimple.h> #include <es/eoEsSimple.h>
#include <es/eoEsStdev.h> #include <es/eoEsStdev.h>
#include <es/eoEsFull.h> #include <es/eoEsFull.h>
#include <utils/eoRealBounds.h> #include <utils/eoRealBounds.h>
#include <utils/eoRNG.h>
#include <eoOp.h>
#ifndef M_PI #ifndef M_PI
#define M_PI 3.1415926535897932384626433832795 #define M_PI 3.1415926535897932384626433832795
#endif #endif
/** /** @ingroup EvolutionStrategies
\ingroup EvolutionStrategies @brief ES-style mutation in the large
ES-style mutation in the large: Obviously, valid only for eoES* 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
It is currently valid for three types of ES chromosomes: Each of these three variant has it's own operator() in eoEsMutate and
intialization is also split into three cases (that share some
eoEsSimple: only 1 std deviation commonalities)
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 EOT> template <class EOT>
class eoEsMutate: public eoMonOp< EOT > { class eoEsMutate : public eoMonOp< EOT >
{
public: public:
/** Fitness-type */
typedef typename EOT::Fitness FitT; typedef typename EOT::Fitness FitT;
/** Initialization /** Initialization.
parameters:
@param _init proxy class for initializating the three parameters eoEsMutate needs @param _init Proxy class for initializating the three parameters
@param _bounds the bounds for the objective variables eoEsMutate needs
@param _bounds Bounds for the objective variables
*/ */
eoEsMutate(eoEsMutationInit& _init, eoRealVectorBounds& _bounds) : bounds(_bounds) eoEsMutate(eoEsMutationInit& _init, eoRealVectorBounds& _bounds) : bounds(_bounds)
{ {
init(EOT(), _init); // initialize on actual type used init(EOT(), _init); // initialize on actual type used
} }
/// needed virtual dtor /** @brief Virtual Destructor */
virtual ~eoEsMutate() {}; virtual ~eoEsMutate() {};
/** Inherited from eoObject
@see eoObject
*/
virtual std::string className() const {return "eoESMutate";};
/** /** Classname.
Mutate eoEsSimple
*/
virtual bool operator()( eoEsSimple<FitT>& _eo)
{
_eo.stdev *= exp(TauLcl * rng.normal());
if (_eo.stdev < stdev_eps) Inherited from eoObject @see eoObject
@return Name of class.
*/
virtual std::string className() const {return "eoESMutate";};
/** Mutate eoEsSimple */
virtual bool operator()( eoEsSimple<FitT>& _eo)
{
_eo.stdev *= exp(TauLcl * rng.normal());
if (_eo.stdev < stdev_eps)
_eo.stdev = stdev_eps; _eo.stdev = stdev_eps;
// now apply to all
// now apply to all for (unsigned i = 0; i < _eo.size(); ++i)
{
for (unsigned i = 0; i < _eo.size(); ++i) _eo[i] += _eo.stdev * rng.normal();
{ }
_eo[i] += _eo.stdev * rng.normal(); bounds.foldsInBounds(_eo);
} return true;
bounds.foldsInBounds(_eo); }
return true;
}
/// 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 bool operator()( eoEsStdev<FitT>& _eo )
{
double global = TauGlb * rng.normal();
for (unsigned i = 0; i < _eo.size(); i++)
{
double stdev = _eo.stdevs[i];
stdev *= exp( global + TauLcl * rng.normal() );
if (stdev < stdev_eps)
stdev = stdev_eps;
_eo.stdevs[i] = stdev;
_eo[i] += stdev * rng.normal();
}
bounds.foldsInBounds(_eo);
return true;
}
/*
* 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 bool operator()( eoEsFull<FitT> & _eo )
{
/*
* First: mutate standard deviations (as above).
*/
double global = TauGlb * rng.normal();
unsigned i;
for (i = 0; i < _eo.size(); i++)
{
double stdev = _eo.stdevs[i];
stdev *= exp( global + TauLcl*rng.normal() );
if (stdev < stdev_eps)
stdev = stdev_eps;
_eo.stdevs[i] = stdev;
}
/* /** Standard mutation in ESs
* Mutate rotation angles.
*/
for (i = 0; i < _eo.correlations.size(); i++) Standard mutation of object variables and standard deviations in ESs.
{
_eo.correlations[i] += TauBeta * rng.normal();
if ( fabs(_eo.correlations[i]) > M_PI )
{
_eo.correlations[i] -= M_PI * (int) (_eo.correlations[i]/M_PI) ;
}
}
/* If there are fewer different standard deviations available than the
* Perform correlated mutations. dimension of the objective function requires, the last standard deviation is
*/ responsible for ALL remaining object variables.
unsigned k, n1, n2;
double d1,d2, S, C;
std::vector<double> VarStp(_eo.size()); @param _eo Individual to mutate.
for (i = 0; i < _eo.size(); i++)
VarStp[i] = _eo.stdevs[i] * rng.normal();
unsigned nq = _eo.correlations.size() - 1; @see Schwefel 1977: Numerische Optimierung von Computer-Modellen mittels der
Evolutionsstrategie, pp. 165 ff.
*/
virtual bool operator()( eoEsStdev<FitT>& _eo )
{
double global = TauGlb * rng.normal();
for (unsigned i = 0; i < _eo.size(); i++)
{
double stdev = _eo.stdevs[i];
stdev *= exp( global + TauLcl * rng.normal() );
if (stdev < stdev_eps)
stdev = stdev_eps;
_eo.stdevs[i] = stdev;
_eo[i] += stdev * rng.normal();
}
bounds.foldsInBounds(_eo);
return true;
}
for (k = 0; k < _eo.size()-1; k++)
{
n1 = _eo.size() - k - 1;
n2 = _eo.size() - 1;
for (i = 0; i < k; i++) /** Correlated mutations in ESs
{
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++) Correlated mutations in ESs, according to the following sources:
_eo[i] += VarStp[i]; - H.-P. Schwefel: Internal Report of KFA Juelich, KFA-STE-IB-3/80, p. 43, 1980
- G. Rudolph: Globale Optimierung mit parallelen Evolutionsstrategien,
Diploma Thesis, University of Dortmund, 1990
- Code from Thomas Baeck
*/
virtual bool operator()( eoEsFull<FitT> & _eo )
{
// First: mutate standard deviations (as above).
double global = TauGlb * rng.normal();
unsigned i;
for (i = 0; i < _eo.size(); i++)
{
double stdev = _eo.stdevs[i];
stdev *= exp( global + 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;
std::vector<double> 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];
bounds.foldsInBounds(_eo);
return true;
}
bounds.foldsInBounds(_eo);
return true;
}
private : private :
@ -236,34 +208,39 @@ public:
void init(eoEsStdev<FitT>, eoEsMutationInit& _init) void init(eoEsStdev<FitT>, eoEsMutationInit& _init)
{ {
unsigned size = bounds.size(); unsigned size = bounds.size();
TauLcl = _init.TauLcl(); TauLcl = _init.TauLcl();
TauGlb = _init.TauGlb(); TauGlb = _init.TauGlb();
// renormalization // renormalization
TauLcl /= sqrt( 2.0 * sqrt( (double)size ) ); TauLcl /= sqrt( 2.0 * sqrt(double(size)) );
TauGlb /= sqrt( 2.0 * ( (double) size ) ); TauGlb /= sqrt( 2.0 * double(size) );
std::cout << "Init<eoStDev>: tau local " << TauLcl << " et global " << TauGlb << std::endl; std::cout << "Init<eoStDev>: tau local " << TauLcl << " et global " << TauGlb << std::endl;
} }
void init(eoEsFull<FitT>, eoEsMutationInit& _init) void init(eoEsFull<FitT>, eoEsMutationInit& _init)
{ {
init(eoEsStdev<FitT>(), _init); init(eoEsStdev<FitT>(), _init);
TauBeta = _init.TauBeta(); TauBeta = _init.TauBeta();
std::cout << "Init<eoEsFull>: tau local " << TauLcl << " et global " << TauGlb << std::endl; std::cout << "Init<eoEsFull>: tau local " << TauLcl << " et global " << TauGlb << std::endl;
} }
// 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 */
eoRealVectorBounds& bounds; /** Local factor for mutation of std deviations */
double TauLcl;
static const double stdev_eps; /** Global factor for mutation of std deviations */
double TauGlb;
/** Factor for mutation of correlation parameters */
double TauBeta;
/** Bounds of parameters */
eoRealVectorBounds& bounds;
/** Minimum stdev */
static const double stdev_eps;
}; };
template <class EOT> template <class EOT>
const double eoEsMutate<EOT>::stdev_eps = 1.0e-40; const double eoEsMutate<EOT>::stdev_eps = 1.0e-40;