#ifndef _eoStandardBitMutation_h_ #define _eoStandardBitMutation_h_ #include "../utils/eoRNG.h" /** Standard bit mutation with mutation rate p: * choose k from the binomial distribution Bin(n,p) and apply flip_k(x). * * @ingroup Bitstrings * @ingroup Variators */ template class eoStandardBitMutation : public eoMonOp { public: eoStandardBitMutation(double rate = 0.5) : _rate(rate), _nb(1), _bitflip(_nb) {} virtual bool operator()(EOT& chrom) { _nb = eo::rng.binomial(chrom.size(),_rate); // BitFlip operator is bound to the _nb reference, // thus one don't need to re-instantiate. return _bitflip(chrom); } virtual std::string className() const {return "eoStandardBitMutation";} protected: double _rate; unsigned _nb; eoDetSingleBitFlip _bitflip; }; /** Uniform bit mutation with mutation rate p: * choose k from the uniform distribution U(0,n) and apply flip_k(x). * * @ingroup Bitstrings * @ingroup Variators */ template class eoUniformBitMutation : public eoMonOp { public: eoUniformBitMutation(double rate = 0.5) : _rate(rate), _nb(1), _bitflip(_nb) {} virtual bool operator()(EOT& chrom) { _nb = eo::rng.random(chrom.size()); // BitFlip operator is bound to the _nb reference, // thus one don't need to re-instantiate. return _bitflip(chrom); } virtual std::string className() const {return "eoUniformBitMutation";} protected: double _rate; unsigned _nb; eoDetSingleBitFlip _bitflip; }; /** Conditional standard bit mutation with mutation rate p: * choose k from the binomial distribution Bin(n,p) until k >0 * and apply flip_k(x). * * This is identical to sampling k from the conditional binomial * distribution Bin>0(n,p) which re-assigns the probability to sample * a 0 proportionally to all values i ∈ [1..n]. * * @ingroup Bitstrings * @ingroup Variators */ template class eoConditionalBitMutation : public eoStandardBitMutation { public: eoConditionalBitMutation(double rate = 0.5) : eoStandardBitMutation(rate) {} virtual bool operator()(EOT& chrom) { assert(chrom.size()>0); this->_nb = eo::rng.binomial(chrom.size()-1,this->_rate); this->_nb++; // BitFlip operator is bound to the _nb reference, // thus one don't need to re-instantiate. return this->_bitflip(chrom); } virtual std::string className() const {return "eoConditionalBitMutation";} }; /** Shifted standard bit mutation with mutation rate p: * choose k from the binomial distribution Bin(n,p). * When k= 0, set k= 1. Apply flip_k(x). * * This is identical to sampling k from the conditional binomial * distribution Bin0→1(n,p) which re-assigns the probability to * sample a 0 to sampling k= 1. * * @ingroup Bitstrings * @ingroup Variators */ template class eoShiftedBitMutation : public eoStandardBitMutation { public: eoShiftedBitMutation(double rate = 0.5) : eoStandardBitMutation(rate) {} virtual bool operator()(EOT& chrom) { assert(chrom.size()>0); this->_nb = eo::rng.binomial(chrom.size()-1,this->_rate); if(this->_nb == 0) { this->_nb = 1; } // BitFlip operator is bound to the _nb reference, // thus one don't need to re-instantiate. return this->_bitflip(chrom); } virtual std::string className() const {return "eoShiftedBitMutation";} }; /** Mutation which size is sample in a gaussian. * * sample k from the normal distribution N(pn,σ^2) * and apply flip_k(x). * * From: * Furong Ye, Carola Doerr, and Thomas Back. * Interpolating local and global search by controllingthe variance of standard bit mutation. * In 2019 IEEE Congress on Evolutionary Computation(CEC), pages 2292–2299. * * In contrast to standard bit mutation, this operators allows to scale * the variance of the mutation strength independently of the mean. * * @ingroup Bitstrings * @ingroup Variators */ template class eoNormalBitMutation : public eoStandardBitMutation { public: eoNormalBitMutation(double rate = 0.5, double variance = 1) : eoStandardBitMutation(rate), _variance(variance) {} virtual bool operator()(EOT& chrom) { this->_nb = eo::rng.normal(this->_rate * chrom.size(), _variance); if(this->_nb >= chrom.size()) { this->_nb = eo::rng.random(chrom.size()); } // BitFlip operator is bound to the _nb reference, // thus one don't need to re-instantiate. return this->_bitflip(chrom); } virtual std::string className() const {return "eoNormalBitMutation";} protected: double _variance; }; /** Fast mutation which size is sampled from an adaptive power law. * * From: * Benjamin Doerr, Huu Phuoc Le, Régis Makhmara, and Ta Duy Nguyen. * Fast genetic algorithms. * In Proc. of Genetic and Evolutionary Computation Conference (GECCO’17), pages 777–784.ACM, 2017. * * @ingroup Bitstrings * @ingroup Variators */ template class eoFastBitMutation : public eoStandardBitMutation { public: eoFastBitMutation(double rate = 0.5, double beta = 1.5) : eoStandardBitMutation(rate), _beta(beta) { assert(beta > 1); } virtual bool operator()(EOT& chrom) { this->_nb = powerlaw(chrom.size(),_beta); // BitFlip operator is bound to the _nb reference, // thus one don't need to re-instantiate. return this->_bitflip(chrom); } virtual std::string className() const {return "eoFastBitMutation";} protected: double powerlaw(unsigned n, double beta) { double cnb = 0; for(unsigned i=1; i