00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #ifndef eoNormalMutation_h
00027 #define eoNormalMutation_h
00028
00029
00030
00031 #include <algorithm>
00032 #include <utils/eoRNG.h>
00033 #include <utils/eoUpdatable.h>
00034 #include <eoEvalFunc.h>
00035 #include <es/eoReal.h>
00036 #include <utils/eoRealBounds.h>
00037
00038
00048 template<class EOT> class eoNormalVecMutation: public eoMonOp<EOT>
00049 {
00050 public:
00058 eoNormalVecMutation(double _sigma, const double& _p_change = 1.0):
00059 sigma(_sigma), bounds(eoDummyVectorNoBounds), p_change(_p_change) {}
00060
00069 eoNormalVecMutation(eoRealVectorBounds & _bounds,
00070 double _sigma, const double& _p_change = 1.0):
00071 sigma(_bounds.size(), _sigma), bounds(_bounds), p_change(_p_change)
00072 {
00073
00074 for (unsigned i=0; i<bounds.size(); i++)
00075 if (bounds.isBounded(i))
00076 sigma[i] *= _sigma*bounds.range(i);
00077 }
00078
00080 virtual std::string className() const { return "eoNormalVecMutation"; }
00081
00086 bool operator()(EOT& _eo)
00087 {
00088 bool hasChanged=false;
00089 for (unsigned lieu=0; lieu<_eo.size(); lieu++)
00090 {
00091 if (rng.flip(p_change))
00092 {
00093 _eo[lieu] += sigma[lieu]*rng.normal();
00094 bounds.foldsInBounds(lieu, _eo[lieu]);
00095 hasChanged = true;
00096 }
00097 }
00098 return hasChanged;
00099 }
00100
00101 private:
00102 std::vector<double> sigma;
00103 eoRealVectorBounds & bounds;
00104 double p_change;
00105 };
00106
00116 template<class EOT> class eoNormalMutation
00117 : public eoMonOp<EOT>
00118 {
00119 public:
00127 eoNormalMutation(double & _sigma, const double& _p_change = 1.0):
00128 sigma(_sigma), bounds(eoDummyVectorNoBounds), p_change(_p_change) {}
00129
00136 eoNormalMutation(eoRealVectorBounds & _bounds,
00137 double _sigma, const double& _p_change = 1.0):
00138 sigma(_sigma), bounds(_bounds), p_change(_p_change) {}
00139
00141 virtual std::string className() const { return "eoNormalMutation"; }
00142
00147 bool operator()(EOT& _eo)
00148 {
00149 bool hasChanged=false;
00150 for (unsigned lieu=0; lieu<_eo.size(); lieu++)
00151 {
00152 if (rng.flip(p_change))
00153 {
00154 _eo[lieu] += sigma*rng.normal();
00155 bounds.foldsInBounds(lieu, _eo[lieu]);
00156 hasChanged = true;
00157 }
00158 }
00159 return hasChanged;
00160 }
00161
00163 double & Sigma() {return sigma;}
00164
00165 private:
00166 double & sigma;
00167 eoRealVectorBounds & bounds;
00168 double p_change;
00169 };
00170
00177 template<class EOT> class eoOneFifthMutation :
00178 public eoNormalMutation<EOT>, public eoUpdatable
00179 {
00180 public:
00181
00182 using eoNormalMutation< EOT >::Sigma;
00183
00184 typedef typename EOT::Fitness Fitness;
00185
00195 eoOneFifthMutation(eoEvalFunc<EOT> & _eval, double & _sigmaInit,
00196 unsigned _windowSize = 10, double _updateFactor=0.83,
00197 double _threshold=0.2):
00198 eoNormalMutation<EOT>(_sigmaInit), eval(_eval),
00199 threshold(_threshold), updateFactor(_updateFactor),
00200 nbMut(_windowSize, 0), nbSuccess(_windowSize, 0), genIndex(0)
00201 {
00202
00203 if (updateFactor>=1)
00204 throw std::runtime_error("Update factor must be < 1 in eoOneFifthMutation");
00205 }
00206
00208 virtual std::string className() const { return "eoOneFifthMutation"; }
00209
00216 bool operator()(EOT & _eo)
00217 {
00218 if (_eo.invalid())
00219 eval(_eo);
00220 Fitness oldFitness = _eo.fitness();
00221
00222
00223 if (eoNormalMutation<EOT>::operator()(_eo))
00224 {
00225 _eo.invalidate();
00226 nbMut[genIndex]++;
00227 eval(_eo);
00228
00229 if (_eo.fitness() > oldFitness)
00230 nbSuccess[genIndex]++;
00231 }
00232 return false;
00233 }
00234
00238 void update()
00239 {
00240 unsigned totalMut = 0;
00241 unsigned totalSuccess = 0;
00242
00243 for ( unsigned i=0; i<nbMut.size(); i++)
00244 {
00245 totalMut += nbMut[i];
00246 totalSuccess += nbSuccess[i];
00247 }
00248
00249
00250 double prop = double(totalSuccess) / totalMut;
00251 if (prop > threshold) {
00252 Sigma() /= updateFactor;
00253 }
00254 else
00255 {
00256 Sigma() *= updateFactor;
00257 }
00258 genIndex = (genIndex+1) % nbMut.size() ;
00259 nbMut[genIndex] = nbSuccess[genIndex] = 0;
00260
00261 }
00262
00263 private:
00264 eoEvalFunc<EOT> & eval;
00265 double threshold;
00266 double updateFactor ;
00267 std::vector<unsigned> nbMut;
00268 std::vector<unsigned> nbSuccess;
00269 unsigned genIndex ;
00270 };
00271
00272
00273
00275 #endif
00276