diff --git a/eo/src/es/eoNormalMutation.h b/eo/src/es/eoNormalMutation.h new file mode 100644 index 00000000..cc3276e8 --- /dev/null +++ b/eo/src/es/eoNormalMutation.h @@ -0,0 +1,165 @@ +// -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*- + +//----------------------------------------------------------------------------- +// eoNormalMutation.h +// (c) EEAAX 2001 - Maarten Keijzer 2000 +/* + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Contact: Marc.Schoenauer@polytechnique.fr + mak@dhi.dk + */ +//----------------------------------------------------------------------------- + +#ifndef eoNormalMutation_h +#define eoNormalMutation_h + +//----------------------------------------------------------------------------- + +#include // swap_ranges +#include +#include +#include +#include + +//----------------------------------------------------------------------------- + +/** Simple normal mutation of a vector of real values. + * The stDev is fixed - but it is passed ans stored as a reference, + * to enable dynamic mutations (see eoOenFithMutation below). + */ + +template class eoNormalMutation: public eoMonOp +{ + public: + /** + * (Default) Constructor. + * @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): + sigma(_sigma), 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 hasChanged=false; + for (unsigned lieu=0; lieu<_eo.size(); lieu++) + { + if (rng.flip(p_change)) + { + _eo[lieu] += sigma*rng.normal(); + hasChanged = true; + } + } + if (hasChanged) + _eo.invalidate(); + } + +protected: + double & sigma; +private: + double p_change; +}; + +/** 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 + * increase sigma if more than threshold (1/5 !) + */ + +template class eoOneFifthMutation : + public eoNormalMutation, public eoUpdatable +{ +public: + typedef typename EOT::Fitness Fitness; + + /** + * (Default) Constructor. + * + * @param eval the evaluation fuinction, needed to recompute the fitmess + * @param _sigmaInit the initial value for uniform nutation + * @param _windowSize the size of the window for statistics + * @param _threshold the threshold (the 1/5 - 0.2) + * @param _updateFactor multiplicative update factor for sigma + */ + eoOneFifthMutation(eoEvalFunc & _eval, double & _sigmaInit, + unsigned _windowSize = 10, + double _threshold=0.2, double _updateFactor=0.83): + eoNormalMutation(_sigmaInit), eval(_eval), + threshold(_threshold), updateFactor(_updateFactor), + nbMut(_windowSize, 0), nbSuccess(_windowSize, 0), genIndex(0) {} + + /** + * Do it! + * @param _eo The cromosome undergoing the mutation + * calls the standard mutation, then checks for success + */ + void operator()(EOT & _eo) + { + Fitness oldFitness = _eo.fitness(); // save old fitness + + eoNormalMutation::operator()(_eo); // normal mutation + nbMut++; // assumes normal mutation always modifies _eo + + eval(_eo); // compute fitness of offspring + + if (_eo.fitness() > oldFitness) + nbSuccess++; // update counter + } + + // this will be called every generation + void update() + { + unsigned totalMut = 0; + unsigned totalSuccess = 0; + // compute the average stats over the time window + for ( unsigned i=0; i threshold) + sigma /= updateFactor; // increase sigma + else + sigma *= updateFactor; // decrease sigma + + // go to next generation + genIndex = (genIndex+1) % nbMut.size() ; + nbMut[genIndex] = nbSuccess[genIndex] = 0; + } +private: + eoEvalFunc & eval; + double threshold; // 1/5 ! + double updateFactor ; // the multiplicative factor + vector nbMut; // total number of mutations per gen + vector nbSuccess; // number of successful mutations per gen + unsigned genIndex ; // current gen +}; + + +//----------------------------------------------------------------------------- +//@} +#endif eoRealOp_h + diff --git a/eo/src/es/eoRealOp.h b/eo/src/es/eoRealOp.h index 5eabd416..1cdef1cd 100644 --- a/eo/src/es/eoRealOp.h +++ b/eo/src/es/eoRealOp.h @@ -41,7 +41,7 @@ \ingroup parameteric */ -template class eoUniformMutation: public eoMonOp +template class eoUniformMutation: public eoMonOp { public: /** @@ -57,21 +57,21 @@ template class eoUniformMutation: public eoMonOp /** * Do it! - * @param chrom The cromosome undergoing the mutation + * @param _eo The cromosome undergoing the mutation */ - void operator()(Chrom& chrom) + void operator()(EOT& _eo) { bool hasChanged=false; - for (unsigned lieu=0; lieu class eoDetUniformMutation: public eoMonOp +template class eoDetUniformMutation: public eoMonOp { public: /** @@ -101,16 +101,16 @@ template class eoDetUniformMutation: public eoMonOp /** * Do it! - * @param chrom The cromosome undergoing the mutation + * @param _eo The cromosome undergoing the mutation */ - void operator()(Chrom& chrom) + void operator()(EOT& _eo) { - chrom.invalidate(); + _eo.invalidate(); for (unsigned i=0; i class eoNormalMutation: public eoMonOp -{ - public: - /** - * (Default) Constructor. - * @param _epsilon the range for uniform nutation - * @param _p_change the probability to change a given coordinate - */ - eoNormalMutation(const double& _epsilon, const double& _p_change = 1.0): - epsilon(_epsilon), p_change(_p_change) {} - - /// The class name. - string className() const { return "eoNormalMutation"; } - - /** - * Do it! - * @param chrom The cromosome undergoing the mutation - */ - void operator()(Chrom& chrom) - { - bool hasChanged=false; - for (unsigned lieu=0; lieu uniform choice in segment @@ -167,7 +128,7 @@ private: \ingroup parameteric */ -template class eoSegmentCrossover: public eoQuadraticOp +template class eoSegmentCrossover: public eoQuadraticOp { public: /** @@ -184,23 +145,23 @@ template class eoSegmentCrossover: public eoQuadraticOp /** * segment crossover - modifies both parents - * @param chrom1 The first parent - * @param chrom2 The first parent + * @param _eo1 The first parent + * @param _eo2 The first parent */ - void operator()(Chrom& chrom1, Chrom& chrom2) + void operator()(EOT& _eo1, EOT& _eo2) { unsigned i; double r1, r2, fact; fact = rng.uniform(range); // in [0,range) - for (i=0; i class eoArithmeticCrossover: public eoQuadraticOp +template class eoArithmeticCrossover: public eoQuadraticOp { public: /** @@ -231,20 +192,20 @@ template class eoArithmeticCrossover: public eoQuadraticOp /** * arithmetical crossover - modifies both parents - * @param chrom1 The first parent - * @param chrom2 The first parent + * @param _eo1 The first parent + * @param _eo2 The first parent */ - void operator()(Chrom& chrom1, Chrom& chrom2) + void operator()(EOT& _eo1, EOT& _eo2) { unsigned i; double r1, r2, fact; - for (i=0; i class eoRealUxOver: public eoQuadraticOp +template class eoRealUxOver: public eoQuadraticOp { public: /** @@ -277,30 +238,30 @@ template class eoRealUxOver: public eoQuadraticOp /** * Uniform crossover for real vectors - * @param chrom1 The first parent - * @param chrom2 The second parent + * @param _eo1 The first parent + * @param _eo2 The second parent * @runtime_error if sizes don't match */ - void operator()(Chrom& chrom1, Chrom& chrom2) + void operator()(EOT& _eo1, EOT& _eo2) { - if ( chrom1.size() != chrom2.size()) + if ( _eo1.size() != _eo2.size()) runtime_error("UxOver --> chromosomes sizes don't match" ); bool changed = false; - for (unsigned int i=0; i