Added the crossover in make_op_es (parameters were read, but that's all!

This commit is contained in:
evomarc 2001-05-21 04:13:10 +00:00
commit 8b177dd6cd
6 changed files with 91 additions and 56 deletions

View file

@ -16,4 +16,4 @@ libes_a_SOURCES = make_algo_scalar_real.cpp make_checkpoint_real.cpp \
CPPFLAGS = -Wall CPPFLAGS = -Wall
CXXFLAGS = CXXFLAGS =
libeoincdir = $(includedir)/eo/es 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

View file

@ -63,45 +63,51 @@ public:
*/ */
bool operator()(EOT& _eo1, const EOT& _eo2) bool operator()(EOT& _eo1, const EOT& _eo2)
{ {
bool bLoc=false;
// first, the object variables // first, the object variables
for (unsigned i=0; i<_eo1.size(); i++) 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 // then the self-adaptation parameters
cross_self_adapt(_eo1, _eo2); bLoc |= cross_self_adapt(_eo1, _eo2);
return bLoc;
} }
private: private:
// the method to cross slef-adaptation parameters: need to specialize // 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++) 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; unsigned i;
// the StDev // the StDev
for (i=0; i<_parent1.size(); i++) 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 // the roataion angles
for (i=0; i<_parent1.correlations.size(); i++) 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;
} }

View file

@ -38,16 +38,16 @@
/** /**
Discrete crossover == exchange of values Discrete crossover == exchange of values
*/ */
class eoRealAtomExchange: public eoBinOp<double> class eoDoubleExchange: public eoBinOp<double>
{ {
public: public:
/** /**
* (Default) Constructor. * (Default) Constructor.
*/ */
eoRealAtomExchange() {} eoDoubleExchange() {}
/// The class name. Used to display statistics /// The class name. Used to display statistics
virtual string className() const { return "eoRealAtomExchange"; } virtual string className() const { return "eoDoubleExchange"; }
/** /**
Exchanges or not the values Exchanges or not the values
@ -68,16 +68,16 @@ public:
/** /**
Intermediate crossover == linear combination Intermediate crossover == linear combination
*/ */
class eoRealIntermediate: public eoBinOp<double> class eoDoubleIntermediate: public eoBinOp<double>
{ {
public: public:
/** /**
* (Default) Constructor. * (Default) Constructor.
*/ */
eoRealIntermediate() {} eoDoubleIntermediate() {}
/// The class name. Used to display statistics /// The class name. Used to display statistics
virtual string className() const { return "eoRealIntermediate"; } virtual string className() const { return "eoDoubleIntermediate"; }
/** /**
Linear combination of both parents Linear combination of both parents

View file

@ -301,12 +301,12 @@ template<class EOT> class eoSegmentCrossover: public eoQuadOp<EOT>
if (bounds.isMinBounded(i)) if (bounds.isMinBounded(i))
{ {
alphaMin = max(alphaMin, (bounds.minimum(i)-rmin)/length); 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)) if (bounds.isMaxBounded(i))
{ {
alphaMax = min(alphaMax, (bounds.maximum(i)-rmin)/length); 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 operator()(EOT& _eo1, EOT& _eo2)
{ {
bool hasChanged = false;
unsigned i; unsigned i;
double r1, r2, fact; double r1, r2, fact;
if (alpha == 0.0) // no check to perform if (alpha == 0.0) // no check to perform
for (i=0; i<_eo1.size(); i++) for (i=0; i<_eo1.size(); i++)
{ {
r1=_eo1[i]; r1=_eo1[i];
r2=_eo2[i]; r2=_eo2[i];
fact = -alpha + rng.uniform(range); // in [-alpha,1+alpha) if (r1 != r2) { // otherwise do nothing
_eo1[i] = fact * r1 + (1-fact) * r2; fact = rng.uniform(range); // in [0,1)
_eo2[i] = (1-fact) * r1 + fact * r2; _eo1[i] = fact * r1 + (1-fact) * r2;
} _eo2[i] = (1-fact) * r1 + fact * r2;
else // check the bounds 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++) for (i=0; i<_eo1.size(); i++)
{ {
r1=_eo1[i]; r1=_eo1[i];
r2=_eo2[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 rmin = min(r1, r2);
double rmax = max(r1, r2); double rmax = max(r1, r2);
double length = rmax - rmin;
double alphaMin = -alpha; // compute min and max for object variables
double alphaMax = 1+alpha; double objMin = -alpha * rmax + (1+alpha) * rmin;
double objMax = -alpha * rmin + (1+alpha) * rmax;
// first find the limits on the alpha's // first find the limits on the alpha's
if (bounds.isMinBounded(i)) if (bounds.isMinBounded(i))
{ {
alphaMin = max(alphaMin, (bounds.minimum(i)-rmin)/length); objMin = max(objMin, bounds.minimum(i));
alphaMin = max(alphaMin, (rmax-bounds.maximum(i))/length);
} }
if (bounds.isMaxBounded(i)) if (bounds.isMaxBounded(i))
{ {
alphaMax = min(alphaMax, (bounds.maximum(i)-rmin)/length); objMax = min(objMax, bounds.maximum(i));
alphaMax = min(alphaMax, (rmax-bounds.minimum(i))/length);
} }
fact = alphaMin + rng.uniform(alphaMax-alphaMin); // then draw variables
_eo1[i] = fact * rmin + (1-fact) * rmax; double median = (objMin+objMax)/2.0; // uniform within bounds
_eo2[i] = (1-fact) * rmin + fact * rmax; // 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: protected:

View file

@ -42,7 +42,7 @@
#include <es/eoEsMutationInit.h> #include <es/eoEsMutationInit.h>
#include <es/eoEsMutate.h> #include <es/eoEsMutate.h>
#include <es/eoEsGlobalXover.h> #include <es/eoEsGlobalXover.h>
#include <es/eoEsLocalXover.h> #include <es/eoEsStandardXover.h>
// also need the parser and param includes // also need the parser and param includes
#include <utils/eoParser.h> #include <utils/eoParser.h>
#include <utils/eoState.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 // The pointers: first the atom Xover
eoBinOp<double> *ptObjAtomCross = NULL; eoBinOp<double> *ptObjAtomCross = NULL;
eoBinOp<double> *ptStdevAtomCross = 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; eoGenOp<EOT> *ptCross;
// check for the atom Xovers // check for the atom Xovers
if (crossObjParam.value() == string("discrete")) if (crossObjParam.value() == string("discrete"))
ptObjAtomCross = new eoRealAtomExchange; ptObjAtomCross = new eoDoubleExchange;
else if (crossObjParam.value() == string("intermediate")) else if (crossObjParam.value() == string("intermediate"))
ptObjAtomCross = new eoRealAtomExchange; ptObjAtomCross = new eoDoubleIntermediate;
else throw runtime_error("Invalid Object variable crossover type"); else throw runtime_error("Invalid Object variable crossover type");
if (crossStdevParam.value() == string("discrete")) if (crossStdevParam.value() == string("discrete"))
ptStdevAtomCross = new eoRealAtomExchange; ptStdevAtomCross = new eoDoubleExchange;
else if (crossStdevParam.value() == string("intermediate")) else if (crossStdevParam.value() == string("intermediate"))
ptStdevAtomCross = new eoRealAtomExchange; ptStdevAtomCross = new eoDoubleIntermediate;
else throw runtime_error("Invalid mutation strategy parameter crossover type"); else throw runtime_error("Invalid mutation strategy parameter crossover type");
// and build the indi Xover // and build the indi Xover
if (crossTypeParam.value() == string("global")) if (crossTypeParam.value() == string("global"))
ptCross = new eoEsGlobalXover<EOT>(*ptObjAtomCross, *ptStdevAtomCross); ptCross = new eoEsGlobalXover<EOT>(*ptObjAtomCross, *ptStdevAtomCross);
else if (crossTypeParam.value() == string("standard")) 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"); else throw runtime_error("Invalide Object variable crossover type");
// now that everything is OK, DON'T FORGET TO STORE MEMORY // 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 // Proxy for the mutation parameters
eoEsMutationInit mutateInit(_parser, "Variation Operators"); eoEsMutationInit mutateInit(_parser, "Variation Operators");
eoEsMutate<EOT> * ptMon = new eoEsMutate<EOT>(mutateInit, boundsParam.value()); eoEsMutate<EOT> & mut = _state.storeFunctor(
_state.storeFunctor(ptMon); new eoEsMutate<EOT>(mutateInit, boundsParam.value()));
// encapsulate into an eoGenop // now the general op - a sequential application of crossover and mutatation
eoMonGenOp<EOT> * op = new eoMonGenOp<EOT>(*ptMon); // no need to first have crossover combined with a clone as it is an
_state.storeFunctor(op); // 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! // that's it!
return *op; return op;
} }
#endif #endif

View file

@ -232,12 +232,11 @@ eoGenOp<EOT> & do_make_op(eoParameterLoader& _parser, eoState& _state, eoRealIni
cross->add(*ptQuad, 1-pCrossParam.value()); // clone operator cross->add(*ptQuad, 1-pCrossParam.value()); // clone operator
// now the sequential // now the sequential
eoSequentialOp<EOT> *op = new eoSequentialOp<EOT>; eoSequentialOp<EOT> & op = _state.storeFunctor(new eoSequentialOp<EOT>);
_state.storeFunctor(op); op.add(*cross, 1.0); // always crossover (but clone with prob 1-pCross
op->add(*cross, 1.0); // always crossover (but clone with prob 1-pCross op.add(*ptCombinedMonOp, pMutParam.value());
op->add(*ptCombinedMonOp, pMutParam.value());
// that's it! // that's it!
return *op; return op;
} }
#endif #endif