diff --git a/eo/tutorial/Templates/Makefile.tmpl b/eo/tutorial/Templates/Makefile.tmpl index 9975023ca..f91d23089 100644 --- a/eo/tutorial/Templates/Makefile.tmpl +++ b/eo/tutorial/Templates/Makefile.tmpl @@ -2,7 +2,7 @@ .cpp: ; c++ -DPACKAGE=\"eo\" -DVERSION=\"0.9.1\" -I. -I../../src -Wall -g -o $@ $*.cpp ../../src/libeo.a ../../src/utils/libeoutils.a -.cpp.o: ; c++ -DPACKAGE=\"eo\" -DVERSION=\"0.9.1\" -DF2C -I. -I../../src -I../Points -I./Sol -I./util -Wall -g -c $*.cpp +.cpp.o: ; c++ -DPACKAGE=\"eo\" -DVERSION=\"0.9.1\" -DF2C -I. -I../../src -I./util -Wall -g -c $*.cpp # START eventually modify the name of EO dir @@ -11,12 +11,12 @@ DIR_EO = ../../src LIB_EO = $(DIR_EO)/utils/libeoutils.a $(DIR_EO)/libeo.a -ALL = eoMyStructEA +ALL = MyStructEA -eoMyStructEA : eoMyStructEA.o - c++ -g -o $@ eoMyStructEA.o ../../src/utils/libeoutils.a ../../src/libeo.a -lm +MyStructEA : MyStructEA.o + c++ -g -o $@ MyStructEA.o ../../src/utils/libeoutils.a ../../src/libeo.a -lm -tar : ; tar czvf climat.tgz *.h *.cpp Makefile +tar : ; tar czvf MyStruct.tgz *.h *.cpp Makefile all : $(ALL) diff --git a/eo/tutorial/Templates/MyStructEA.cpp b/eo/tutorial/Templates/MyStructEA.cpp new file mode 100644 index 000000000..9d58f81d0 --- /dev/null +++ b/eo/tutorial/Templates/MyStructEA.cpp @@ -0,0 +1,184 @@ +/** -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*- + +The above line is usefulin Emacs-like editors + */ + +/* +Template for creating a new representation in EO +================================================ + +This is the template main file. +It includes all other files that have been generated by the script create.sh +so it is the only file to compile. + +In case you want to build up a separate library for your new Evolving Object, +you'll need some work - follow what's done in the src/ga dir, used in the +main file BitEA in tutorial/Lesson4 dir. +Or you can wait until we do it :-) +*/ + +// Miscilaneous include and declaration +#include +using namespace std; + +// eo general include +#include "eo" +// the real bounds (not yet in general eo include) +#include "utils/eoRealVectorBounds.h" + +// include here whatever specific files for your representation +// Basically, this should include at least the following + +/** definition of representation: + * class eoMyStruct MUST derive from EO for some fitness + */ +#include "eoMyStruct.h" + +/** definition of initilizqtion: + * class eoMyStructInit MUST derive from eoInit + */ +#include "eoMyStructInit.h" + +/** definition of evaluation: + * class eoMyStructEvalFunc MUST derive from eoEvalFunc + * and should test for validity before doing any computation + * see tutorial/Templates/evalFunc.tmpl + */ +#include "eoMyStructEvalFunc.h" + +// GENOTYPE eoMyStruct ***MUST*** be templatized over the fitness + +//*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* +// START fitness type: double or eoMaximizingFitness if you are maximizing +// eoMinimizingFitness if you are minimizing +typedef eoMyStruct Indi; // ***MUST*** derive from EO +// END fitness type +//*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* + +// create an initializer +#include "make_genotype_MyStruct.h" +eoInit & make_genotype(eoParameterLoader& _parser, eoState&_state, Indi _eo) +{ + return do_make_genotype(_parser, _state, _eo); +} + +// and the variation operaotrs +#include "make_op_MyStruct.h" +eoGenOp& make_op(eoParameterLoader& _parser, eoState& _state, eoInit& _init) +{ + return do_make_op(_parser, _state, _init); +} + +// Use existing modules to define representation independent routines +// These are parser-based definitions of objects + +// how to initialize the population +// it IS representation independent if an eoInit is given +#include +eoPop& make_pop(eoParser& _parser, eoState& _state, eoInit & _init) +{ + return do_make_pop(_parser, _state, _init); +} + +// the stopping criterion +#include +eoContinue& make_continue(eoParser& _parser, eoState& _state, eoEvalFuncCounter & _eval) +{ + return do_make_continue(_parser, _state, _eval); +} + +// outputs (stats, population dumps, ...) +#include +eoCheckPoint& make_checkpoint(eoParameterLoader& _parser, eoState& _state, eoEvalFuncCounter& _eval, eoContinue& _continue) +{ + return do_make_checkpoint(_parser, _state, _eval, _continue); +} + +// evolution engine (selection and replacement) +#include +eoAlgo& make_algo_scalar(eoParameterLoader& _parser, eoState& _state, eoEvalFunc& _eval, eoContinue& _continue, eoGenOp& _op) +{ + return do_make_algo_scalar(_parser, _state, _eval, _continue, _op); +} + +// simple call to the algo. stays there for consistency reasons +// no template for that one +#include +// the instanciating fitnesses +#include +void run_ea(eoAlgo& _ga, eoPop& _pop) +{ + do_run(_ga, _pop); +} + +// checks for help demand, and writes the status file +// and make_help; in libutils +void make_help(eoParser & _parser); + +// now use all of the above, + representation dependent things +int main(int argc, char* argv[]) +{ + + try + { + eoParser parser(argc, argv); // for user-parameter reading + + eoState state; // keeps all things allocated + + // The fitness + ////////////// + eoMyStructEvalFunc plainEval/* (varType _anyVariable) */; + // turn that object into an evaluation counter + eoEvalFuncCounter eval(plainEval); + + // the genotype - through a genotype initializer + eoInit& init = make_genotype(parser, state, Indi()); + + // Build the variation operator (any seq/prop construct) + eoGenOp& op = make_op(parser, state, init); + + + //// Now the representation-independent things + // + // YOU SHOULD NOT NEED TO MODIFY ANYTHING BEYOND THIS POINT + // unless you want to add specific statistics to the checkpoint + ////////////////////////////////////////////// + + // initialize the population + // yes, this is representation indepedent once you have an eoInit + eoPop& pop = make_pop(parser, state, init); + + // stopping criteria + eoContinue & term = make_continue(parser, state, eval); + // output + eoCheckPoint & checkpoint = make_checkpoint(parser, state, eval, term); + // algorithm (need the operator!) + eoAlgo& ga = make_algo_scalar(parser, state, eval, checkpoint, op); + + ///// End of construction of the algorithm + + ///////////////////////////////////////// + // to be called AFTER all parameters have been read!!! + make_help(parser); + + //// GO + /////// + // evaluate intial population AFTER help and status in case it takes time + apply(eval, pop); + // if you want to print it out +// cout << "Initial Population\n"; +// pop.sortedPrintOn(cout); +// cout << endl; + + run_ea(ga, pop); // run the ga + + cout << "Final Population\n"; + pop.sortedPrintOn(cout); + cout << endl; + + } + catch(exception& e) + { + cout << e.what() << endl; + } +} diff --git a/eo/tutorial/Templates/README b/eo/tutorial/Templates/README index 9ef2dde88..e1284acb3 100644 --- a/eo/tutorial/Templates/README +++ b/eo/tutorial/Templates/README @@ -1,7 +1,7 @@ This directory contains sample files that should make it easy to create an EO algorithm to evolve any type of structure (EO comes with two examples, bitstrings and vector of real variables, -so you'll need this qs soon as you want to evolve something else). +so you'll need this as soon as you want to evolve something else). At the moment, only algorithms involving a scalar fitness (double) are implemented (see test dir for Pareto optimization of multiple- @@ -9,7 +9,7 @@ objective fitness - or be patient :-) This file will help you to build the same algorithm than the ones in the Lesson4 of the tutorial, but with YOUR genotype instead of -*bitstrings or vector +bitstrings or vector It is assumed in the following that you have read the first part of the tutorial (Lessons 1 to 4). @@ -21,18 +21,19 @@ structure, and that you have enough programming skills to be able to write C code for its random initilialization, its crossover, its mutation and the computation of its fitness. -The helper script create.sh will create for you the files you need -from teh examples in tutorial/Templates dir, and all you'll have to do +The helper script * create.sh * will create for you the files you need +from the samples in tutorial/Templates dir, and all you'll have to do is to include the actual code where indicated in those files (between keywords START and END). First, let's choose a name: let's call the new EO class eoAppli. -All newly created classes will be named eoApplicationXXX (in the file -eoApplicationXXX) +All newly created classes will be named eoAppliXXX (in the file +eoAppliXXX) -1- create a directory for your application in the tutorial dir, "parallel" to -the LessonX dirs (though any name can do, of course, we will suppose -its full name, from the / root dir, is APPLICATION in what follows) +1- choose a directory name for your application in the tutorial dir, +"parallel" to the LessonX dirs (though any name can do, of course, we +will suppose its full name, from the / root dir, is APPLICATION in +what follows) 2- cd to the tutorial/Templates dir @@ -41,25 +42,30 @@ its full name, from the / root dir, is APPLICATION in what follows) 4- cd to the APPLICATION dir. You should see there the following files: + AppliEA.cpp the main file, includes all other, to be compiled Makefile with default target eoAppliEA eoAppli.h class eoAppli, FitT = template fitness - eoAppliEA.cpp the main file, includes all other, to be compiled eoAppliEvalFunc.h class for the computation of fotness eoAppliInit.h class for genotype initlialization eoAppliMutation.h class for mutation eoAppliQuadCrossover.h class for (quadratic) crossover + make_genotype_Appli.h helper function that create the initializer + make_op_Appli.h helper function that creates the variatin operators Note: You can go directly to step 6 and 7: you'll get a lot of warnings, but will be able to run an EA that does nothing! -5- Edit those files one after the other and add you code where -indicated (look for keywords START and END and modify code in -between). +5- Edit those files to suit your needs. The minimal addition you'll need +to make are + in eoAppli.h define your genotype + in eoAppliInit.h define the initialization of one genotype + in eoAppliMutation.h define the mutation of one genotype + in eoAppliQuadCrossover.h define the crossover of 2 genotypes -Note: If your APPLICATION dir is in the tutorial dir, you don't need -to modify Makefile. +HINT: look for keywords START and END and modify code in between. -6- Compile eoAppliEA.cpp: +6- Compile eoAppliEA.cpp. If your APPLICATION dir is in the tutorial +dir, you don't need to modify Makefile. Just type in % make @@ -83,24 +89,22 @@ want to become active), and run HINTS ----- -1- All new classes you will create probably require some parameters in -the constructor, and some (if not all) thoses parameters are likele to -be user parameter: you can either read them in the main file (as is -done in the sample eoAppliEA.cpp) or pass the eoParser to the +1- If some new classes you create require some user parameter, you can +either read them in the file where they are created (e.g. +make_op_Appli.h for variation operators), or pass the eoParser to the constructor of the class, and read the parameter from the parser. 2- If you stick to privacy for the data in your EO class, you will probably need to write accessors to those data, as well as some public -methods to modify them. +methods to modify them, as soon as some other methods need them too. -3- The sample eoAppliEA.cpp supposes that you ony have one crossover -and one mutation operator. However, the code for multiple operators -is there: you can have for instance 2 crossover operators, and choose +3- The sample make_op_Appli.h supposes that you ony have one crossover +and one mutation operator. However, the code for multiple operators is +there: you can have for instance 2 crossover operators, and choose among them according to relative weights (proportional choice) - same -for mutation. Look at the operator section in eoAppliEA.cpp -In particular, the user parameter mutationRate is totally useless for -a single operator, and is there only as a provision for using more -than one. +for mutation. Look at the operator section in eoAppliEA.cpp In +particular, the user parameters cross1Rate and mut1Rate are totally +useless for a single operator. To add another operator, you have to create another class by mimicking what has been done for the first operator. @@ -113,13 +117,16 @@ name in the class declaration, in the constructor and in the className() method. * in the new eoAppliBetterMutation class, change the code for the operator() - and eventually the code for the constructor. -* in the eoAppliEA.cpp file, in the mutation section, uncomment the +* in the make_op_Appli.h file, in the mutation section, uncomment the lines - eoMyStructSecondMutation mut2(varType _anyVariable); - double mut2Rate = parser.createParam(1.0, "mut2Rate", "Relative rate for mutation 2", '2', "Variation Operators").value(); - propMutation.add(mut2, mut2Rate); + mut = new eoAppliSecondMutation(varType _anyVariable); + _state.storeFunctor(mut); + double mut2Rate = _parser.createParam(1.0, "mut2Rate", "Relative rate for mutation 2", '2', "Variation Operators").value(); + propMutation.add(*mut, mut2Rate); and change the name of the class from eoAppliSecondMutation to your name eoAppliBetterMutation (you can also change the keyword from mut2Rate to something more meaningful like BetterMutationRate). You're done! + +In case of problem: Marc.Schoenauer@inria.fr diff --git a/eo/tutorial/Templates/create.sh b/eo/tutorial/Templates/create.sh index f834a31e3..e8e5056cf 100755 --- a/eo/tutorial/Templates/create.sh +++ b/eo/tutorial/Templates/create.sh @@ -3,11 +3,17 @@ if ($#argv < 2) then echo Usage $argv[0] ApplicationName TargetDir exit endif -sed s/eoMyStruct/eo$1/g eoMyStruct.tmpl > $2/eo$1.h -sed s/eoMyStruct/eo$1/g init.tmpl > $2/eo$1Init.h -sed s/eoMyStruct/eo$1/g evalFunc.tmpl > $2/eo$1EvalFunc.h -sed s/eoMyStruct/eo$1/g mutation.tmpl > $2/eo$1Mutation.h -sed s/eoMyStruct/eo$1/g quadCrossover.tmpl > $2/eo$1QuadCrossover.h -sed s/eoMyStruct/eo$1/g eoMyStructEA.cpp > $2/eo$1EA.cpp -sed s/eoMyStruct/eo$1/g Makefile.tmpl > $2/Makefile +if (! -e $2) then + mkdir $2 +endif +sed s/MyStruct/$1/g eoMyStruct.tmpl > $2/eo$1.h +sed s/MyStruct/$1/g init.tmpl > $2/eo$1Init.h +sed s/MyStruct/$1/g evalFunc.tmpl > $2/eo$1EvalFunc.h +sed s/MyStruct/$1/g mutation.tmpl > $2/eo$1Mutation.h +sed s/MyStruct/$1/g quadCrossover.tmpl > $2/eo$1QuadCrossover.h +sed s/MyStruct/$1/g MyStructEA.cpp > $2/$1EA.cpp +sed s/MyStruct/$1/g make_genotype_MyStruct.h > $2/make_genotype_$1.h +sed s/MyStruct/$1/g make_op_MyStruct.h > $2/make_op_$1.h +sed s/MyStruct/$1/g Makefile.tmpl > $2/Makefile + diff --git a/eo/tutorial/Templates/evalFunc.tmpl b/eo/tutorial/Templates/evalFunc.tmpl index c2c7fdd86..b8c9f1ed7 100644 --- a/eo/tutorial/Templates/evalFunc.tmpl +++ b/eo/tutorial/Templates/evalFunc.tmpl @@ -4,7 +4,7 @@ The above line is usefulin Emacs-like editors */ /* -Template for continuator in EO, i.e. stopping conditions for EO algorithms +Template for evaluator in EO, a functor that computes the fitness of an EO ========================================================================== */ diff --git a/eo/tutorial/Templates/make_genotype_MyStruct.h b/eo/tutorial/Templates/make_genotype_MyStruct.h new file mode 100644 index 000000000..a5194f9b0 --- /dev/null +++ b/eo/tutorial/Templates/make_genotype_MyStruct.h @@ -0,0 +1,73 @@ +// -*- 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 + + +/* + * This fuction does the create an eoInit + * + * It could be here tempatized only on the fitness, as it can be used + * to evolve structures with any fitness. + * However, for consistency reasons, it was finally chosen, as in + * the rest of EO, to templatize by the full EOT, as this eventually + * allows to choose the type of genotype at run time (see in es dir) + * + * It returns an eoInit that 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. + * + * WARNING: that last argument will generally be the result of calling + * the default ctor of EOT, resulting in most cases in an EOT + * that is ***not properly initialized*** +*/ + +template +eoInit & do_make_genotype(eoParameterLoader& _parser, eoState& _state, EOT) +{ + // read any useful parameter here from the parser + // the param itself will belong to the parser (as far as memory is concerned) + + // paramType & param = _parser.createParam(deafultValue, "Keyword", "Comment to appear in help and status", 'c',"Section of status file").value(); + + // Then built the initializer - a pointer, stored in the eoState + eoInit* init = new eoMyStructInit /* ( param ) */ ; + // store in state + _state.storeFunctor(init); + // and return a reference + return *init; +} + +#endif diff --git a/eo/tutorial/Templates/make_op_MyStruct.h b/eo/tutorial/Templates/make_op_MyStruct.h new file mode 100644 index 000000000..8b43d17bb --- /dev/null +++ b/eo/tutorial/Templates/make_op_MyStruct.h @@ -0,0 +1,210 @@ +// -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*- + +//----------------------------------------------------------------------------- +// make_op_MyStruct.h +// (c) Marc Schoenauer, Maarten Keijzer 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_MyStruct_h +#define _make_op_MyStruct_h + +// the operators +#include +#include +#include +#include +// combinations of simple eoOps (eoMonOp and eoQuadOp) +#include + +/** definition of mutation: + * class eoMyStructMonop MUST derive from eoMonOp + */ +#include "eoMyStructMutation.h" + +/** definition of crossover (either as eoBinOp (2->1) or eoQuadOp (2->2): + * class eoMyStructBinCrossover MUST derive from eoBinOp + * OR + * class eoMyStructQuadCrossover MUST derive from eoQuadOp + */ +// #include "eoMyStructBinOp.h" +// OR +#include "eoMyStructQuadCrossover.h" + + // also need the parser and state includes +#include +#include + + +/////////////////// variation operators /////////////// +// canonical (crossover + mutation) only at the moment // + +/* + * This function builds the operators that will be applied to the eoMyStruct + * + * It uses a parser (to get user parameters), a state (to store the memory) + * the last parameter is an eoInit: if some operator needs some info + * about the genotypes, the init has it all (e.g. bounds, ...) + * Simply do + * EOT myEO; + * _init(myEO); + * and myEO is then an ACTUAL object + * + * As usual, the template is the complete EOT even though only the fitness + * is actually templatized here: the following only applies to eoMyStruct +*/ + +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! + + + ///////////////////////////// + // Variation operators + //////////////////////////// + // read crossover and mutations, combine each in a proportional Op + // and create the eoGenOp that calls crossover at rate pCross + // then mutation with rate pMut + + // the crossovers + ///////////////// + + // here we can have eoQuadOp (2->2) only - no time for the eoBinOp case + + // you can have more than one - combined in a proportional way + + // first, define the crossover objects and read their rates from the parser + + // A first crossover + eoQuadOp *cross = new eoMyStructQuadCrossover /* (varType _anyVariable) */; + // store in the state + _state.storeFunctor(cross); + + // read its relative rate in the combination + double cross1Rate = _parser.createParam(1.0, "cross1Rate", "Relative rate for crossover 1", '1', "Variation Operators").value(); + + // and create the combined operator with this one + eoPropCombinedQuadOp *propXover = + new eoPropCombinedQuadOp(*cross, cross1Rate); + // and of course stor it in the state + _state.storeFunctor(propXover); + + + // Optional: A second(and third, and ...) crossover + // of course you must create the corresponding classes + // and all ***MUST*** derive from eoQuadOp + + /* Uncomment if necessary - and replicate as many time as you need + cross = new eoMyStructSecondCrossover(varType _anyVariable); + _state.storeFunctor(cross); + double cross2Rate = _parser.createParam(1.0, "cross2Rate", "Relative rate for crossover 2", '2', "Variation Operators").value(); + propXover.add(*cross, cross2Rate); + */ + // if you want some gentle output, the last one shoudl be like + // propXover.add(*cross, crossXXXRate, true); + + + // the mutation: same story + //////////////// + // you can have more than one - combined in a proportional way + + // for each mutation, + // - define the mutator object + // - read its rate from the parser + // - add it to the proportional combination + + // a first mutation + eoMonOp *mut = new eoMyStructMutation/* (varType _anyVariable) */; + _state.storeFunctor(mut); + // its relative rate in the combination + double mut1Rate = _parser.createParam(1.0, "mut1Rate", "Relative rate for mutation 1", '1', "Variation Operators").value(); + // and the creation of the combined operator with this one + eoPropCombinedMonOp *propMutation = new eoPropCombinedMonOp(*mut, mut1Rate); + _state.storeFunctor(propMutation); + + // Optional: A second(and third, and ...) mutation with their rates + // of course you must create the corresponding classes + // and all ***MUST*** derive from eoMonOp + + /* Uncomment if necessary - and replicate as many time as you need + mut = new eoMyStructSecondMutation(varType _anyVariable); + _state.storeFunctor(mut); + double mut2Rate = _parser.createParam(1.0, "mut2Rate", "Relative rate for mutation 2", '2', "Variation Operators").value(); + propMutation.add(*mut, mut2Rate); + */ + // if you want some gentle output, the last one shoudl be like + // propMutation.add(*mut, mutXXXRate, true); + + // end of crossover and mutation definitions + //////////////////////////////////////////// + +// END Modify definitions of objects by eventually add parameters +//*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* + +// from now on, you do not need to modify anything +// though you CAN add things to the checkpointing (see tutorial) + + // 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 + + // but of course you're free to use any smart combination you could think of + // especially, if you have to use eoBinOp rather than eoQuad Op youùll have + // to modify that part + + // First read the individual level parameters + eoValueParam& pCrossParam = _parser.createParam(0.6, "pCross", "Probability of Crossover", 'C', "Variation 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', "Variation Operators" ); + // minimum check + if ( (pMutParam.value() < 0) || (pMutParam.value() > 1) ) + throw runtime_error("Invalid pMut"); + + + // the crossover - with probability pCross + eoProportionalOp * propOp = new eoProportionalOp ; + _state.storeFunctor(propOp); + eoQuadOp *ptQuad = new eoQuadCloneOp; + _state.storeFunctor(ptQuad); + propOp->add(*propXover, pCrossParam.value()); // crossover, with proba pcross + propOp->add(*ptQuad, 1-pCrossParam.value()); // nothing, with proba 1-pcross + + // now the sequential + eoSequentialOp *op = new eoSequentialOp; + _state.storeFunctor(op); + op->add(*propOp, 1.0); // always do combined crossover + op->add(*propMutation, pMutParam.value()); // then mutation, with proba pmut + + // that's it - return a reference + return *op; +} +#endif