Added the crossover in make_op_es (parameters were read, but that's all!
This commit is contained in:
parent
d9ddfeeaea
commit
8b177dd6cd
6 changed files with 91 additions and 56 deletions
|
|
@ -16,4 +16,4 @@ libes_a_SOURCES = make_algo_scalar_real.cpp make_checkpoint_real.cpp \
|
|||
CPPFLAGS = -Wall
|
||||
CXXFLAGS =
|
||||
libeoincdir = $(includedir)/eo/es
|
||||
libeoinc_HEADERS = eoEsChromInit.h eoEsFull.h eoEsMutate.h eoEsMutationInit.h eoEsSimple.h eoEsStdev.h eoEsStdevXOver.h eoGenericRealOp.h eoNormalMutation.h eoReal.h eoRealOp.h eoEsGlobalXover.h eoEsLocalXover.h eoRealAtomXover.h
|
||||
libeoinc_HEADERS = eoEsChromInit.h eoEsFull.h eoEsMutate.h eoEsMutationInit.h eoEsSimple.h eoEsStdev.h eoNormalMutation.h eoReal.h eoRealOp.h eoEsGlobalXover.h eoEsStandardXover.h eoRealAtomXover.h
|
||||
|
|
|
|||
|
|
@ -63,45 +63,51 @@ public:
|
|||
*/
|
||||
bool operator()(EOT& _eo1, const EOT& _eo2)
|
||||
{
|
||||
bool bLoc=false;
|
||||
// first, the object variables
|
||||
for (unsigned i=0; i<_eo1.size(); i++)
|
||||
{
|
||||
crossObj(_eo1[i], _eo2[i]); // apply eoBinOp
|
||||
bLoc |= crossObj(_eo1[i], _eo2[i]); // apply eoBinOp
|
||||
}
|
||||
// then the self-adaptation parameters
|
||||
cross_self_adapt(_eo1, _eo2);
|
||||
bLoc |= cross_self_adapt(_eo1, _eo2);
|
||||
return bLoc;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
// the method to cross slef-adaptation parameters: need to specialize
|
||||
|
||||
void cross_self_adapt(eoEsSimple<FitT> & _parent1, const eoEsSimple<FitT> & _parent2)
|
||||
bool cross_self_adapt(eoEsSimple<FitT> & _parent1, const eoEsSimple<FitT> & _parent2)
|
||||
{
|
||||
crossMut(_parent1.stdev, _parent2.stdev); // apply eoBinOp
|
||||
return crossMut(_parent1.stdev, _parent2.stdev); // apply eoBinOp
|
||||
}
|
||||
|
||||
void cross_self_adapt(eoEsStdev<FitT> & _parent1, const eoEsStdev<FitT> & _parent2)
|
||||
bool cross_self_adapt(eoEsStdev<FitT> & _parent1, const eoEsStdev<FitT> & _parent2)
|
||||
{
|
||||
bool bLoc=false;
|
||||
for (unsigned i=0; i<_parent1.size(); i++)
|
||||
{
|
||||
crossMut(_parent1.stdevs[i], _parent2.stdevs[i]); // apply eoBinOp
|
||||
bLoc |= crossMut(_parent1.stdevs[i], _parent2.stdevs[i]); // apply eoBinOp
|
||||
}
|
||||
return bLoc;
|
||||
}
|
||||
|
||||
void cross_self_adapt(eoEsFull<FitT> & _parent1, const eoEsFull<FitT> & _parent2)
|
||||
bool cross_self_adapt(eoEsFull<FitT> & _parent1, const eoEsFull<FitT> & _parent2)
|
||||
{
|
||||
bool bLoc=false;
|
||||
unsigned i;
|
||||
// the StDev
|
||||
for (i=0; i<_parent1.size(); i++)
|
||||
{
|
||||
crossMut(_parent1.stdevs[i], _parent2.stdevs[i]); // apply eoBinOp
|
||||
bLoc |= crossMut(_parent1.stdevs[i], _parent2.stdevs[i]); // apply eoBinOp
|
||||
}
|
||||
// the roataion angles
|
||||
for (i=0; i<_parent1.correlations.size(); i++)
|
||||
{
|
||||
crossMut(_parent1.correlations[i], _parent2.correlations[i]); // apply eoBinOp
|
||||
bLoc |= crossMut(_parent1.correlations[i], _parent2.correlations[i]); // apply eoBinOp
|
||||
}
|
||||
return bLoc;
|
||||
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -38,16 +38,16 @@
|
|||
/**
|
||||
Discrete crossover == exchange of values
|
||||
*/
|
||||
class eoRealAtomExchange: public eoBinOp<double>
|
||||
class eoDoubleExchange: public eoBinOp<double>
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* (Default) Constructor.
|
||||
*/
|
||||
eoRealAtomExchange() {}
|
||||
eoDoubleExchange() {}
|
||||
|
||||
/// The class name. Used to display statistics
|
||||
virtual string className() const { return "eoRealAtomExchange"; }
|
||||
virtual string className() const { return "eoDoubleExchange"; }
|
||||
|
||||
/**
|
||||
Exchanges or not the values
|
||||
|
|
@ -68,16 +68,16 @@ public:
|
|||
/**
|
||||
Intermediate crossover == linear combination
|
||||
*/
|
||||
class eoRealIntermediate: public eoBinOp<double>
|
||||
class eoDoubleIntermediate: public eoBinOp<double>
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* (Default) Constructor.
|
||||
*/
|
||||
eoRealIntermediate() {}
|
||||
eoDoubleIntermediate() {}
|
||||
|
||||
/// The class name. Used to display statistics
|
||||
virtual string className() const { return "eoRealIntermediate"; }
|
||||
virtual string className() const { return "eoDoubleIntermediate"; }
|
||||
|
||||
/**
|
||||
Linear combination of both parents
|
||||
|
|
|
|||
|
|
@ -301,12 +301,12 @@ template<class EOT> class eoSegmentCrossover: public eoQuadOp<EOT>
|
|||
if (bounds.isMinBounded(i))
|
||||
{
|
||||
alphaMin = max(alphaMin, (bounds.minimum(i)-rmin)/length);
|
||||
alphaMin = max(alphaMin, (rmax-bounds.maximum(i))/length);
|
||||
alphaMax = min(alphaMax, (rmax-bounds.minimum(i))/length);
|
||||
}
|
||||
if (bounds.isMaxBounded(i))
|
||||
{
|
||||
alphaMax = min(alphaMax, (bounds.maximum(i)-rmin)/length);
|
||||
alphaMax = min(alphaMax, (rmax-bounds.minimum(i))/length);
|
||||
alphaMin = max(alphaMin, (rmax-bounds.maximum(i))/length);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -380,46 +380,67 @@ template<class EOT> class eoHypercubeCrossover: public eoQuadOp<EOT>
|
|||
*/
|
||||
bool operator()(EOT& _eo1, EOT& _eo2)
|
||||
{
|
||||
bool hasChanged = false;
|
||||
unsigned i;
|
||||
double r1, r2, fact;
|
||||
if (alpha == 0.0) // no check to perform
|
||||
for (i=0; i<_eo1.size(); i++)
|
||||
{
|
||||
r1=_eo1[i];
|
||||
r2=_eo2[i];
|
||||
fact = -alpha + rng.uniform(range); // in [-alpha,1+alpha)
|
||||
_eo1[i] = fact * r1 + (1-fact) * r2;
|
||||
_eo2[i] = (1-fact) * r1 + fact * r2;
|
||||
}
|
||||
else // check the bounds
|
||||
{
|
||||
r1=_eo1[i];
|
||||
r2=_eo2[i];
|
||||
if (r1 != r2) { // otherwise do nothing
|
||||
fact = rng.uniform(range); // in [0,1)
|
||||
_eo1[i] = fact * r1 + (1-fact) * r2;
|
||||
_eo2[i] = (1-fact) * r1 + fact * r2;
|
||||
hasChanged = true; // forget (im)possible alpha=0
|
||||
}
|
||||
}
|
||||
else // check the bounds
|
||||
// do not try to get a bound on the linear factor, but rather
|
||||
// on the object variables themselves
|
||||
for (i=0; i<_eo1.size(); i++)
|
||||
{
|
||||
r1=_eo1[i];
|
||||
r2=_eo2[i];
|
||||
if (r1 != r2) { // otherwise you'll get NAN's
|
||||
if (r1 != r2) { // otherwise do nothing
|
||||
double rmin = min(r1, r2);
|
||||
double rmax = max(r1, r2);
|
||||
double length = rmax - rmin;
|
||||
double alphaMin = -alpha;
|
||||
double alphaMax = 1+alpha;
|
||||
|
||||
// compute min and max for object variables
|
||||
double objMin = -alpha * rmax + (1+alpha) * rmin;
|
||||
double objMax = -alpha * rmin + (1+alpha) * rmax;
|
||||
|
||||
// first find the limits on the alpha's
|
||||
if (bounds.isMinBounded(i))
|
||||
{
|
||||
alphaMin = max(alphaMin, (bounds.minimum(i)-rmin)/length);
|
||||
alphaMin = max(alphaMin, (rmax-bounds.maximum(i))/length);
|
||||
objMin = max(objMin, bounds.minimum(i));
|
||||
}
|
||||
if (bounds.isMaxBounded(i))
|
||||
{
|
||||
alphaMax = min(alphaMax, (bounds.maximum(i)-rmin)/length);
|
||||
alphaMax = min(alphaMax, (rmax-bounds.minimum(i))/length);
|
||||
objMax = min(objMax, bounds.maximum(i));
|
||||
}
|
||||
fact = alphaMin + rng.uniform(alphaMax-alphaMin);
|
||||
_eo1[i] = fact * rmin + (1-fact) * rmax;
|
||||
_eo2[i] = (1-fact) * rmin + fact * rmax;
|
||||
// then draw variables
|
||||
double median = (objMin+objMax)/2.0; // uniform within bounds
|
||||
// double median = (rmin+rmax)/2.0; // Bounce on bounds
|
||||
double valMin = objMin + (median-objMin)*rng.uniform();
|
||||
double valMax = median + (objMax-median)*rng.uniform();
|
||||
// don't always put large value in _eo1 - or what?
|
||||
if (rng.flip(0.5))
|
||||
{
|
||||
_eo1[i] = valMin;
|
||||
_eo2[i] = valMax;
|
||||
}
|
||||
else
|
||||
{
|
||||
_eo1[i] = valMax;
|
||||
_eo2[i] = valMin;
|
||||
}
|
||||
// seomthing has changed
|
||||
hasChanged = true; // forget (im)possible alpha=0
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
return hasChanged;
|
||||
}
|
||||
|
||||
protected:
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@
|
|||
#include <es/eoEsMutationInit.h>
|
||||
#include <es/eoEsMutate.h>
|
||||
#include <es/eoEsGlobalXover.h>
|
||||
#include <es/eoEsLocalXover.h>
|
||||
#include <es/eoEsStandardXover.h>
|
||||
// also need the parser and param includes
|
||||
#include <utils/eoParser.h>
|
||||
#include <utils/eoState.h>
|
||||
|
|
@ -108,27 +108,32 @@ eoGenOp<EOT> & do_make_op(eoParameterLoader& _parser, eoState& _state, eoRealIni
|
|||
// The pointers: first the atom Xover
|
||||
eoBinOp<double> *ptObjAtomCross = NULL;
|
||||
eoBinOp<double> *ptStdevAtomCross = NULL;
|
||||
// then the global one
|
||||
// then the EOT-level one (need to be an eoGenOp as global Xover is
|
||||
eoGenOp<EOT> *ptCross;
|
||||
|
||||
// check for the atom Xovers
|
||||
if (crossObjParam.value() == string("discrete"))
|
||||
ptObjAtomCross = new eoRealAtomExchange;
|
||||
ptObjAtomCross = new eoDoubleExchange;
|
||||
else if (crossObjParam.value() == string("intermediate"))
|
||||
ptObjAtomCross = new eoRealAtomExchange;
|
||||
ptObjAtomCross = new eoDoubleIntermediate;
|
||||
else throw runtime_error("Invalid Object variable crossover type");
|
||||
|
||||
if (crossStdevParam.value() == string("discrete"))
|
||||
ptStdevAtomCross = new eoRealAtomExchange;
|
||||
ptStdevAtomCross = new eoDoubleExchange;
|
||||
else if (crossStdevParam.value() == string("intermediate"))
|
||||
ptStdevAtomCross = new eoRealAtomExchange;
|
||||
ptStdevAtomCross = new eoDoubleIntermediate;
|
||||
else throw runtime_error("Invalid mutation strategy parameter crossover type");
|
||||
|
||||
// and build the indi Xover
|
||||
if (crossTypeParam.value() == string("global"))
|
||||
ptCross = new eoEsGlobalXover<EOT>(*ptObjAtomCross, *ptStdevAtomCross);
|
||||
else if (crossTypeParam.value() == string("standard"))
|
||||
ptCross = new eoEsLocalXover<EOT>(*ptObjAtomCross, *ptStdevAtomCross);
|
||||
{ // using a standard eoBinOp, but wrap it into an eoGenOp
|
||||
eoBinOp<EOT> & crossTmp = _state.storeFunctor(
|
||||
new eoEsStandardXover<EOT>(*ptObjAtomCross, *ptStdevAtomCross)
|
||||
);
|
||||
ptCross = new eoBinGenOp<EOT>(crossTmp);
|
||||
}
|
||||
else throw runtime_error("Invalide Object variable crossover type");
|
||||
|
||||
// now that everything is OK, DON'T FORGET TO STORE MEMORY
|
||||
|
|
@ -143,14 +148,18 @@ eoGenOp<EOT> & do_make_op(eoParameterLoader& _parser, eoState& _state, eoRealIni
|
|||
// Proxy for the mutation parameters
|
||||
eoEsMutationInit mutateInit(_parser, "Variation Operators");
|
||||
|
||||
eoEsMutate<EOT> * ptMon = new eoEsMutate<EOT>(mutateInit, boundsParam.value());
|
||||
_state.storeFunctor(ptMon);
|
||||
eoEsMutate<EOT> & mut = _state.storeFunctor(
|
||||
new eoEsMutate<EOT>(mutateInit, boundsParam.value()));
|
||||
|
||||
// encapsulate into an eoGenop
|
||||
eoMonGenOp<EOT> * op = new eoMonGenOp<EOT>(*ptMon);
|
||||
_state.storeFunctor(op);
|
||||
// now the general op - a sequential application of crossover and mutatation
|
||||
// no need to first have crossover combined with a clone as it is an
|
||||
// eoBinOp and not an eoQuadOp as in SGA paradigm
|
||||
|
||||
eoSequentialOp<EOT> & op = _state.storeFunctor(new eoSequentialOp<EOT>);
|
||||
op.add(*ptCross, pCrossParam.value());
|
||||
op.add(mut, pMutParam.value());
|
||||
|
||||
// that's it!
|
||||
return *op;
|
||||
return op;
|
||||
}
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -232,12 +232,11 @@ eoGenOp<EOT> & do_make_op(eoParameterLoader& _parser, eoState& _state, eoRealIni
|
|||
cross->add(*ptQuad, 1-pCrossParam.value()); // clone operator
|
||||
|
||||
// now the sequential
|
||||
eoSequentialOp<EOT> *op = new eoSequentialOp<EOT>;
|
||||
_state.storeFunctor(op);
|
||||
op->add(*cross, 1.0); // always crossover (but clone with prob 1-pCross
|
||||
op->add(*ptCombinedMonOp, pMutParam.value());
|
||||
eoSequentialOp<EOT> & op = _state.storeFunctor(new eoSequentialOp<EOT>);
|
||||
op.add(*cross, 1.0); // always crossover (but clone with prob 1-pCross
|
||||
op.add(*ptCombinedMonOp, pMutParam.value());
|
||||
|
||||
// that's it!
|
||||
return *op;
|
||||
return op;
|
||||
}
|
||||
#endif
|
||||
|
|
|
|||
Reference in a new issue