Well, what do you know, major commit.

Changed the signature of eoMon, eoBin and eoQuadOp to return a bool,
without invalidating fitness. Added a set of invalidators to take over
that job (see for instance eoSGA and eoSGATransform how this can transparantly used)

Derived eoState from eoFunctorStore (for convenience, from a design perspective this may sound wrong)

Added a wrap_op function that does the wrapping for you (see eoOpContainer how this made this functor
exceedingly less hairy). Checked all the tests removed the eoGeneric*Op family (not needed anymore)
and of course changed all the operators to reflect the change (and found a few that didn't
invalidate the fitness, thus really pointing out the advantage of the current approach)
This commit is contained in:
maartenkeijzer 2001-02-14 10:35:26 +00:00
commit 3a9b5a0e7e
30 changed files with 651 additions and 564 deletions

View file

@ -80,22 +80,22 @@ public:
/// needed virtual dtor
virtual ~eoEsMutate() {};
/** Inherited from eoObject
/** Inherited from eoObject
@see eoObject
*/
virtual string className() const {return "eoESMutate";};
/**
Mutate eoEsSimple
*/
virtual void operator()( eoEsSimple<FitT>& _eo)
virtual bool operator()( eoEsSimple<FitT>& _eo)
{
_eo.stdev *= exp(TauLcl * rng.normal());
_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)
@ -104,40 +104,40 @@ public:
}
bounds.foldsInBounds(_eo);
_eo.invalidate();
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
* 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<FitT>& _eo )
virtual bool operator()( eoEsStdev<FitT>& _eo )
{
double global = exp(TauGlb * rng.normal());
for (unsigned i = 0; i < _eo.size(); i++)
for (unsigned i = 0; i < _eo.size(); i++)
{
double stdev = _eo.stdevs[i];
stdev *= global * exp(TauLcl * rng.normal());
stdev *= global * exp(TauLcl * rng.normal());
if (stdev < stdev_eps)
stdev = stdev_eps;
_eo.stdevs[i] = stdev;
_eo.stdevs[i] = stdev;
_eo[i] += stdev * rng.normal();
}
bounds.foldsInBounds(_eo);
_eo.invalidate();
return true;
}
/*
@ -148,43 +148,43 @@ public:
* G. Rudolph: Globale Optimierung mit parallelen Evolutions-
* strategien, Diploma Thesis, University of Dortmund, 1990
*/
// Code from Thomas Baeck
virtual void operator()( eoEsFull<FitT> & _eo )
// Code from Thomas Baeck
virtual bool operator()( eoEsFull<FitT> & _eo )
{
/*
* First: mutate standard deviations (as above).
*/
double global = exp(TauGlb * rng.normal());
unsigned i;
for (i = 0; i < _eo.size(); i++)
for (i = 0; i < _eo.size(); i++)
{
double stdev = _eo.stdevs[i];
stdev *= global * exp(TauLcl * rng.normal());
stdev *= global * exp(TauLcl * rng.normal());
if (stdev < stdev_eps)
stdev = stdev_eps;
_eo.stdevs[i] = stdev;
_eo.stdevs[i] = stdev;
}
/*
* Mutate rotation angles.
*/
for (i = 0; i < _eo.correlations.size(); i++)
for (i = 0; i < _eo.correlations.size(); i++)
{
_eo.correlations[i] += TauBeta * rng.normal();
if ( fabs(_eo.correlations[i]) > M_PI )
_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.
*/
@ -192,17 +192,17 @@ public:
double d1,d2, S, C;
vector<double> VarStp(_eo.size());
for (i = 0; i < _eo.size(); i++)
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++)
for (k = 0; k < _eo.size()-1; k++)
{
n1 = _eo.size() - k - 1;
n2 = _eo.size() - 1;
for (i = 0; i < k; i++)
for (i = 0; i < k; i++)
{
d1 = VarStp[n1];
d2 = VarStp[n2];
@ -214,13 +214,13 @@ public:
nq--;
}
}
for (i = 0; i < _eo.size(); i++)
for (i = 0; i < _eo.size(); i++)
_eo[i] += VarStp[i];
bounds.foldsInBounds(_eo);
_eo.invalidate();
return true;
}
private :
@ -243,14 +243,14 @@ public:
TauLcl /= sqrt( 2.0 * sqrt( (double)size ) );
TauGlb /= sqrt( 2.0 * ( (double) size ) );
}
void init(eoEsFull<FitT>, eoEsMutationInit& _init)
{
init(eoEsStdev<FitT>(), _init);
TauBeta = _init.TauBeta();
}
// the data
// the data
//=========
double TauLcl; /* Local factor for mutation of std deviations */
double TauGlb; /* Global factor for mutation of std deviations */

View file

@ -33,10 +33,10 @@
/**
\ingroup EvolutionStrategies
Crossover for Evolutionary strategie style representation,
supporting co-evolving standard deviations.
Crossover for Evolutionary strategie style representation,
supporting co-evolving standard deviations.
Simply calls a crossover for the object variables,
Simply calls a crossover for the object variables,
and a crossover for teh StdDev
*/
@ -44,26 +44,30 @@ template <class EOT>
class eoEsStdevXOver : public eoQuadOp<EOT>
{
public :
eoEsStdevXOver(eoGenericQuadOp<vector<double> > & _objectXOver,
eoGenericQuadOp<vector<double> > & _stdDevXOver) :
eoEsStdevXOver(eoQuadOp<vector<double> > & _objectXOver,
eoQuadOp<vector<double> > & _stdDevXOver) :
objectXOver(_objectXOver), stdDevXOver(_stdDevXOver) {}
std::string className(void) const { return "eoEsStdevXOver"; }
void operator()(EOT & _eo1, EOT & _eo2)
bool operator()(EOT & _eo1, EOT & _eo2)
{
bool objectChanged = objectXOver(_eo1, _eo2); // as vector<double>
bool stdDevChanged = stdDevXOver(_eo1.stdevs, _eo2.stdevs);
/// Marc, I didn't change it, but if only the stdev has changed,
/// doesn't that mean that the fitness is stil valid. Maarten
if ( objectChanged || stdDevChanged )
{
_eo1.invalidate();
_eo2.invalidate();
return true;
}
return false;
}
private:
eoGenericQuadOp<vector<double> > & objectXOver;
eoGenericQuadOp<vector<double> > & stdDevXOver;
eoQuadOp<vector<double> > & objectXOver;
eoQuadOp<vector<double> > & stdDevXOver;
};
/* A question: it seems it really makes no difference to have

View file

@ -31,27 +31,26 @@
in eoRealOp.h.
So they can be used when part of the genotype is a vector<double> ...
In the long run, they should replace completely the operators from eoRealOp
when all constructs using eoOp will be able to use the corresponding
when all constructs using eoOp will be able to use the corresponding
eoGenericOp - as it is already done in eoProportinoalCombinedOp
MS January 25. 2001
*/
#include <algorithm> // swap_ranges
#include <utils/eoRNG.h>
#include <eoGenericMonOp.h>
#include <eoGenericQuadOp.h>
#include <eoOp.h>
#include <es/eoRealBounds.h>
//-----------------------------------------------------------------------------
/** eoUniformMutation --> changes all values of the vector
by uniform choice with range epsilon
/** eoUniformMutation --> changes all values of the vector
by uniform choice with range epsilon
with probability p_change per variable
\class eoUniformMutation eoRealOp.h Tutorial/eoRealOp.h
\ingroup parameteric
*/
template<class EOT> class eoGenericUniformMutation: public eoGenericMonOp<EOT>
template<class EOT> class eoGenericUniformMutation: public eoMonOp<EOT>
{
public:
/**
@ -61,8 +60,8 @@ template<class EOT> class eoGenericUniformMutation: public eoGenericMonOp<EOT>
* @param _epsilon the range for uniform nutation
* @param _p_change the probability to change a given coordinate
*/
eoGenericUniformMutation(const double& _epsilon,
const double& _p_change = 1.0):
eoGenericUniformMutation(const double& _epsilon,
const double& _p_change = 1.0):
bounds(eoDummyVectorNoBounds), epsilon(_epsilon), p_change(_p_change) {}
/**
@ -71,23 +70,23 @@ template<class EOT> class eoGenericUniformMutation: public eoGenericMonOp<EOT>
* @param _epsilon the range for uniform nutation
* @param _p_change the probability to change a given coordinate
*/
eoGenericUniformMutation(eoRealVectorBounds & _bounds,
const double& _epsilon, const double& _p_change = 1.0):
eoGenericUniformMutation(eoRealVectorBounds & _bounds,
const double& _epsilon, const double& _p_change = 1.0):
bounds(_bounds), epsilon(_epsilon), p_change(_p_change) {}
/// The class name.
string className() const { return "eoGenericUniformMutation"; }
/**
* Do it!
* @param _eo The cromosome undergoing the mutation
*/
bool operator()(EOT& _eo)
bool operator()(EOT& _eo)
{
bool hasChanged=false;
for (unsigned lieu=0; lieu<_eo.size(); lieu++)
for (unsigned lieu=0; lieu<_eo.size(); lieu++)
{
if (rng.flip(p_change))
if (rng.flip(p_change))
{
// check the bounds
double emin = _eo[lieu]-epsilon;
@ -104,21 +103,21 @@ template<class EOT> class eoGenericUniformMutation: public eoGenericMonOp<EOT>
return true;
return false;
}
private:
eoRealVectorBounds & bounds;
double epsilon;
double p_change;
};
/** eoDetUniformMutation --> changes exactly k values of the vector
by uniform choice with range epsilon
/** eoDetUniformMutation --> changes exactly k values of the vector
by uniform choice with range epsilon
\class eoDetUniformMutation eoRealOp.h Tutorial/eoRealOp.h
\ingroup parameteric
*/
template<class EOT> class eoGenericDetUniformMutation:
public eoGenericMonOp<EOT>
template<class EOT> class eoGenericDetUniformMutation:
public eoMonOp<EOT>
{
public:
/**
@ -126,8 +125,8 @@ template<class EOT> class eoGenericDetUniformMutation:
* @param _epsilon the range for uniform nutation
* @param number of coordinate to modify
*/
eoGenericDetUniformMutation(const double& _epsilon,
const unsigned& _no = 1):
eoGenericDetUniformMutation(const double& _epsilon,
const unsigned& _no = 1):
bounds(eoDummyVectorNoBounds), epsilon(_epsilon), no(_no) {}
/**
@ -136,18 +135,18 @@ template<class EOT> class eoGenericDetUniformMutation:
* @param _epsilon the range for uniform nutation
* @param number of coordinate to modify
*/
eoGenericDetUniformMutation(eoRealVectorBounds & _bounds,
const double& _epsilon, const unsigned& _no = 1):
eoGenericDetUniformMutation(eoRealVectorBounds & _bounds,
const double& _epsilon, const unsigned& _no = 1):
bounds(_bounds), epsilon(_epsilon), no(_no) {}
/// The class name.
string className() const { return "eoGenericDetUniformMutation"; }
/**
* Do it!
* @param _eo The cromosome undergoing the mutation
*/
bool operator()(EOT& _eo)
bool operator()(EOT& _eo)
{
for (unsigned i=0; i<no; i++)
{
@ -175,37 +174,37 @@ private:
// two arithmetical crossovers
/** eoSegmentCrossover --> uniform choice in segment
/** eoSegmentCrossover --> uniform choice in segment
== arithmetical with same value along all coordinates
\class eoSegmentCrossover eoRealOp.h Tutorial/eoRealOp.h
\ingroup parameteric
*/
template<class EOT> class eoGenericSegmentCrossover: public eoGenericQuadOp<EOT>
template<class EOT> class eoGenericSegmentCrossover: public eoQuadOp<EOT>
{
public:
/**
* (Default) Constructor.
* The bounds are initialized with the global object that says: no bounds.
*
* @param _alphaMin the amount of exploration OUTSIDE the parents
* @param _alphaMin the amount of exploration OUTSIDE the parents
* as in BLX-alpha notation (Eshelman and Schaffer)
* 0 == contractive application
* Must be positive
*/
eoGenericSegmentCrossover(const double& _alpha = 0.0) :
eoGenericSegmentCrossover(const double& _alpha = 0.0) :
bounds(eoDummyVectorNoBounds), alpha(_alpha), range(1+2*_alpha) {}
/**
* Constructor with bounds
* @param _bounds an eoRealVectorBounds that contains the bounds
* @param _alphaMin the amount of exploration OUTSIDE the parents
* @param _alphaMin the amount of exploration OUTSIDE the parents
* as in BLX-alpha notation (Eshelman and Schaffer)
* 0 == contractive application
* Must be positive
*/
eoGenericSegmentCrossover(eoRealVectorBounds & _bounds,
const double& _alpha = 0.0) :
eoGenericSegmentCrossover(eoRealVectorBounds & _bounds,
const double& _alpha = 0.0) :
bounds(_bounds), alpha(_alpha), range(1+2*_alpha) {}
/// The class name.
@ -216,12 +215,12 @@ template<class EOT> class eoGenericSegmentCrossover: public eoGenericQuadOp<EOT>
* @param _eo1 The first parent
* @param _eo2 The first parent
*/
bool operator()(EOT& _eo1, EOT& _eo2)
bool operator()(EOT& _eo1, EOT& _eo2)
{
unsigned i;
double r1, r2, fact;
double alphaMin = -alpha;
double alphaMax = 1+alpha;
double alphaMax = 1+alpha;
if ( (alpha == 0.0) || bounds.hasNoBoundAtAll() ) // no check to perform
fact = -alpha + rng.uniform(range); // in [-alpha,1+alpha)
else // look for the bounds for fact
@ -238,7 +237,7 @@ template<class EOT> class eoGenericSegmentCrossover: public eoGenericQuadOp<EOT>
{
alphaMin = max(alphaMin, (bounds.minimum(i)-rmin)/length);
alphaMin = max(alphaMin, (rmax-bounds.maximum(i))/length);
}
}
if (bounds.isMaxBounded(i))
{
alphaMax = min(alphaMax, (bounds.maximum(i)-rmin)/length);
@ -264,28 +263,28 @@ protected:
double alpha;
double range; // == 1+2*alpha
};
/** eoArithmeticCrossover --> uniform choice in hypercube
/** eoArithmeticCrossover --> uniform choice in hypercube
== arithmetical with different values for each coordinate
\class eoArithmeticCrossover eoRealOp.h Tutorial/eoRealOp.h
\ingroup parameteric
*/
template<class EOT> class eoGenericArithmeticCrossover:
public eoGenericQuadOp<EOT>
template<class EOT> class eoGenericArithmeticCrossover:
public eoQuadOp<EOT>
{
public:
/**
* (Default) Constructor.
* The bounds are initialized with the global object that says: no bounds.
*
* @param _alphaMin the amount of exploration OUTSIDE the parents
* @param _alphaMin the amount of exploration OUTSIDE the parents
* as in BLX-alpha notation (Eshelman and Schaffer)
* 0 == contractive application
* Must be positive
*/
eoGenericArithmeticCrossover(const double& _alpha = 0.0):
bounds(eoDummyVectorNoBounds), alpha(_alpha), range(1+2*_alpha)
eoGenericArithmeticCrossover(const double& _alpha = 0.0):
bounds(eoDummyVectorNoBounds), alpha(_alpha), range(1+2*_alpha)
{
if (_alpha < 0)
throw runtime_error("BLX coefficient should be positive");
@ -294,14 +293,14 @@ template<class EOT> class eoGenericArithmeticCrossover:
/**
* Constructor with bounds
* @param _bounds an eoRealVectorBounds that contains the bounds
* @param _alphaMin the amount of exploration OUTSIDE the parents
* @param _alphaMin the amount of exploration OUTSIDE the parents
* as in BLX-alpha notation (Eshelman and Schaffer)
* 0 == contractive application
* Must be positive
*/
eoGenericArithmeticCrossover(eoRealVectorBounds & _bounds,
const double& _alpha = 0.0):
bounds(_bounds), alpha(_alpha), range(1+2*_alpha)
eoGenericArithmeticCrossover(eoRealVectorBounds & _bounds,
const double& _alpha = 0.0):
bounds(_bounds), alpha(_alpha), range(1+2*_alpha)
{
if (_alpha < 0)
throw runtime_error("BLX coefficient should be positive");
@ -315,7 +314,7 @@ template<class EOT> class eoGenericArithmeticCrossover:
* @param _eo1 The first parent
* @param _eo2 The first parent
*/
bool operator()(EOT& _eo1, EOT& _eo2)
bool operator()(EOT& _eo1, EOT& _eo2)
{
unsigned i;
double r1, r2, fact;
@ -344,7 +343,7 @@ template<class EOT> class eoGenericArithmeticCrossover:
{
alphaMin = max(alphaMin, (bounds.minimum(i)-rmin)/length);
alphaMin = max(alphaMin, (rmax-bounds.maximum(i))/length);
}
}
if (bounds.isMaxBounded(i))
{
alphaMax = min(alphaMax, (bounds.maximum(i)-rmin)/length);
@ -363,14 +362,14 @@ protected:
double alpha;
double range; // == 1+2*alphaMin
};
/** eoRealUxOver --> Uniform crossover, also termed intermediate crossover
\class eoRealUxOver eoRealOp.h Tutorial/eoRealOp.h
\ingroup parameteric
*/
template<class EOT> class eoGenericRealUxOver: public eoGenericQuadOp<EOT>
template<class EOT> class eoGenericRealUxOver: public eoQuadOp<EOT>
{
public:
/**
@ -378,7 +377,7 @@ template<class EOT> class eoGenericRealUxOver: public eoGenericQuadOp<EOT>
* @param _preference bias in the choice (usually, no bias == 0.5)
*/
eoGenericRealUxOver(double _preference = 0.5): preference(_preference)
{
{
if ( (_preference <= 0.0) || (_preference >= 1.0) )
runtime_error("UxOver --> invalid preference");
}
@ -392,10 +391,10 @@ template<class EOT> class eoGenericRealUxOver: public eoGenericQuadOp<EOT>
* @param _eo2 The second parent
* @runtime_error if sizes don't match
*/
bool operator()(EOT& _eo1, EOT& _eo2)
bool operator()(EOT& _eo1, EOT& _eo2)
{
if ( _eo1.size() != _eo2.size())
runtime_error("eoRealUxOver --> chromosomes sizes don't match" );
if ( _eo1.size() != _eo2.size())
runtime_error("eoRealUxOver --> chromosomes sizes don't match" );
bool changed = false;
for (unsigned int i=0; i<_eo1.size(); i++)
{
@ -415,7 +414,7 @@ template<class EOT> class eoGenericRealUxOver: public eoGenericQuadOp<EOT>
private:
double preference;
};
//-----------------------------------------------------------------------------
//@}

View file

@ -41,7 +41,7 @@
* to enable dynamic mutations (see eoOenFithMutation below).
*
* As for the bounds, the values are here folded back into the bounds.
* The other possiblity would be to iterate until we fall inside the bounds -
* The other possiblity would be to iterate until we fall inside the bounds -
* but this sometimes takes a long time!!!
*/
@ -55,7 +55,7 @@ template<class EOT> class eoNormalMutation: public eoMonOp<EOT>
* @param _sigma the range for uniform nutation
* @param _p_change the probability to change a given coordinate
*/
eoNormalMutation(double & _sigma, const double& _p_change = 1.0):
eoNormalMutation(double & _sigma, const double& _p_change = 1.0):
sigma(_sigma), bounds(eoDummyVectorNoBounds), p_change(_p_change) {}
/**
@ -64,33 +64,32 @@ template<class EOT> class eoNormalMutation: public eoMonOp<EOT>
* @param _sigma the range for uniform nutation
* @param _p_change the probability to change a given coordinate
*/
eoNormalMutation(eoRealVectorBounds & _bounds,
double & _sigma, const double& _p_change = 1.0):
eoNormalMutation(eoRealVectorBounds & _bounds,
double & _sigma, const double& _p_change = 1.0):
sigma(_sigma), bounds(_bounds), p_change(_p_change) {}
/// The class name.
string className() const { return "eoNormalMutation"; }
/**
* Do it!
* @param _eo The cromosome undergoing the mutation
*/
void operator()(EOT& _eo)
bool operator()(EOT& _eo)
{
bool hasChanged=false;
for (unsigned lieu=0; lieu<_eo.size(); lieu++)
for (unsigned lieu=0; lieu<_eo.size(); lieu++)
{
if (rng.flip(p_change))
if (rng.flip(p_change))
{
_eo[lieu] += sigma*rng.normal();
bounds.foldsInBounds(lieu, _eo[lieu]);
hasChanged = true;
}
}
if (hasChanged)
_eo.invalidate();
return hasChanged;
}
protected:
double & sigma;
private:
@ -98,9 +97,9 @@ private:
double p_change;
};
/** the dynamic version: just say it is updatable -
/** the dynamic version: just say it is updatable -
* and write the update() method!
* here the 1 fifth rule: count the proportion of successful mutations, and
* here the 1 fifth rule: count the proportion of successful mutations, and
* increase sigma if more than threshold (1/5 !)
*/

View file

@ -35,8 +35,8 @@
//-----------------------------------------------------------------------------
/** eoUniformMutation --> changes all values of the vector
by uniform choice with range epsilon
/** eoUniformMutation --> changes all values of the vector
by uniform choice with range epsilon
with probability p_change per variable
\class eoUniformMutation eoRealOp.h Tutorial/eoRealOp.h
\ingroup parameteric
@ -52,7 +52,7 @@ template<class EOT> class eoUniformMutation: public eoMonOp<EOT>
* @param _epsilon the range for uniform nutation
* @param _p_change the probability to change a given coordinate
*/
eoUniformMutation(const double& _epsilon, const double& _p_change = 1.0):
eoUniformMutation(const double& _epsilon, const double& _p_change = 1.0):
bounds(eoDummyVectorNoBounds), epsilon(_epsilon), p_change(_p_change) {}
/**
@ -61,23 +61,23 @@ template<class EOT> class eoUniformMutation: public eoMonOp<EOT>
* @param _epsilon the range for uniform nutation
* @param _p_change the probability to change a given coordinate
*/
eoUniformMutation(eoRealVectorBounds & _bounds,
const double& _epsilon, const double& _p_change = 1.0):
eoUniformMutation(eoRealVectorBounds & _bounds,
const double& _epsilon, const double& _p_change = 1.0):
bounds(_bounds), epsilon(_epsilon), p_change(_p_change) {}
/// The class name.
string className() const { return "eoUniformMutation"; }
/**
* Do it!
* @param _eo The cromosome undergoing the mutation
*/
void operator()(EOT& _eo)
bool operator()(EOT& _eo)
{
bool hasChanged=false;
for (unsigned lieu=0; lieu<_eo.size(); lieu++)
for (unsigned lieu=0; lieu<_eo.size(); lieu++)
{
if (rng.flip(p_change))
if (rng.flip(p_change))
{
// check the bounds
double emin = _eo[lieu]-epsilon;
@ -90,18 +90,17 @@ template<class EOT> class eoUniformMutation: public eoMonOp<EOT>
hasChanged = true;
}
}
if (hasChanged)
_eo.invalidate();
return hasChanged;
}
private:
eoRealVectorBounds & bounds;
double epsilon;
double p_change;
};
/** eoDetUniformMutation --> changes exactly k values of the vector
by uniform choice with range epsilon
/** eoDetUniformMutation --> changes exactly k values of the vector
by uniform choice with range epsilon
\class eoDetUniformMutation eoRealOp.h Tutorial/eoRealOp.h
\ingroup parameteric
*/
@ -114,7 +113,7 @@ template<class EOT> class eoDetUniformMutation: public eoMonOp<EOT>
* @param _epsilon the range for uniform nutation
* @param number of coordinate to modify
*/
eoDetUniformMutation(const double& _epsilon, const unsigned& _no = 1):
eoDetUniformMutation(const double& _epsilon, const unsigned& _no = 1):
bounds(eoDummyVectorNoBounds), epsilon(_epsilon), no(_no) {}
/**
@ -134,12 +133,11 @@ template<class EOT> class eoDetUniformMutation: public eoMonOp<EOT>
* Do it!
* @param _eo The cromosome undergoing the mutation
*/
void operator()(EOT& _eo)
bool operator()(EOT& _eo)
{
_eo.invalidate();
for (unsigned i=0; i<no; i++)
{
unsigned lieu = rng.random(_eo.size());
{
unsigned lieu = rng.random(_eo.size());
// actually, we should test that we don't re-modify same variable!
// check the bounds
@ -150,7 +148,9 @@ template<class EOT> class eoDetUniformMutation: public eoMonOp<EOT>
if (bounds.isMaxBounded(lieu))
emax = min(bounds.maximum(lieu), emax);
_eo[lieu] = emin + (emax-emin)*rng.uniform();
}
}
return true;
}
private:
@ -162,7 +162,7 @@ private:
// two arithmetical crossovers
/** eoSegmentCrossover --> uniform choice in segment
/** eoSegmentCrossover --> uniform choice in segment
== arithmetical with same value along all coordinates
\class eoSegmentCrossover eoRealOp.h Tutorial/eoRealOp.h
\ingroup parameteric
@ -175,12 +175,12 @@ template<class EOT> class eoSegmentCrossover: public eoQuadOp<EOT>
* (Default) Constructor.
* The bounds are initialized with the global object that says: no bounds.
*
* @param _alphaMin the amount of exploration OUTSIDE the parents
* @param _alphaMin the amount of exploration OUTSIDE the parents
* as in BLX-alpha notation (Eshelman and Schaffer)
* 0 == contractive application
* Must be positive
*/
eoSegmentCrossover(const double& _alpha = 0.0) :
eoSegmentCrossover(const double& _alpha = 0.0) :
bounds(eoDummyVectorNoBounds), alpha(_alpha), range(1+2*_alpha) {}
/**
@ -203,12 +203,12 @@ template<class EOT> class eoSegmentCrossover: public eoQuadOp<EOT>
* @param _eo1 The first parent
* @param _eo2 The first parent
*/
void operator()(EOT& _eo1, EOT& _eo2)
bool operator()(EOT& _eo1, EOT& _eo2)
{
unsigned i;
double r1, r2, fact;
double alphaMin = -alpha;
double alphaMax = 1+alpha;
double alphaMax = 1+alpha;
if (alpha == 0.0) // no check to perform
fact = -alpha + rng.uniform(range); // in [-alpha,1+alpha)
else // look for the bounds for fact
@ -225,7 +225,7 @@ template<class EOT> class eoSegmentCrossover: public eoQuadOp<EOT>
{
alphaMin = max(alphaMin, (bounds.minimum(i)-rmin)/length);
alphaMin = max(alphaMin, (rmax-bounds.maximum(i))/length);
}
}
if (bounds.isMaxBounded(i))
{
alphaMax = min(alphaMax, (bounds.maximum(i)-rmin)/length);
@ -243,8 +243,7 @@ template<class EOT> class eoSegmentCrossover: public eoQuadOp<EOT>
_eo1[i] = fact * r1 + (1-fact) * r2;
_eo2[i] = (1-fact) * r1 + fact * r2;
}
_eo1.invalidate(); // shoudl test if fact was 0 or 1 :-)))
_eo2.invalidate();
return true; // shoudl test if fact was 0 or 1 :-)))
}
protected:
@ -252,8 +251,8 @@ protected:
double alpha;
double range; // == 1+2*alpha
};
/** eoArithmeticCrossover --> uniform choice in hypercube
/** eoArithmeticCrossover --> uniform choice in hypercube
== arithmetical with different values for each coordinate
\class eoArithmeticCrossover eoRealOp.h Tutorial/eoRealOp.h
\ingroup parameteric
@ -266,13 +265,13 @@ template<class EOT> class eoArithmeticCrossover: public eoQuadOp<EOT>
* (Default) Constructor.
* The bounds are initialized with the global object that says: no bounds.
*
* @param _alphaMin the amount of exploration OUTSIDE the parents
* @param _alphaMin the amount of exploration OUTSIDE the parents
* as in BLX-alpha notation (Eshelman and Schaffer)
* 0 == contractive application
* Must be positive
*/
eoArithmeticCrossover(const double& _alpha = 0.0):
bounds(eoDummyVectorNoBounds), alpha(_alpha), range(1+2*_alpha)
eoArithmeticCrossover(const double& _alpha = 0.0):
bounds(eoDummyVectorNoBounds), alpha(_alpha), range(1+2*_alpha)
{
if (_alpha < 0)
throw runtime_error("BLX coefficient should be positive");
@ -302,7 +301,7 @@ template<class EOT> class eoArithmeticCrossover: public eoQuadOp<EOT>
* @param _eo1 The first parent
* @param _eo2 The first parent
*/
void operator()(EOT& _eo1, EOT& _eo2)
bool operator()(EOT& _eo1, EOT& _eo2)
{
unsigned i;
double r1, r2, fact;
@ -331,7 +330,7 @@ template<class EOT> class eoArithmeticCrossover: public eoQuadOp<EOT>
{
alphaMin = max(alphaMin, (bounds.minimum(i)-rmin)/length);
alphaMin = max(alphaMin, (rmax-bounds.maximum(i))/length);
}
}
if (bounds.isMaxBounded(i))
{
alphaMax = min(alphaMax, (bounds.maximum(i)-rmin)/length);
@ -342,16 +341,16 @@ template<class EOT> class eoArithmeticCrossover: public eoQuadOp<EOT>
_eo2[i] = (1-fact) * rmin + fact * rmax;
}
}
_eo1.invalidate();
_eo2.invalidate();
}
return true;
}
protected:
eoRealVectorBounds & bounds;
double alpha;
double range; // == 1+2*alphaMin
};
/** eoRealUxOver --> Uniform crossover, also termed intermediate crossover
\class eoRealUxOver eoRealOp.h Tutorial/eoRealOp.h
@ -380,10 +379,10 @@ template<class EOT> class eoRealUxOver: public eoQuadOp<EOT>
* @param _eo2 The second parent
* @runtime_error if sizes don't match
*/
void operator()(EOT& _eo1, EOT& _eo2)
bool operator()(EOT& _eo1, EOT& _eo2)
{
if ( _eo1.size() != _eo2.size())
runtime_error("UxOver --> chromosomes sizes don't match" );
if ( _eo1.size() != _eo2.size())
runtime_error("UxOver --> chromosomes sizes don't match" );
bool changed = false;
for (unsigned int i=0; i<_eo1.size(); i++)
{
@ -396,11 +395,7 @@ template<class EOT> class eoRealUxOver: public eoQuadOp<EOT>
changed = true;
}
}
if (changed)
{
_eo1.invalidate();
_eo2.invalidate();
}
return changed;
}
private:
float preference;