From 7bbdd173078cf7acbd35c2f1075ec8767dca103a Mon Sep 17 00:00:00 2001 From: evomarc Date: Tue, 4 Sep 2001 08:35:22 +0000 Subject: [PATCH] Added many template files, and totally modified the comments in most other. This was when preparing Evonet Summer School - though it finally was not used there! --- eo/tutorial/Templates/Makefile.tmpl | 25 ++ eo/tutorial/Templates/README | 125 +++++++ eo/tutorial/Templates/binCrossover.tmpl | 62 ++-- eo/tutorial/Templates/continue.tmpl | 45 ++- eo/tutorial/Templates/create.sh | 13 + eo/tutorial/Templates/eoMyStruct.tmpl | 78 +++++ eo/tutorial/Templates/eoMyStructEA.cpp | 321 ++++++++++++++++++ eo/tutorial/Templates/evalFunc.tmpl | 65 ++++ eo/tutorial/Templates/init.tmpl | 57 ++++ .../lessOffspringExternalSelectorGenOp.tmpl | 13 +- .../lessOffspringSameSelectorGenOp.tmpl | 17 +- eo/tutorial/Templates/moreOffspringGenOp.tmpl | 17 +- eo/tutorial/Templates/mutation.tmpl | 56 +-- eo/tutorial/Templates/quadCrossover.tmpl | 57 ++-- 14 files changed, 855 insertions(+), 96 deletions(-) create mode 100644 eo/tutorial/Templates/Makefile.tmpl create mode 100644 eo/tutorial/Templates/README create mode 100755 eo/tutorial/Templates/create.sh create mode 100644 eo/tutorial/Templates/eoMyStruct.tmpl create mode 100644 eo/tutorial/Templates/eoMyStructEA.cpp create mode 100644 eo/tutorial/Templates/evalFunc.tmpl create mode 100644 eo/tutorial/Templates/init.tmpl diff --git a/eo/tutorial/Templates/Makefile.tmpl b/eo/tutorial/Templates/Makefile.tmpl new file mode 100644 index 000000000..9975023ca --- /dev/null +++ b/eo/tutorial/Templates/Makefile.tmpl @@ -0,0 +1,25 @@ +# sample makefile for building an EA evolving a new genotype + +.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 + + +# START eventually modify the name of EO dir +DIR_EO = ../../src +# END eventually modify the name of EO dir + +LIB_EO = $(DIR_EO)/utils/libeoutils.a $(DIR_EO)/libeo.a + +ALL = eoMyStructEA + +eoMyStructEA : eoMyStructEA.o + c++ -g -o $@ eoMyStructEA.o ../../src/utils/libeoutils.a ../../src/libeo.a -lm + +tar : ; tar czvf climat.tgz *.h *.cpp Makefile + +all : $(ALL) + +clean : ; /bin/rm *.o $(ALL) + + diff --git a/eo/tutorial/Templates/README b/eo/tutorial/Templates/README new file mode 100644 index 000000000..9ef2dde88 --- /dev/null +++ b/eo/tutorial/Templates/README @@ -0,0 +1,125 @@ +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). + +At the moment, only algorithms involving a scalar fitness (double) +are implemented (see test dir for Pareto optimization of multiple- +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 + +It is assumed in the following that you have read the first part of +the tutorial (Lessons 1 to 4). + +Creating the algorithm for your genotype +---------------------------------------- +In what follows, we will suppose that you want to evolve some data +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 +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) + +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) + +2- cd to the tutorial/Templates dir + +3- run the helper script create.sh with the following arguments + create.sh Appli APPLICATION + +4- cd to the APPLICATION dir. You should see there the following +files: + 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 + +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). + +Note: If your APPLICATION dir is in the tutorial dir, you don't need +to modify Makefile. + +6- Compile eoAppliEA.cpp: + + % make + +7- Run the resulting program: + + % eoAppliEA + +The default output is one line per generation with the generation +number, the number of evaluations performed, the best and average +fitnesses in the population. +The algorithm stops by default after 100 generations. + +8- Customize the parameters: copy eoAppliEA.status into +e.g. eoAppliEA.param, edit eoAppliEA.param (uncomment the lines you +want to become active), and run + + % eoAppliEA @eoAppliEA.param + +(see the Lesson 4 of the tutorial for more details now). + +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 +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. + +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 +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. + +To add another operator, you have to create another class by mimicking +what has been done for the first operator. +For instance, let's suppose you want to create another mutation. + +* duplicate the code for eoAppliMutation class +* in the second version, change the class name (eoAppliMutation) into +another name (let's say eoAppliBetterMutation) - you must change the +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 +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); + +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! diff --git a/eo/tutorial/Templates/binCrossover.tmpl b/eo/tutorial/Templates/binCrossover.tmpl index b90729b29..5adabe688 100644 --- a/eo/tutorial/Templates/binCrossover.tmpl +++ b/eo/tutorial/Templates/binCrossover.tmpl @@ -1,54 +1,70 @@ /** -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*- -The above line is usefulin Emacs-like editors +The above line is useful in Emacs-like editors */ /* Template for simple binary crossover operators ============================================== -Binary crossover operators modify the first parent only, +Binary crossover operators modify the first genotype only, based on the second */ -#ifndef eoMyDerivedBinOp_H -#define eoMyDerivedBinOp_H +#ifndef eoMyStructBinCrossover_H +#define eoMyStructBinCrossover_H #include /** - Always write a comment in this format before class definition - if you want the class to be documented by Doxygen -*/ -template -class eoMyDerivedBinOp: public eoBinOp + * Always write a comment in this format before class definition + * if you want the class to be documented by Doxygen + * + * THere is NO ASSUMPTION on the class GenoypeT. + * In particular, it does not need to derive from EO + */ +template +class eoMyStructBinCrossover: public eoBinOp { public: /** - * (Default) Constructor. + * Ctor - no requirement */ - eoMyDerivedBinOp(paramType _anyParameter) : - anyParameter(_anyParameter) {} +// START eventually add or modify the anyVariable argument + eoMyStructBinCrossover() + // eoMyStructBinCrossover( varType _anyVariable) : anyVariable(_anyVariable) +// END eventually add or modify the anyVariable argument + { + // START Code of Ctor of an eoMyStructEvalFunc object + // END Code of Ctor of an eoMyStructEvalFunc object + } /// The class name. Used to display statistics - string className() const { return "eoMyDerivedBinOp"; } + string className() const { return "eoMyStructBinCrossover"; } /** - * eoBin crossover - modifies first parent only - * @param Indi1 The first parent - * @param Indi2 The second parent - const + * binCrossover - modifies first genotype only + * @param _genotype1 The first genotype + * @param _genotype2 The second genotype - const */ - bool operator()(Indi& Indi1, const Indi& Indi2) + bool operator()(GenotypeT & _genotype1, const GenotypeT & _genotype2) { - // do whatever needs to be done - // if Indi1 has been modified - return true; - // otherwise - // return false; + // START code for crossover of _genotype1 and _genotype2 objects + + /** Requirement + * if _genotype1 has been modified + * return true; + * otherwise + * return false; + */ + + // END code for crossover of _genotype1 and _genotype2 objects } private: - paramType anyParameter +// START Private data of an eoMyStructBinCrossover object + // varType anyVariable; // for example ... +// END Private data of an eoMyStructBinCrossover object }; #endif diff --git a/eo/tutorial/Templates/continue.tmpl b/eo/tutorial/Templates/continue.tmpl index 746bfba6e..2ec5a7be8 100644 --- a/eo/tutorial/Templates/continue.tmpl +++ b/eo/tutorial/Templates/continue.tmpl @@ -8,38 +8,57 @@ Template for continuator in EO, i.e. stopping conditions for EO algorithms ========================================================================== */ -#ifndef _eoMyContinue_h -#define _eoMyContinue_h +#ifndef _eoMyStructContinue_h +#define _eoMyStructContinue_h -#include +// include the base definition of eoContinue +#include /** - Always write a comment in this format before class definition - if you want the class to be documented by Doxygen -*/ + * Always write a comment in this format before class definition + * if you want the class to be documented by Doxygen + * + * ATTENTION, class EOT *must* derive from EO, as operator() will + * be called with an eoPop + */ template< class EOT> -class eoMyContinue: public eoContinue { +class eoMyStructContinue: public eoContinue { public: - /// Ctor - eoMyContinue( paramType _anyParameter) : - anyParameter(_anyParameter) {} + /** + * Ctor - no requirement + */ +// START eventually add or modify the anyVariable argument + eoMyStructContinue() + // eoMyStructBinCrossover( varType _anyVariable) : anyVariable(_anyVariable) +// END eventually add or modify the anyVariable argument + { + // START Code of Ctor of an eoMyStructEvalFunc object + // END Code of Ctor of an eoMyStructEvalFunc object + } /** Returns false when you want to stop + * + * @param _pop an eoPop */ virtual bool operator() ( const eoPop& _pop ) { - bool stopCondition = ... ; // compute the stopping condition + bool stopCondition ; // to store the stopping condition + // START Code of computation of stopping condition + // stopCondition = blablabla + // END Code of computation of stopping condition if (stopCondition) // the algo will stop upon return FALSE { - cout << "STOP in eoMyContinue: blablabla \n"; + cout << "STOP in eoMyStructContinue \n"; return false; } return true; // == do not stop } private: - paramType anyParameter +// START Private data of an eoMyStructContinue object + // varType anyVariable; // for example ... +// END Private data of an eoMyStructContinue object }; #endif diff --git a/eo/tutorial/Templates/create.sh b/eo/tutorial/Templates/create.sh new file mode 100755 index 000000000..f834a31e3 --- /dev/null +++ b/eo/tutorial/Templates/create.sh @@ -0,0 +1,13 @@ +#! /bin/tcsh -f +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 + diff --git a/eo/tutorial/Templates/eoMyStruct.tmpl b/eo/tutorial/Templates/eoMyStruct.tmpl new file mode 100644 index 000000000..b33c30f3a --- /dev/null +++ b/eo/tutorial/Templates/eoMyStruct.tmpl @@ -0,0 +1,78 @@ +/** -*- 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 +================================================ +*/ + +#ifndef _eoMyStruct_h +#define _eoMyStruct_h + +/** + * Always write a comment in this format before class definition + * if you want the class to be documented by Doxygen + + * Note that you MUST derive your structure from EO + * but you MAY use some other already prepared class in the hierarchy + * like eoVector for instance, if you handle a vector of something.... + + * If you create a structure from scratch, + * the only thing you need to provide are + * a default constructor + * IO routines printOn and readFrom + * + * Note that operator<< and operator>> are defined at EO level + * using these routines + */ +template< class FitT> +class eoMyStruct: public EO { +public: + /** Ctor: you MUST provide a default ctor. + * though such individuals will generally be processed + * by some eoInit object + */ + eoMyStruct() + { + // START Code of default Ctor of an eoMyStruct object + // END Code of default Ctor of an eoMyStruct object + } + + + /** printing... */ + void printOn(ostream& os) const + { + // START Code of default output + + /** HINTS + * in EO we systematically write the sizes of things before the things + * so readFrom is easier to code (see below) + */ + + // END Code of default output + } + + /** reading... + * of course, your readFrom must be able to read what printOn writes!!! + */ + void readFrom(istream& is) + { + // START Code of input + + /** HINTS + * remember the eoMyStruct object will come from the default ctor + * this is why having the sizes written out is useful + */ + + // END Code of input + } + +private: // put all data here + // START Private data of an eoMyStruct object + // END Private data of an eoMyStruct object +}; + +#endif + diff --git a/eo/tutorial/Templates/eoMyStructEA.cpp b/eo/tutorial/Templates/eoMyStructEA.cpp new file mode 100644 index 000000000..8b03560f3 --- /dev/null +++ b/eo/tutorial/Templates/eoMyStructEA.cpp @@ -0,0 +1,321 @@ +#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 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" + +/** 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 +//*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* + + +// 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 + + ///// FIRST, problem or representation dependent stuff + ////////////////////////////////////////////////////// + + ////////////////////////////////////////////// + // the genotype - through a genotype initializer + +//*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* +// START read parameters (if any) and create the initializer directly + + // As far as memory management is concerned, the parameters + // AND the values are owned by the parser (handled through references) + + // example of parameter reading using the most compact syntax + // varType var = parser.createParam(varType defaultValue, + // string keyword, + // string comment, + // char shortKeyword, + // string section,).value(); + + // an unsigned parameter + unsigned sampleUnsigned = parser.createParam(unsigned(10), "anUnsigned", "An unsigned parameter",'V', "Representation").value(); + + // a double parameter + double sampleDouble = parser.createParam(0.3, "aDouble", "A double parameter", 's', "Representation" ).value(); + + // some real bounds: [-1,1]x[-1,1] by default + eoRealVectorBounds & sampleBounds = parser.createParam(eoRealVectorBounds(2,-1,1), "someBounds", "Bounds of some real variables", 'B', "Representation").value(); +// END read parameters (if any) and create the initializer directly +//*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* + +//*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* +// START Modify definitions of objects by eventually add parameters + + /** HINTS + * + * The following declare variables that are objects defined + * in the customized files. + * You shoudl only modify the arguments passed onto their constructors + * ("varType _anyVariable") in their definition + * + * and you can optionally uncomment and modify the lines commented between + * /* and */ + + // the initializer: will be used in make_pop + //////////////////// + eoMyStructInit init/* (varType _anyVariable) */; + + // The fitness + ////////////// + eoMyStructEvalFunc plainEval/* (varType _anyVariable) */; + // turn that object into an evaluation counter + eoEvalFuncCounter eval(plainEval); + + ///////////////////////////// + // 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 + eoMyStructQuadCrossover cross1/* (varType _anyVariable) */; + // its relative rate in the combination + double cross1Rate = parser.createParam(1.0, "cross1Rate", "Relative rate for crossover 1", '1', "Variation Operators").value(); + // and the creation of the combined operator with this one + eoPropCombinedQuadOp propXover(cross1, cross1Rate); + + // 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 + eoMyStructSecondCrossover cross2(varType _anyVariable); + double cross2Rate = parser.createParam(1.0, "cross2Rate", "Relative rate for crossover 2", '2', "Variation Operators").value(); + propXover.add(cross2, cross2Rate); + */ + // if you want some gentle output, the last one shoudl be like + // propXover.add(crossXXX, 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 + eoMyStructMutation mut1/* (varType _anyVariable) */; + // 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(mut1, mut1Rate); + + // 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 + eoMyStructSecondMutation mut2(varType _anyVariable); + double mut2Rate = parser.createParam(1.0, "mut2Rate", "Relative rate for mutation 2", '2', "Variation Operators").value(); + propMutation.add(mut2, mut2Rate); + */ + // if you want some gentle output, the last one shoudl be like + // propMutation.add(mutXXX, 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 * cross = new eoProportionalOp ; + state.storeFunctor(cross); + eoQuadOp *ptQuad = new eoQuadCloneOp; + state.storeFunctor(ptQuad); + cross->add(propXover, pCrossParam.value()); // crossover, with proba pcross + cross->add(*ptQuad, 1-pCrossParam.value()); // nothing, with proba 1-pcross + + // now the sequential + eoSequentialOp *op = new eoSequentialOp; + state.storeFunctor(op); + op->add(*cross, 1.0); // always do combined crossover + op->add(propMutation, pMutParam.value()); // then mutation, with proba pmut + + // that's it! (beware op is a pointer - for lazy cut-and-paste reasons! + + // end of operator definition + //////////////////////////// + + //// 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/evalFunc.tmpl b/eo/tutorial/Templates/evalFunc.tmpl new file mode 100644 index 000000000..c2c7fdd86 --- /dev/null +++ b/eo/tutorial/Templates/evalFunc.tmpl @@ -0,0 +1,65 @@ +/** -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*- + +The above line is usefulin Emacs-like editors + */ + +/* +Template for continuator in EO, i.e. stopping conditions for EO algorithms +========================================================================== +*/ + +#ifndef _eoMyStructEvalFunc_h +#define _eoMyStructEvalFunc_h + +// include whatever general include you need +#include +#include + +// include the base definition of eoEvalFunc +#include "eoEvalFunc.h" + +/** + Always write a comment in this format before class definition + if you want the class to be documented by Doxygen +*/ +template +class eoMyStructEvalFunc : public eoEvalFunc +{ +public: + /// Ctor - no requirement +// START eventually add or modify the anyVariable argument + eoMyStructEvalFunc() + // eoMyStructEvalFunc( varType _anyVariable) : anyVariable(_anyVariable) +// END eventually add or modify the anyVariable argument + { + // START Code of Ctor of an eoMyStructEvalFunc object + // END Code of Ctor of an eoMyStructEvalFunc object + } + + /** Actually compute the fitness + * + * @param EOT & _eo the EO object to evaluate + * it should stay templatized to be usable + * with any fitness type + */ + void operator()(EOT & _eo) + { + // test for invalid to avoid recomputing fitness of unmodified individuals + if (_eo.invalid()) + { + double fit; // to hold fitness value + // START Code of computation of fitness of the eoMyStruct object + // fit = blablabla + // END Code of computation of fitness of the eoMyStruct object + _eo.fitness(fit); + } + } + +private: +// START Private data of an eoMyStructEvalFunc object + // varType anyVariable; // for example ... +// END Private data of an eoMyStructEvalFunc object +}; + + +#endif diff --git a/eo/tutorial/Templates/init.tmpl b/eo/tutorial/Templates/init.tmpl new file mode 100644 index 000000000..96d45b3ac --- /dev/null +++ b/eo/tutorial/Templates/init.tmpl @@ -0,0 +1,57 @@ +/** -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*- + +The above line is usefulin Emacs-like editors + */ + +/* +Template for EO objects initialization in EO +============================================ +*/ + +#ifndef _eoMyStructInit_h +#define _eoMyStructInit_h + +// include the base definition of eoInit +#include + +/** + * Always write a comment in this format before class definition + * if you want the class to be documented by Doxygen + * + * There is NO ASSUMPTION on the class GenoypeT. + * In particular, it does not need to derive from EO (e.g. to initialize + * atoms of an eoVector you will need an eoInit) + */ +template +class eoMyStructInit: public eoInit { +public: + /// Ctor - no requirement +// START eventually add or modify the anyVariable argument + eoMyStructInit() + // eoMyStructInit( varType _anyVariable) : anyVariable(_anyVariable) +// END eventually add or modify the anyVariable argument + { + // START Code of Ctor of an eoMyStructInit object + // END Code of Ctor of an eoMyStructInit object + } + + + /** initialize a genotype + * + * @param _genotype generally a genotype that has been default-constructed + * whatever it contains will be lost + */ + void operator()(GenotypeT & _genotype) + { + // START Code of random initialization of an eoMyStruct object + // END Code of random initialization of an eoMyStruct object + } + +private: +// START Private data of an eoMyStructInit object + // varType anyVariable; // for example ... +// END Private data of an eoMyStructInit object +}; + +#endif + diff --git a/eo/tutorial/Templates/lessOffspringExternalSelectorGenOp.tmpl b/eo/tutorial/Templates/lessOffspringExternalSelectorGenOp.tmpl index 11ce2b534..9a0c3c426 100644 --- a/eo/tutorial/Templates/lessOffspringExternalSelectorGenOp.tmpl +++ b/eo/tutorial/Templates/lessOffspringExternalSelectorGenOp.tmpl @@ -19,11 +19,14 @@ Second version, get parents using an external eoSelectOne #include /** - Always write a comment in this format before class definition - if you want the class to be documented by Doxygen -*/ -template -class eoLessOffspringExternalSelectorGenOp: public eoGenOp + * Always write a comment in this format before class definition + * if you want the class to be documented by Doxygen + * + * ATTENTION, class EOT *must* derive from EO, as method invalidate() + * must be called if the genotypes of the indis is modified + */ +template +class eoLessOffspringExternalSelectorGenOp: public eoGenOp { public: /** diff --git a/eo/tutorial/Templates/lessOffspringSameSelectorGenOp.tmpl b/eo/tutorial/Templates/lessOffspringSameSelectorGenOp.tmpl index 826ebf37b..c0790f93c 100644 --- a/eo/tutorial/Templates/lessOffspringSameSelectorGenOp.tmpl +++ b/eo/tutorial/Templates/lessOffspringSameSelectorGenOp.tmpl @@ -10,7 +10,7 @@ i.e. that takes any number of parents and generates any number of offspring a GenOp that creates less offspring than there are parents -First version, get parents from populator using the ibbedded select() method +First version, get parents from populator using the imbedded select() method */ #ifndef eoLessOffspringSameSelectorGenOp_H @@ -19,11 +19,14 @@ First version, get parents from populator using the ibbedded select() method #include /** - Always write a comment in this format before class definition - if you want the class to be documented by Doxygen -*/ -template -class eoLessOffspringSameSelectorGenOp: public eoGenOp + * Always write a comment in this format before class definition + * if you want the class to be documented by Doxygen + * + * ATTENTION, class EOT *must* derive from EO, as method invalidate() + * must be called if the genotypes of the indis is modified + */ +template +class eoLessOffspringSameSelectorGenOp: public eoGenOp { public: /** @@ -70,4 +73,4 @@ private: paramType anyParameter }; -#endif \ No newline at end of file +#endif diff --git a/eo/tutorial/Templates/moreOffspringGenOp.tmpl b/eo/tutorial/Templates/moreOffspringGenOp.tmpl index 9753ded61..c8644276a 100644 --- a/eo/tutorial/Templates/moreOffspringGenOp.tmpl +++ b/eo/tutorial/Templates/moreOffspringGenOp.tmpl @@ -18,11 +18,14 @@ than there are parents #include /** - Always write a comment in this format before class definition - if you want the class to be documented by Doxygen -*/ -template -class eoMoreOffspringGenOp: public eoGenOp + * Always write a comment in this format before class definition + * if you want the class to be documented by Doxygen + * + * ATTENTION, class EOT *must* derive from EO, as method invalidate() + * must be called if the genotypes of the indis is modified + */ +template +class eoMoreOffspringGenOp: public eoGenOp { public: /** @@ -53,7 +56,7 @@ public: // points to the last that has already been treated // apply operator to the parents (modifying them AND generating - // new individuals ofs1, ofs2, ..., ofsN + // new individuals ofs1, ofs2, ..., ofsN ++_plop; // advance before each insertion _plop.insert(ofs1); ... @@ -71,4 +74,4 @@ private: paramType anyParameter }; -#endif \ No newline at end of file +#endif diff --git a/eo/tutorial/Templates/mutation.tmpl b/eo/tutorial/Templates/mutation.tmpl index 41e62e887..2b66be2cd 100644 --- a/eo/tutorial/Templates/mutation.tmpl +++ b/eo/tutorial/Templates/mutation.tmpl @@ -1,6 +1,6 @@ /** -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*- -The above line is usefulin Emacs-like editors +The above line is useful in Emacs-like editors */ /* @@ -8,44 +8,60 @@ Template for simple mutation operators ====================================== */ -#ifndef eoMyDerivedMonOp_H -#define eoMyDerivedMonOp_H +#ifndef eoMyStructMutation_H +#define eoMyStructMutation_H #include /** - Always write a comment in this format before class definition - if you want the class to be documented by Doxygen -*/ -template -class eoMyDerivedMonOp: public eoMonOp + * Always write a comment in this format before class definition + * if you want the class to be documented by Doxygen + * + * THere is NO ASSUMPTION on the class GenoypeT. + * In particular, it does not need to derive from EO + */ +template +class eoMyStructMutation: public eoMonOp { public: /** - * (Default) Constructor. + * Ctor - no requirement */ - eoMyDerivedMonOp(paramType _anyParameter) : - anyParameter(_anyParameter) {} +// START eventually add or modify the anyVariable argument + eoMyStructMutation() + // eoMyStructMutation( varType _anyVariable) : anyVariable(_anyVariable) +// END eventually add or modify the anyVariable argument + { + // START Code of Ctor of an eoMyStructEvalFunc object + // END Code of Ctor of an eoMyStructEvalFunc object + } /// The class name. Used to display statistics - string className() const { return "eoMyDerivedMonOp"; } + string className() const { return "eoMyStructMutation"; } /** * modifies the parent - * @param Indi The parent + * @param _genotype The parent genotype (will be modified) */ - bool operator()(Indi& Indi) + bool operator()(GenotypeT & _genotype) { - // do whatever needs to be done - // if Indi has been modified - return true; - // otherwise - // return false; + // START code for mutation of the _genotype object + + /** Requirement + * if _genotype has been modified + * return true; + * otherwise + * return false; + */ + + // END code for mutation of the _genotype object } private: - paramType anyParameter +// START Private data of an eoMyStructMutation object + // varType anyVariable; // for example ... +// END Private data of an eoMyStructMutation object }; #endif diff --git a/eo/tutorial/Templates/quadCrossover.tmpl b/eo/tutorial/Templates/quadCrossover.tmpl index f66f1ea8c..355543127 100644 --- a/eo/tutorial/Templates/quadCrossover.tmpl +++ b/eo/tutorial/Templates/quadCrossover.tmpl @@ -7,48 +7,63 @@ The above line is usefulin Emacs-like editors Template for simple quadratic crossover operators ================================================= -Quadratic crossover operators modify the both parents +Quadratic crossover operators modify the both genotypes */ -#ifndef eoMyDerivedQuadOp_H -#define eoMyDerivedQuadOp_H +#ifndef eoMyStructQuadCrossover_H +#define eoMyStructQuadCrossover_H #include /** - Always write a comment in this format before class definition - if you want the class to be documented by Doxygen -*/ -template -class eoMyDerivedQuadOp: public eoQuadOp + * Always write a comment in this format before class definition + * if you want the class to be documented by Doxygen + * + * THere is NO ASSUMPTION on the class GenoypeT. + * In particular, it does not need to derive from EO + */ +template +class eoMyStructQuadCrossover: public eoQuadOp { public: /** - * (Default) Constructor. + * Ctor - no requirement */ - eoMyDerivedQuadOp(paramType _anyParameter) : - anyParameter(_anyParameter) {} +// START eventually add or modify the anyVariable argument + eoMyStructQuadCrossover() + // eoMyStructQuadCrossover( varType _anyVariable) : anyVariable(_anyVariable) +// END eventually add or modify the anyVariable argument + { + // START Code of Ctor of an eoMyStructEvalFunc object + // END Code of Ctor of an eoMyStructEvalFunc object + } /// The class name. Used to display statistics - string className() const { return "eoMyDerivedQuadOp"; } + string className() const { return "eoMyStructQuadCrossover"; } /** * eoQuad crossover - modifies both parents - * @param Indi1 The first parent - * @param Indi2 The second parent + * @param _genotype1 The first parent + * @param _genotype2 The second parent */ - bool operator()(Indi& Indi1, Indi& Indi2) + bool operator()(GenotypeT& _genotype1, GenotypeT & _genotype2) { - // do whatever needs to be done + // START code for crossover of _genotype1 and _genotype2 objects - // if at least one individual has been modified - no way to distinguish - return true; - // otherwise - // return false; + /** Requirement + * if at least one genotype has been modified - no way to distinguish + * return true; + * otherwise + * return false; + */ + + // END code for crossover of _genotype1 and _genotype2 objects } private: - paramType anyParameter +// START Private data of an eoMyStructQuadCrossover object + // varType anyVariable; // for example ... +// END Private data of an eoMyStructQuadCrossover object }; #endif