diff --git a/eo/src/es/Makefile.am b/eo/src/es/Makefile.am index bef3f588..9b388266 100644 --- a/eo/src/es/Makefile.am +++ b/eo/src/es/Makefile.am @@ -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 diff --git a/eo/src/es/eoEsStandardXover.h b/eo/src/es/eoEsStandardXover.h index df7c2374..d360d953 100644 --- a/eo/src/es/eoEsStandardXover.h +++ b/eo/src/es/eoEsStandardXover.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 & _parent1, const eoEsSimple & _parent2) + bool cross_self_adapt(eoEsSimple & _parent1, const eoEsSimple & _parent2) { - crossMut(_parent1.stdev, _parent2.stdev); // apply eoBinOp + return crossMut(_parent1.stdev, _parent2.stdev); // apply eoBinOp } - void cross_self_adapt(eoEsStdev & _parent1, const eoEsStdev & _parent2) + bool cross_self_adapt(eoEsStdev & _parent1, const eoEsStdev & _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 & _parent1, const eoEsFull & _parent2) + bool cross_self_adapt(eoEsFull & _parent1, const eoEsFull & _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; } diff --git a/eo/src/es/eoRealAtomXover.h b/eo/src/es/eoRealAtomXover.h index 82448d98..91d7520e 100644 --- a/eo/src/es/eoRealAtomXover.h +++ b/eo/src/es/eoRealAtomXover.h @@ -38,16 +38,16 @@ /** Discrete crossover == exchange of values */ -class eoRealAtomExchange: public eoBinOp +class eoDoubleExchange: public eoBinOp { 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 +class eoDoubleIntermediate: public eoBinOp { 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 diff --git a/eo/src/es/eoRealOp.h b/eo/src/es/eoRealOp.h index 9125b28a..1f7ee14d 100644 --- a/eo/src/es/eoRealOp.h +++ b/eo/src/es/eoRealOp.h @@ -301,12 +301,12 @@ template class eoSegmentCrossover: public eoQuadOp 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 eoHypercubeCrossover: public eoQuadOp */ 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: diff --git a/eo/src/es/make_op_es.h b/eo/src/es/make_op_es.h index 846ac9e3..91274a24 100644 --- a/eo/src/es/make_op_es.h +++ b/eo/src/es/make_op_es.h @@ -42,7 +42,7 @@ #include #include #include -#include +#include // also need the parser and param includes #include #include @@ -108,27 +108,32 @@ eoGenOp & do_make_op(eoParameterLoader& _parser, eoState& _state, eoRealIni // The pointers: first the atom Xover eoBinOp *ptObjAtomCross = NULL; eoBinOp *ptStdevAtomCross = NULL; - // then the global one + // then the EOT-level one (need to be an eoGenOp as global Xover is eoGenOp *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(*ptObjAtomCross, *ptStdevAtomCross); else if (crossTypeParam.value() == string("standard")) - ptCross = new eoEsLocalXover(*ptObjAtomCross, *ptStdevAtomCross); + { // using a standard eoBinOp, but wrap it into an eoGenOp + eoBinOp & crossTmp = _state.storeFunctor( + new eoEsStandardXover(*ptObjAtomCross, *ptStdevAtomCross) + ); + ptCross = new eoBinGenOp(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 & do_make_op(eoParameterLoader& _parser, eoState& _state, eoRealIni // Proxy for the mutation parameters eoEsMutationInit mutateInit(_parser, "Variation Operators"); - eoEsMutate * ptMon = new eoEsMutate(mutateInit, boundsParam.value()); - _state.storeFunctor(ptMon); + eoEsMutate & mut = _state.storeFunctor( + new eoEsMutate(mutateInit, boundsParam.value())); - // encapsulate into an eoGenop - eoMonGenOp * op = new eoMonGenOp(*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 & op = _state.storeFunctor(new eoSequentialOp); + op.add(*ptCross, pCrossParam.value()); + op.add(mut, pMutParam.value()); // that's it! - return *op; + return op; } #endif diff --git a/eo/src/es/make_op_real.h b/eo/src/es/make_op_real.h index 75aa8569..c8835717 100644 --- a/eo/src/es/make_op_real.h +++ b/eo/src/es/make_op_real.h @@ -232,12 +232,11 @@ eoGenOp & do_make_op(eoParameterLoader& _parser, eoState& _state, eoRealIni cross->add(*ptQuad, 1-pCrossParam.value()); // clone operator // now the sequential - eoSequentialOp *op = new eoSequentialOp; - _state.storeFunctor(op); - op->add(*cross, 1.0); // always crossover (but clone with prob 1-pCross - op->add(*ptCombinedMonOp, pMutParam.value()); + eoSequentialOp & op = _state.storeFunctor(new eoSequentialOp); + 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