THe code for the 1/5th mutation was completely wrong!

This commit is contained in:
evomarc 2002-05-01 02:44:54 +00:00
commit 8998caa4ff

View file

@ -65,10 +65,10 @@ template<class EOT> class eoNormalMutation: public eoMonOp<EOT>
* @param _p_change the probability to change a given coordinate * @param _p_change the probability to change a given coordinate
*/ */
eoNormalMutation(eoRealVectorBounds & _bounds, eoNormalMutation(eoRealVectorBounds & _bounds,
double & _sigma, const double& _p_change = 1.0): double _sigma, const double& _p_change = 1.0):
sigma(_sigma), bounds(_bounds), p_change(_p_change) {} sigma(_sigma), bounds(_bounds), p_change(_p_change) {}
/// The class name. /** The class name */
virtual string className() const { return "eoNormalMutation"; } virtual string className() const { return "eoNormalMutation"; }
/** /**
@ -90,9 +90,11 @@ template<class EOT> class eoNormalMutation: public eoMonOp<EOT>
return hasChanged; return hasChanged;
} }
protected: /** Accessor to ref to sigma - for update and monitor */
double & sigma; double & Sigma() {return sigma;}
private: private:
double & sigma;
eoRealVectorBounds & bounds; eoRealVectorBounds & bounds;
double p_change; double p_change;
}; };
@ -112,38 +114,55 @@ public:
/** /**
* (Default) Constructor. * (Default) Constructor.
* *
* @param eval the evaluation fuinction, needed to recompute the fitmess * @param eval the evaluation function, needed to recompute the fitmess
* @param _sigmaInit the initial value for uniform nutation * @param _sigmaInit the initial value for uniform mutation
* @param _windowSize the size of the window for statistics * @param _windowSize the size of the window for statistics
* @param _threshold the threshold (the 1/5 - 0.2) * @param _threshold the threshold (the 1/5 - 0.2)
* @param _updateFactor multiplicative update factor for sigma * @param _updateFactor multiplicative update factor for sigma
*/ */
eoOneFifthMutation(eoEvalFunc<EOT> & _eval, double & _sigmaInit, eoOneFifthMutation(eoEvalFunc<EOT> & _eval, double & _sigmaInit,
unsigned _windowSize = 10, unsigned _windowSize = 10, double _updateFactor=0.83,
double _threshold=0.2, double _updateFactor=0.83): double _threshold=0.2):
eoNormalMutation<EOT>(_sigmaInit), eval(_eval), eoNormalMutation<EOT>(_sigmaInit), eval(_eval),
threshold(_threshold), updateFactor(_updateFactor), threshold(_threshold), updateFactor(_updateFactor),
nbMut(_windowSize, 0), nbSuccess(_windowSize, 0), genIndex(0) {} nbMut(_windowSize, 0), nbSuccess(_windowSize, 0), genIndex(0)
{
// minimal check
if (updateFactor>=1)
throw runtime_error("Update factor must be < 1 in eoOneFifthMutation");
}
/** The class name */
virtual string className() const { return "eoOneFifthMutation"; }
/** /**
* Do it! * Do it!
* @param _eo The cromosome undergoing the mutation * calls the standard mutation, then checks for success and updates stats
* calls the standard mutation, then checks for success *
* @param _eo The chromosome undergoing the mutation
*/ */
void operator()(EOT & _eo) bool operator()(EOT & _eo)
{ {
if (_eo.invalid()) // due to some crossover???
eval(_eo);
Fitness oldFitness = _eo.fitness(); // save old fitness Fitness oldFitness = _eo.fitness(); // save old fitness
eoNormalMutation<EOT>::operator()(_eo); // normal mutation // call standard operator - then count the successes
nbMut++; // assumes normal mutation always modifies _eo if (eoNormalMutation<EOT>::operator()(_eo)) // _eo has been modified
{
_eo.invalidate(); // don't forget!!!
nbMut[genIndex]++;
eval(_eo); // compute fitness of offspring
eval(_eo); // compute fitness of offspring if (_eo.fitness() > oldFitness)
nbSuccess[genIndex]++; // update counter
if (_eo.fitness() > oldFitness) }
nbSuccess++; // update counter return false; // because eval has reset the validity flag
} }
// this will be called every generation /** the method that will be called every generation
* if the object is added to the checkpoint
*/
void update() void update()
{ {
unsigned totalMut = 0; unsigned totalMut = 0;
@ -156,23 +175,26 @@ public:
} }
// update sigma accordingly // update sigma accordingly
double prop = (double) totalSuccess / totalMut; double prop = double(totalSuccess) / totalMut;
if (prop > threshold) if (prop > threshold) {
sigma /= updateFactor; // increase sigma Sigma() /= updateFactor; // increase sigma
}
else else
sigma *= updateFactor; // decrease sigma {
Sigma() *= updateFactor; // decrease sigma
// go to next generation }
genIndex = (genIndex+1) % nbMut.size() ; genIndex = (genIndex+1) % nbMut.size() ;
nbMut[genIndex] = nbSuccess[genIndex] = 0; nbMut[genIndex] = nbSuccess[genIndex] = 0;
} }
private: private:
eoEvalFunc<EOT> & eval; eoEvalFunc<EOT> & eval;
double threshold; // 1/5 ! double threshold; // 1/5 !
double updateFactor ; // the multiplicative factor double updateFactor ; // the multiplicative factor
vector<unsigned> nbMut; // total number of mutations per gen vector<unsigned> nbMut; // total number of mutations per gen
vector<unsigned> nbSuccess; // number of successful mutations per gen vector<unsigned> nbSuccess; // number of successful mutations per gen
unsigned genIndex ; // current gen unsigned genIndex ; // current index in vectors (circular)
}; };