diff --git a/eo/src/ga/make_genotype.h b/eo/src/ga/make_genotype.h new file mode 100644 index 00000000..ce8270e1 --- /dev/null +++ b/eo/src/ga/make_genotype.h @@ -0,0 +1,68 @@ +// -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*- + +//----------------------------------------------------------------------------- +// make_genotype.h +// (c) Maarten Keijzer, Marc Schoenauer and GeNeura Team, 2001 +/* + 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 + mkeijzer@dhi.dk + */ +//----------------------------------------------------------------------------- + +#ifndef _make_genotype_h +#define _make_genotype_h + +#include +#include + // also need the parser and param includes +#include +#include + + +/////////////////// the bitstring //////////////// +/* + * This fuciont does the initialization of what's needed for a particular + * genotype (here, bitstrings). + * It is templatized ***olny on the fitness*** so it can be used to evolve + * bitstrings with any fitness. + * It is instanciated in ga/ga.cpp - and incorporated in the ga/libga.a + * + * It returns an eoInit > tha can later be used to initialize + * the population (see make_pop.h). + * + * It uses a parser (to get user parameters) and a state (to store the memory) + * the last argument is to disambiguate the call upon different instanciations. +*/ + +template +eoInit > & do_make_genotype(eoParameterLoader& _parser, eoState& _state, FitT) +{ + // for bitstring, only thing needed is the size + eoValueParam& chromSize = _parser.createParam(unsigned(10), "ChromSize", "The length of the bitstrings", 'n',"initialization"); + + // Then we can built a bitstring random initializer + // based on boolean_generator class (see utils/rnd_generator.h) + eoBooleanGenerator * gen = new eoBooleanGenerator; + _state.storeFunctor(gen); + eoInitFixedLength >* init = new eoInitFixedLength >(chromSize.value(), *gen); + // satore in state + _state.storeFunctor(init); + return *init; +} + +#endif diff --git a/eo/src/ga/make_op.h b/eo/src/ga/make_op.h new file mode 100644 index 00000000..05af2eb9 --- /dev/null +++ b/eo/src/ga/make_op.h @@ -0,0 +1,211 @@ +// -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*- + +//----------------------------------------------------------------------------- +// make_op.h +// (c) Maarten Keijzer, Marc Schoenauer and GeNeura Team, 2001 +/* + 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 + mkeijzer@dhi.dk + */ +//----------------------------------------------------------------------------- + +#ifndef _make_op_h +#define _make_op_h + +// the operators +#include +#include +#include +#include +// combinations of simple eoOps (eoMonOp and eoQuadOp) +#include + +// the specialized GA stuff +#include +#include + // also need the parser and param includes +#include +#include + + +/////////////////// bitstring operators /////////////// +// canonical (crossover + mutation) only at the moment // + +/* + * This function builds the operators that will be applied to the bitstrings + * + * It uses a parser (to get user parameters) and a state (to store the memory) + * the last argument is an individual, needed for 2 reasons + * it disambiguates the call after instanciations + * some operator might need some private information about the indis + * + * This is why the template is the complete EOT even though only the fitness + * is actually templatized here: the following only applies to bitstrings + * + * Note : the last parameter is an eoInit: if some operator needs some info + * about the gneotypes, the init has it all (e.g. bounds, ...) + * Simply do + * EOT myEO; + * _init(myEO); + * and myEO is then an ACTUAL object +*/ + +template +eoGenOp & do_make_op(eoParameterLoader& _parser, eoState& _state, eoInit& _init) +{ + // this is a temporary version, while Maarten codes the full tree-structured + // general operator input + // BTW we must leave that simple version available somehow, as it is the one + // that 90% people use! + eoValueParam& operatorParam = _parser.createParam(string("SGA"), "operator", "Description of the operator (SGA only now)", 'o', "Genetic Operators"); + + if (operatorParam.value() != string("SGA")) + throw runtime_error("Only SGA-like operator available roght now\n"); + + // now we read Pcross and Pmut, + // the relative weights for all crossovers -> proportional choice + // the relative weights for all mutations -> proportional choice + // and create the eoGenOp that is exactly + // crossover with pcross + mutation with pmut + + eoValueParam& pCrossParam = _parser.createParam(0.6, "pCross", "Probability of Crossover", 'C', "Genetic Operators" ); + // minimum check + if ( (pCrossParam.value() < 0) || (pCrossParam.value() > 1) ) + throw runtime_error("Invalid pCross"); + + eoValueParam& pMutParam = _parser.createParam(0.1, "pMut", "Probability of Mutation", 'M', "Genetic Operators" ); + // minimum check + if ( (pMutParam.value() < 0) || (pMutParam.value() > 1) ) + throw runtime_error("Invalid pMut"); + + // the crossovers + ///////////////// + // the parameters + eoValueParam& onePointRateParam = _parser.createParam(double(1.0), "onePointRate", "Relative rate for one point crossover", '1', "Genetic Operators" ); + // minimum check + if ( (onePointRateParam.value() < 0) ) + throw runtime_error("Invalid onePointRate"); + + eoValueParam& twoPointsRateParam = _parser.createParam(double(1.0), "twoPointRate", "Relative rate for two point crossover", '2', "Genetic Operators" ); + // minimum check + if ( (twoPointsRateParam.value() < 0) ) + throw runtime_error("Invalid twoPointsRate"); + + eoValueParam& uRateParam = _parser.createParam(double(2.0), "uRate", "Relative rate for uniform crossover", 'U', "Genetic Operators" ); + // minimum check + if ( (uRateParam.value() < 0) ) + throw runtime_error("Invalid uRate"); + + // minimum check + bool bCross = true; + if (onePointRateParam.value()+twoPointsRateParam.value()+uRateParam.value()==0) + { + cerr << "Warning: no crossover" << endl; + bCross = false; + } + + // Create the CombinedQuadOp + eoPropCombinedQuadOp *ptCombinedQuadOp = NULL; + eoQuadOp *ptQuad = NULL; + // 1-point crossover for bitstring + ptQuad = new eo1PtBitXover; + _state.storeFunctor(ptQuad); + ptCombinedQuadOp = new eoPropCombinedQuadOp(*ptQuad, onePointRateParam.value()); + + // uniform crossover for bitstring + ptQuad = new eoUBitXover; + _state.storeFunctor(ptQuad); + ptCombinedQuadOp->add(*ptQuad, uRateParam.value()); + + // 2-points xover + ptQuad = new eoNPtsBitXover; + _state.storeFunctor(ptQuad); + ptCombinedQuadOp->add(*ptQuad, twoPointsRateParam.value()); + + // don't forget to store the CombinedQuadOp + _state.storeFunctor(ptCombinedQuadOp); + + // the mutations + ///////////////// + // the parameters + eoValueParam & pMutPerBitParam = _parser.createParam(0.01, "pMutPerBit", "Probability of flipping 1 bit in bit-flip mutation", 'b', "Genetic Operators" ); + // minimum check + if ( (pMutPerBitParam.value() < 0) || (pMutPerBitParam.value() > 0.5) ) + throw runtime_error("Invalid pMutPerBit"); + + eoValueParam & bitFlipRateParam = _parser.createParam(0.01, "bitFlipRate", "Relative rate for bit-flip mutation", 's', "Genetic Operators" ); + // minimum check + if ( (bitFlipRateParam.value() < 0) ) + throw runtime_error("Invalid bitFlipRate"); + + eoValueParam & oneBitRateParam = _parser.createParam(0.01, "oneBitRate", "Relative rate for deterministic bit-flip mutation", 'd', "Genetic Operators" ); + // minimum check + if ( (oneBitRateParam.value() < 0) ) + throw runtime_error("Invalid oneBitRate"); + + // minimum check + bool bMut = true; + if (bitFlipRateParam.value()+oneBitRateParam.value()==0) + { + cerr << "Warning: no mutation" << endl; + bMut = false; + } + + // Create the CombinedMonOp + eoPropCombinedMonOp *ptCombinedMonOp = NULL; + eoMonOp *ptMon = NULL; + + // standard bit-flip mutation for bitstring + ptMon = new eoBitMutation(pMutPerBitParam.value()); + _state.storeFunctor(ptMon); + // create the CombinedMonOp + ptCombinedMonOp = new eoPropCombinedMonOp(*ptMon, bitFlipRateParam.value()); + + // mutate exactly 1 bit per individual + ptMon = new eoDetBitFlip; + _state.storeFunctor(ptMon); + ptCombinedMonOp->add(*ptMon, oneBitRateParam.value()); + + _state.storeFunctor(ptCombinedMonOp); + + // now build the eoGenOp: + // to simulate SGA (crossover with proba pCross + mutation with proba pMut + // we must construct + // a sequential combination of + // with proba 1, a proportional combination of + // a QuadCopy and our crossover + // with proba pMut, our mutation + + // the crossover - with probability pCross + eoProportionalOp * cross = new eoProportionalOp ; + _state.storeFunctor(cross); + ptQuad = new eoQuadCloneOp; + _state.storeFunctor(ptQuad); + cross->add(*ptCombinedQuadOp, pCrossParam.value()); // user crossover + cross->add(*ptQuad, 1-pCrossParam.value()); // clone operator + + // now the sequential + eoSequentialOp *op = new eoSequentialOp; + _state.storeFunctor(op); + op->add(*cross, 1.0); // always crossover (but clone with prob 1-pCross + op->add(*ptCombinedMonOp, pMutParam.value()); + + // that's it! + return *op; +} +#endif