diff --git a/eo/src/eoFixedLength.h b/eo/src/eoFixedLength.h index a7355e5b..9b65dc6e 100644 --- a/eo/src/eoFixedLength.h +++ b/eo/src/eoFixedLength.h @@ -46,7 +46,17 @@ class eoFixedLength : public EO, public std::vector eoFixedLength(unsigned size = 0, GeneType value = GeneType()) : EO(), std::vector(size, value) {} - /// to avoid conflicts between EO::operator< and vector::operator< + // we can't have a Ctor from a vector, it would create ambiguity + // with the copy Ctor + void value(std::vector _v) + { + if (_v.size() != size()) + throw runtime_error("Wrong size in vector assignation in eoFixedLength"); + copy(_v.begin(), _v.end(), begin()); + invalidate(); + } + + /// to avoid conflicts between EO::operator< and vector::operator< bool operator<(const eoFixedLength& _eo) const { return EO::operator<(_eo); diff --git a/eo/src/eoGenericBinOp.h b/eo/src/eoGenericBinOp.h new file mode 100644 index 00000000..dbf909f8 --- /dev/null +++ b/eo/src/eoGenericBinOp.h @@ -0,0 +1,75 @@ +// -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*- + +//----------------------------------------------------------------------------- +// eoGenericBinOp.h +// (c) GeNeura Team, 2000 - EEAAX 1999 - 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: todos@geneura.ugr.es, http://geneura.ugr.es + Marc.Schoenauer@polytechnique.fr + mak@dhi.dk + */ +//----------------------------------------------------------------------------- + +#ifndef _eoGenericBinOp_h +#define _eoGenericBinOp_h + +#include + +/** Contains base classes for generic binary operators for eoFixedLength + and eoVariableLength (They also derive from the eoOp) as well as + the corresponding converters to actual Ops. +*/ + +/** eoGenericBinOp is the generic binary operator: +it takes two arguments, modifies the first one, and returns a boolean +indicating if the argument has actually been modified +*/ + +template +class eoGenericBinOp: public eoOp, public eoBF +{ +public: + /// Ctor + eoGenericBinOp() + : eoOp( eoOp::binary ) {}; + virtual string className() const {return "eoGenericBinOp";}; +}; + +/** Converter from eoGenericBinOp to eoBinOp + the only thinig to do is to transform the boolean into invalidation +*/ + +template +class eoGeneric2TrueBinOp: public eoBinOp +{ +public: + /// Ctor + eoGeneric2TrueBinOp(eoGenericBinOp & _binOp) + : binOp( _binOp ) {}; + virtual string className() const {return "eoGeneric2TrueBinOp";} + + virtual void operator()(EOT & _eo1, const EOT & _eo2) + { + if (binOp(_eo1, _eo2)) + _eo1.invalidate(); + } + + private: + eoGenericBinOp & binOp; +}; + +#endif diff --git a/eo/src/eoGenericMonOp.h b/eo/src/eoGenericMonOp.h new file mode 100644 index 00000000..d6d833c9 --- /dev/null +++ b/eo/src/eoGenericMonOp.h @@ -0,0 +1,75 @@ +// -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*- + +//----------------------------------------------------------------------------- +// eoGenericMonOp.h +// (c) GeNeura Team, 2000 - EEAAX 1999 - 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: todos@geneura.ugr.es, http://geneura.ugr.es + Marc.Schoenauer@polytechnique.fr + mak@dhi.dk + */ +//----------------------------------------------------------------------------- + +#ifndef _eoGenericMonOp_h +#define _eoGenericMonOp_h + +#include + +/** Contains base classes for generic operators for eoFixedLength + and eoVariableLength (They also derive from the eoOp) as well as + the corresponding converters to actual Ops. +*/ + +/** eoGenericMonOp is the generic unary operator: +it takes one argument, and returns a boolean indicating if the argument +has been modified +*/ + +template +class eoGenericMonOp: public eoOp, public eoUF +{ +public: + /// Ctor + eoGenericMonOp() + : eoOp( eoOp::unary ) {}; + virtual string className() const {return "eoGenericMonOp";}; +}; + +/** COnverter from eoGenericMonOp to eoMonOp + the only thinig to do is to transform the boolean into invalidation +*/ + +template +class eoGeneric2TrueMonOp: public eoMonOp +{ +public: + /// Ctor + eoGeneric2TrueMonOp(eoGenericMonOp & _monOp) + : monOp( _monOp ) {}; + virtual string className() const {return "eoGeneric2trueMonOp";} + + virtual void operator()(EOT & _eo) + { + if (monOp(_eo)) + _eo.invalidate(); + } + + private: + eoGenericMonOp & monOp; +}; + +#endif diff --git a/eo/src/eoGenericQuadOp.h b/eo/src/eoGenericQuadOp.h new file mode 100644 index 00000000..0df6b966 --- /dev/null +++ b/eo/src/eoGenericQuadOp.h @@ -0,0 +1,83 @@ +// -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*- + +//----------------------------------------------------------------------------- +// eoGenericQuadOp.h +// (c) GeNeura Team, 2000 - EEAAX 1999 - 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: todos@geneura.ugr.es, http://geneura.ugr.es + Marc.Schoenauer@polytechnique.fr + mak@dhi.dk + */ +//----------------------------------------------------------------------------- + +#ifndef _eoGenericQuadOp_h +#define _eoGenericQuadOp_h + +#include + +/** Contains base classes for generic quadratic operators for eoFixedLength + and eoVariableLength (They also derive from the eoOp) as well as + the corresponding converters to actual Ops. +*/ + +/** eoGenericQuadOp is the generic quadratic operator: +it takes two arguments, modifies the first one, and returns a boolean +indicating if the arguments have actually been modified + +WARNING: even if only 1 argument is modified, it should return true, + and both fitnesses will be invalidated. It is assumed that + quadratic operators do some exchange of genetic material, so + if one is modified, the other is, too! +*/ + +template +class eoGenericQuadOp: public eoOp, public eoBF +{ +public: + /// Ctor + eoGenericQuadOp() + : eoOp( eoOp::binary ) {}; + virtual string className() const {return "eoGenericQuadOp";}; +}; + +/** Converter from eoGenericQuadOp to eoQuadOp + the only thinig to do is to transform the boolean into invalidation +*/ + +template +class eoGeneric2TrueQuadOp: public eoQuadOp +{ +public: + /// Ctor + eoGeneric2TrueQuadOp(eoGenericQuadOp & _quadOp) + : quadOp( _quadOp ) {}; + virtual string className() const {return "eoGeneric2TrueQuadOp";} + + virtual void operator()(EOT & _eo1, EOT & _eo2) + { + if (quadOp(_eo1, _eo2)) + { + _eo1.invalidate(); + _eo2.invalidate(); + } + } + + private: + eoGenericQuadOp & quadOp; +}; + +#endif diff --git a/eo/src/eoOp.h b/eo/src/eoOp.h index 93cf4d93..dbeb65b5 100644 --- a/eo/src/eoOp.h +++ b/eo/src/eoOp.h @@ -105,6 +105,7 @@ public: /** Quadratic genetic operator: subclasses eoOp, and defines basically the operator() with two operands, both can be modified. */ +#define eoQuadraticOp eoQuadOp template class eoQuadraticOp: public eoOp, public eoBF { @@ -115,6 +116,29 @@ public: virtual string className() const {return "eoQuadOp";}; }; +// Turning an eoBinOp into an eoQuadOp is generic: +template +class eoQuad2BinOp: public eoBinOp +{ +public: + // Ctor, from an eoQuadOp + eoQuad2BinOp(eoQuadOp & _quadOp) : quadOp(_quadOp) {} + + // Operator() simply calls embedded quadOp operator() with dummy second arg + void operator()(EOT & _eo1, const EOT & _eo2) + { + EOT eoTmp = _eo2; // a copy that can be modified + // if the embedded eoQuadOp is not symmetrical, + // the result might be biased - hence the flip ... + if (eo::rng.flip(0.5)) + quadOp(_eo1, eoTmp); // both are modified - that's all + else + quadOp(eoTmp, _eo1); // both are modified - that's all + } + +private: + eoQuadOp & quadOp; +}; // some forward declarations diff --git a/eo/src/eoPop.h b/eo/src/eoPop.h index cfb6b981..31b76c80 100644 --- a/eo/src/eoPop.h +++ b/eo/src/eoPop.h @@ -79,15 +79,24 @@ class eoPop: public vector, public eoObject, public eoPersistent } }; - /** SAME Initialization task than init. ctor, but is NOT a constructor + /** appends random guys at end of pop. + Can be used to initialize it pop is empty @param _popSize total population size @param _chromInit Initialization routine, produces EO's, needs to be an eoInit */ - void append( unsigned _popSize, eoInit& _chromInit ) + void append( unsigned _newPopSize, eoInit& _chromInit ) { - resize(size()+_popSize); // adjust the size - for ( unsigned i = 0; i < _popSize; i++ ) + unsigned oldSize = size(); + if (_newPopSize < oldSize) + { + throw runtime_error("New size smaller than old size in pop.append"); + return; + } + if (_newPopSize == oldSize) + return; + resize(_newPopSize); // adjust the size + for ( unsigned i = oldSize; i < _popSize; i++ ) { _chromInit(operator[](i)); } diff --git a/eo/src/eoVariableLength.h b/eo/src/eoVariableLength.h index 6cd823f3..83889208 100644 --- a/eo/src/eoVariableLength.h +++ b/eo/src/eoVariableLength.h @@ -27,21 +27,34 @@ #ifndef _eoVariableLength_h #define _eoVariableLength_h -#include +#include /** - Base class for variable length chromosomes. Derives from EO and list, + Base class for variable length chromosomes. Derives from EO and vector, redirects the smaller than operator to EO (fitness based comparison), and implements the virtual functions printOn() and readFrom() */ template -class eoVariableLength : public EO, public std::list +class eoVariableLength : public EO, public std::vector { public : typedef GeneType AtomType; - typedef std::list ContainerType; + typedef std::vector ContainerType; + + // default ctor + eoVariableLength(unsigned size = 0, GeneType value = GeneType()) : EO(), std::vector(size, value) + {} + + // we can't have a Ctor from a vector, it would create ambiguity + // with the copy Ctor + void value(std::vector _v) + { + resize(_v.size()); + copy(_v.begin(), _v.end(), begin()); + invalidate(); + } /// printing... void printOn(ostream& os) const @@ -51,7 +64,7 @@ class eoVariableLength : public EO, public std::list os << size() << ' '; - std::copy(begin(), end(), ostream_iterator(os)); + std::copy(begin(), end(), ostream_iterator(os, " ")); } /// reading... @@ -62,14 +75,14 @@ class eoVariableLength : public EO, public std::list unsigned sz; is >> sz; - resize(0); + resize(sz); unsigned i; - unsigned gene; for (i = 0; i < sz; ++i) { - is >> gene; - push_back(gene); + AtomType atom; + is >> atom; + operator[](i) = atom; } } @@ -81,7 +94,7 @@ class eoVariableLength : public EO, public std::list }; -/// to avoid conflicts between EO::operator< and vector::operator< +/// to avoid conflicts between EO::operator< and vector::operator< template bool operator<(const eoVariableLength& _eo1, const eoVariableLength& _eo2) { diff --git a/eo/src/eoVariableLengthCrossover.h b/eo/src/eoVariableLengthCrossover.h new file mode 100644 index 00000000..20d07395 --- /dev/null +++ b/eo/src/eoVariableLengthCrossover.h @@ -0,0 +1,294 @@ +// -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*- + +//----------------------------------------------------------------------------- +// eoVariableLengthCrossover.h +// (c) GeNeura Team, 2000 - EEAAX 1999 - 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: todos@geneura.ugr.es, http://geneura.ugr.es + Marc.Schoenauer@polytechnique.fr + mak@dhi.dk + */ +//----------------------------------------------------------------------------- + +#ifndef _eoVariableLengthCrossover_h +#define _eoVariableLengthCrossover_h + +#include +#include +#include +#include + +/** + Base classes for generic crossovers on variable length chromosomes. + +Basically, they exchange genes - we need some matching information to apply +atom crossover +*/ + +//* A helper class for choosing which genes to exchange +template +class eoAtomExchange : public eoBF +{ +public: + // a function to initlialize - to be called before every crossover + virtual void randomize(unsigned int, unsigned int){} +}; + +//* Uniform crossover - well, not really for FixedLength +template +class eoUniformAtomExchange: public eoAtomExchange +{ +public: + eoUniformAtomExchange(double _rate=0.5):rate(_rate){} + + // randomize: fill the mask: the exchange will be simulated first + // to see if sizes are OK, so it must be repeatable + void randomize(unsigned _size1, unsigned _size2) + { + mask.resize(_size1 + _size2); + for (unsigned i=0; i<_size1+_size2; i++) + mask[i]=eo::rng.flip(rate); + } + + // the operator() simply returns the mask booleans in turn + bool operator()(unsigned _i, Atom & ) + { + return mask[_i]; + } +private: + double rate; + vector mask; +}; + + +/** Exchange Crossover using an AtomExchange + */ + +template +class eoVlAtomExchangeQuadOp : public eoGenericQuadOp +{ +public : + + typedef typename EOT::AtomType AtomType; + + // default ctor: requires bounds on number of genes + a rate + eoVlAtomExchangeQuadOp(unsigned _Min, unsigned _Max, + eoAtomExchange& _atomExchange): + Min(_Min), Max(_Max), atomExchange(_atomExchange) {} + + bool operator()(EOT & _eo1, EOT & _eo2) + { + EOT tmp1, tmp2; // empty individuals + unsigned index=0; + // main loop: until sizes are OK, do only simulated exchange + unsigned i, i1, i2; + do { + // "initialize the AtomExchange + atomExchange.randomize(_eo1.size(), _eo2.size()); + // simulate crossover + i1=i2=0; + for (i=0; i<_eo1.size(); i++) + { + if (atomExchange(i, _eo1[i])) + i1++; + else + i2++; + } + for (i=0; i<_eo2.size(); i++) + { + if (atomExchange(i, _eo2[i])) + i2++; + else + i1++; + } + index++; + } while ( ( (i1Max) || (i2>Max) ) + && (index<10000) ); + if (index >= 10000) + { + cout << "Warning: impossible to generate individual of the right size in 10000 trials\n"; + return false; + } + // here we know we have the right sizes: do the actual exchange + for (i=0; i<_eo1.size(); i++) + { + if (atomExchange(i, _eo1[i])) + tmp1.push_back(_eo1[i]); + else + tmp2.push_back(_eo1[i]); + } + for (i=0; i<_eo2.size(); i++) + { + if (atomExchange(i, _eo2[i])) + tmp2.push_back(_eo2[i]); + else + tmp1.push_back(_eo2[i]); + } + // and put everything back in place + _eo1.swap(tmp1); + _eo2.swap(tmp2); + return true; // should we test that? Yes, but no time now + } +private: + unsigned Min, Max; + eoAtomExchange & atomExchange; +}; + + + + +/** Direct Uniform Exchange of genes (obsolete, already :-) + +A very primitive version, that does no verification at all!!! +NEEDS to be improved - but no time now :-((( +Especially, if both guys have maximal size, it will take a lot of time +to generate 2 offspring that both are not oversized!!! +Also, we should first check for identical atoms, and copy them to the +offspring, and only after that exchange the other ones (Radcliffe's RRR). + */ +template +class eoVlUniformQuadOp : public eoGenericQuadOp +{ +public : + + typedef typename EOT::AtomType AtomType; + + // default ctor: requires bounds on number of genes + a rate + eoVlUniformQuadOp(unsigned _Min, unsigned _Max, double _rate=0.5) : + Min(_Min), Max(_Max), rate(_rate) {} + + bool operator()(EOT & _eo1, EOT & _eo2) + { + unsigned i; + EOT tmp1, tmp2; + unsigned index=0; + do { + for (i=0; i<_eo1.size(); i++) + { + if (eo::rng.flip(rate)) + tmp1.push_back(_eo1[i]); + else + tmp2.push_back(_eo1[i]); + // here we should look for _eo1[i] inside _eo2 and erase it if found! + } + for (i=0; i<_eo2.size(); i++) + { + if (eo::rng.flip(rate)) + tmp1.push_back(_eo2[i]); + else + tmp2.push_back(_eo2[i]); + } + index++; + } while ( ( (tmp1.size()Max) || (tmp2.size()>Max) ) + && (index<10000) ); + if (index >= 10000) + { + cout << "Warning: impossible to generate individual of the right size in 10000 trials\n"; + return false; + } + + _eo1.swap(tmp1); + _eo2.swap(tmp2); + return true; // should we test that? + } +private: + unsigned Min, Max; + double rate; +}; + + +/** Direct Uniform Exchange of genes for Variable Length, BINARY version + +A very primitive version, that does no verification at all!!! +NEEDS to be improved - but no time now :-((( +Especially, if both guys have maximal size, it will take some time +to generate even 1 offspring that is not oversized!!! +Also, we should first check for identical atoms, and copy them to the +offspring, and only after that exchange the other ones (Radcliffe's RRR). + */ +template +class eoVlUniformBinOp : public eoGenericBinOp +{ +public : + + typedef typename EOT::AtomType AtomType; + + // default ctor: requires bounds on number of genes + a rate + eoVlUniformBinOp(unsigned _Min, unsigned _Max, double _rate=0.5) : + Min(_Min), Max(_Max), rate(_rate) {} + + bool operator()(EOT & _eo1, const EOT & _eo2) + { + unsigned i; + EOT tmp1; + bool tmpIsOne=true, tmpIsTwo=true; + unsigned index=0; + do { + for (i=0; i<_eo1.size(); i++) + { + if (eo::rng.flip(rate)) + { + tmp1.push_back(_eo1[i]); + tmpIsTwo = false; + } + else + tmpIsOne=false; + // we should look for _eo1[i] inside _eo2 and erase it there if found! + } + for (i=0; i<_eo2.size(); i++) + { + if (! eo::rng.flip(rate)) + { + tmp1.push_back(_eo2[i]); + tmpIsOne = false; + } + else + tmpIsTwo = false; + } + index++; + } while ( ( (tmp1.size()Max) ) + && (index<10000) ); + // this while condition is not optimal, as it may take some time + if (index >= 10000) + { + cout << "Warning: impossible to generate individual of the right size in 10000 trials\n"; + return false; + } + + _eo1.swap(tmp1); + if (tmpIsTwo) + { + // _eo1.fitness(_eo2.fitness()); NO FITNESS EXISTS HERE! + return false; + } + if (tmpIsOne) // already has the right fitness + { // WRONG: NO FITNESS EXISTS HERE! + return false; + } + return true; // there were some modifications... + } + +private: + unsigned Min, Max; + double rate; +}; + + + +#endif diff --git a/eo/src/eoVariableLengthMutation.h b/eo/src/eoVariableLengthMutation.h new file mode 100644 index 00000000..a23f0b88 --- /dev/null +++ b/eo/src/eoVariableLengthMutation.h @@ -0,0 +1,190 @@ +// -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*- + +//----------------------------------------------------------------------------- +// eoVariableLengthMutation.h +// (c) GeNeura Team, 2000 - EEAAX 1999 - 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: todos@geneura.ugr.es, http://geneura.ugr.es + Marc.Schoenauer@polytechnique.fr + mak@dhi.dk + */ +//----------------------------------------------------------------------------- + +#ifndef _eoVariableLengthMutation_h +#define _eoVariableLengthMutation_h + +#include +#include +#include + +/** + Base classes for generic mutations on variable length chromosomes. + +THey all require a generic mutation for their simple genes +*/ + +/** THis ones applies its atomic mutation to all the genes + */ +template +class eoVlAllMutation : public eoGenericMonOp +{ +public : + + typedef typename EOT::AtomType AtomType; + + // default ctor: requires an Atom mutation + eoVlAllMutation(eoGenericMonOp & _atomMutation) : + atomMutation(_atomMutation) {} + + bool operator()(EOT & _eo) + { + bool modified=false; + for (unsigned i=0; i<_eo.size(); i++) + { + if (atomMutation(_eo[i])) + modified = true; + } + return modified; + } +private: + eoGenericMonOp & atomMutation; +}; + +/** This ones applies its atomic mutation to a fixed + number of genes (1 by default) + */ +template +class eoVlKMutation : public eoGenericMonOp +{ +public : + + typedef typename EOT::AtomType AtomType; + + // default ctor: requires an Atom mutation + eoVlKMutation(eoGenericMonOp & _atomMutation, unsigned _nb=1) : + nb(_nb), atomMutation(_atomMutation) {} + + bool operator()(EOT & _eo) + { + bool modified=false; + for (unsigned k=0; k & atomMutation; +}; + +/** Addition of a gene + Is inserted at a random position - so can be applied to both + order-dependent and order-independent + */ +template +class eoVlAddMutation : public eoGenericMonOp +{ +public : + + typedef typename EOT::AtomType AtomType; + + /** default ctor + + * @param nMax max number of atoms + * @param _atomInit an Atom initializer + */ + eoVlAddMutation(unsigned _nMax, eoInit & _atomInit) : + nMax(_nMax), atomInit(_atomInit) {} + + bool operator()(EOT & _eo) + { + if (_eo.size() >= nMax) + return false; // unmodifed + AtomType atom; + atomInit(atom); + unsigned pos = rng.random(_eo.size()+1); + _eo.insert(_eo.begin()+pos, atom); + return true; + } +private: + unsigned nMax; + eoInit & atomInit; +}; + +//* A helper class for choosing which site to delete +template +class eoGeneDelChooser : public eoUF +{}; + +//* Unifirm choice of gene to delete +template +class eoUniformGeneChooser: public eoGeneDelChooser +{ +public: + eoUniformGeneChooser(){} + unsigned operator()(EOT & _eo) + { + return eo::rng.random(_eo.size()); + } +}; + +/** Deletion of a gene + By default at a random position, but a "chooser" can be specified + can of course be applied to both order-dependent and order-independent + */ +template +class eoVlDelMutation : public eoGenericMonOp +{ +public : + + typedef typename EOT::AtomType AtomType; + + /** ctor with an external gene chooser + + * @param nMin min number of atoms t oleave in the individual + * @param _geneChooser an eoGeneCHooser to choose which one to delete + */ + eoVlDelMutation(unsigned _nMin, eoGeneDelChooser & _chooser) : + nMin(_nMin), uChooser(), chooser(_chooser) {} + + /** ctor with unifirm gebe chooser + + * @param nMin min number of atoms t oleave in the individual + */ + eoVlDelMutation(unsigned _nMin) : + nMin(_nMin), uChooser(), chooser(uChooser) {} + + bool operator()(EOT & _eo) + { + if (_eo.size() <= nMin) + return false; // unmodifed + unsigned pos = chooser(_eo); + _eo.erase(_eo.begin()+pos); + return true; + } +private: + unsigned nMin; + eoUniformGeneChooser uChooser; + eoGeneDelChooser & chooser; +}; + + + +#endif