diff --git a/eo/tutorial/Templates/MakeSimple.tmpl b/eo/tutorial/Templates/MakeSimple.tmpl new file mode 100644 index 00000000..188793f6 --- /dev/null +++ b/eo/tutorial/Templates/MakeSimple.tmpl @@ -0,0 +1,28 @@ +# sample makefile for building an EA evolving a new genotype + +# 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 + +.cpp: ; c++ -DPACKAGE=\"eo\" -DVERSION=\"0.9.3\" -I. -I$(DIR_EO) -Wall -g -o $@ $*.cpp $(LIB_EO) + +.cpp.o: ; c++ -DPACKAGE=\"eo\" -DVERSION=\"0.9.3\" -I. -I$(DIR_EO) -Wall -g -c $*.cpp + +# local sources +SOURCES = MyStructEA.cpp \ + eoMyStruct.h \ + eoMyStructEvalFunc.h \ + eoMyStructInit.h \ + eoMyStructMutation.h \ + eoMyStructQuadCrossover.h + +MyStructEA : MyStructEA.cpp + c++ -I. -I$(DIR_EO) -g -o $@ MyStructEA.cpp $(LIB_EO) -lm + +tar : ; tar czvf MyStruct.tgz *.h *.cpp Makefile + +clean : ; /bin/rm *.o MyStructEA + +########## local dependencies +MyStructEA : $(SOURCES) diff --git a/eo/tutorial/Templates/MyStructSEA.cpp b/eo/tutorial/Templates/MyStructSEA.cpp new file mode 100644 index 00000000..d4cc4801 --- /dev/null +++ b/eo/tutorial/Templates/MyStructSEA.cpp @@ -0,0 +1,252 @@ +/** -*- 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" + +/** definitions of operators: write as many classes as types of operators + * and include them here. In this simple example, + * one crossover (2->2) and one mutation (1->1) operators are used + */ +#include "eoMyStructQuadCrossover.h" +#include "eoMyStructMutation.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 eoMinimizingFitness MyFitT ; // type of fitness +// END fitness type +//*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* + +// Then define your EO objects using that fitness type +typedef eoMyStruct Indi; // ***MUST*** derive from EO + + +// Use existing modules to define representation independent routines + +// 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(eoParser& _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(eoParser& _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); + + // a genotype initializer + eoMyStructInit init; + // or, if you need some parameters, you might as well + // - write a constructor of the eoMyStructInit that uses a parser + // - call it from here: + // eoMyStructInit init(parser); + + + // Build the variation operator (any seq/prop construct) + // here, a simple example with only 1 crossover (2->2, a QuadOp) and + // one mutation, is given. + // Hints to have choice among multiple crossovers and mutations are given + + // A (first) crossover (possibly use the parser in its Ctor) + eoMyStructQuadCrossover cross /* (eoParser parser) */; + + // IF MORE THAN ONE: + + // read its relative rate in the combination +// double cross1Rate = parser.createParam(1.0, "cross1Rate", "Relative rate for crossover 1", '1', "Variation Operators").value(); + + // create the combined operator with the first one (rename it cross1 !!!) +// eoPropCombinedQuadOp cross(cross1, cross1Rate); + + // and as many as you want the following way: + // 1- write the new class by mimicking eoMyStructQuadCrossover.h + // 2- include that file here together with eoMyStructQuadCrossover above + // 3- uncomment and duplicate the following lines: + // +// eoMyStructSecondCrossover cross2(eoParser parser); +// double cross2Rate = parser.createParam(1.0, "cross2Rate", "Relative rate for crossover 2", '2', "Variation Operators").value(); +// cross.add(cross2, cross2Rate); + + // NOTE: if you want some gentle output, the last one shoudl be like + // cross.add(cross, crossXXXRate, true); + + /////////////// Same thing for MUTATION + + // a (first) mutation (possibly use the parser in its Ctor) + eoMyStructMutation mut /* (eoParser parser) */; + + // IF MORE THAN ONE: + + // read its relative rate in the combination +// double mut1Rate = parser.createParam(1.0, "mut1Rate", "Relative rate for mutation 1", '1', "Variation Operators").value(); + + // create the combined operator with the first one (rename it cross1 !!!) +// eoPropCombinedMonOp mut(mut1, mut1Rate); + + // and as many as you want the following way: + // 1- write the new class by mimicking eoMyStructMutation.h + // 2- include that file here together with eoMyStructMutation above + // 3- uncomment and duplicate the following lines: + // +// eoMyStructSecondMutation mut2(eoParser parser); +// double mut2Rate = parser.createParam(1.0, "mut2Rate", "Relative rate for mutation 2", '2', "Variation Operators").value(); +// mut.add(mut2, mut2Rate); + + // NOTE: if you want some gentle output, the last one shoudl be like + // mut.add(mut, mutXXXRate, true); + + // now encapsulate your crossover(s) and mutation(s) into an eoGeneralOp + // so you can fully benefit of the existing evolution engines + + // First read the individual level parameters + double pCross = parser.createParam(0.6, "pCross", "Probability of Crossover", 'C', "Variation Operators" ).value(); + // minimum check + if ( (pCross < 0) || (pCross > 1) ) + throw runtime_error("Invalid pCross"); + + double pMut = parser.createParam(0.1, "pMut", "Probability of Mutation", 'M', "Variation Operators" ).value(); + // minimum check + if ( (pMut < 0) || (pMut > 1) ) + throw runtime_error("Invalid pMut"); + + // now create the generalOp + eoSGAGenOp op(cross, pCross, mut, pMut); + + + //// 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; + } + return 0; +} diff --git a/eo/tutorial/Templates/createSimple b/eo/tutorial/Templates/createSimple new file mode 100755 index 00000000..a329bc5c --- /dev/null +++ b/eo/tutorial/Templates/createSimple @@ -0,0 +1,58 @@ +#! /bin/tcsh -f +if ($PWD:t != Templates) then + echo You must be in the Template dir to run that script + exit +endif + +if ($#argv < 1) then + echo "Usage $0 ApplicationName [TargetDirName]" + echo " will create ../TargetDirName if necessary" + echo " (default dir name = ApplicationName)," + echo " and will put there all files that are strictly necessary" + echo " to compile and run you Application from there" + exit +endif + +echo " " # we're going to do something + +if ($#argv == 1) then + set TargetDir = ../$1 +else + set TargetDir = ../$2 +endif + +if (! -e $TargetDir) then + mkdir $TargetDir +endif + +if ( (-f $TargetDir/eo$1.h) || (-f $TargetDir/eo$1Init.h) || (-f $TargetDir/eo$1EvalFunc.h) || (-f $TargetDir/eo$1Mutation.h) || (-f $TargetDir/eo$1QuadCrossover.h) || (-f $TargetDir/$1EA.cpp) || (-f $TargetDir/make_genotype_$1.h) || (-f $TargetDir/make_op_$1.h) ) then + echo WARNING: some files already exist there. + echo -n "Overwrite ALL (yes/no)? " + set REP = $< + if ($REP != "yes") then + echo Nothing done! + exit + endif +endif + +if (-f $TargetDir/Makefile) then + echo A Makefile already exists there. + echo I'm creating Makefile.$1. You'll have to merge them both, + echo OR to call make -f Makefile.$1 + set MakeName = Makefile.$1 +else + set MakeName = Makefile +endif + +echo Creating source files for application $1 in $TargetDir/ + +sed s/MyStruct/$1/g eoMyStruct.tmpl > $TargetDir/eo$1.h +sed s/MyStruct/$1/g init.tmpl > $TargetDir/eo$1Init.h +sed s/MyStruct/$1/g evalFunc.tmpl > $TargetDir/eo$1EvalFunc.h +sed s/MyStruct/$1/g mutation.tmpl > $TargetDir/eo$1Mutation.h +sed s/MyStruct/$1/g quadCrossover.tmpl > $TargetDir/eo$1QuadCrossover.h +sed s/MyStruct/$1/g MyStructSEA.cpp > $TargetDir/$1EA.cpp +sed s/MyStruct/$1/g MakeSimple.tmpl > $TargetDir/$MakeName + +echo Done! +