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
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

View file

@ -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;
}

View file

@ -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

View file

@ -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:

View file

@ -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

View file

@ -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