diff --git a/eo/tutorial/Lesson5/Makefile b/eo/tutorial/Lesson5/Makefile new file mode 100644 index 00000000..bc179fd2 --- /dev/null +++ b/eo/tutorial/Lesson5/Makefile @@ -0,0 +1,46 @@ +# sample makefile for building an EA evolving a new genotype + +.cpp: ; c++ -DPACKAGE=\"eo\" -DVERSION=\"0.9.3\" -I. -I../../src -Wall -g -o $@ $*.cpp ../../src/libeo.a ../../src/utils/libeoutils.a + +.cpp.o: ; c++ -DPACKAGE=\"eo\" -DVERSION=\"0.9.3\" -I. -I../../src -I./util -Wall -g -c $*.cpp + +# local sources +COMMON_SOURCES = eoOneMax.h \ + eoOneMaxEvalFunc.h \ + eoOneMaxInit.h \ + eoOneMaxMutation.h \ + eoOneMaxQuadCrossover.h \ + make_genotype_OneMax.h \ + make_op_OneMax.h + +NO_LIB_SOURCES = OneMaxEA.cpp + +LIB_SOURCES = OneMaxLibEA.cpp make_OneMax.cpp + + +SOURCES = $(COMMON_SOURCES) OneMaxEA.cpp OneMaxLibEA.cpp make_OneMax.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 = OneMaxEA OneMaxLibEA + +OneMaxEA : OneMaxEA.o + c++ -g -o $@ OneMaxEA.o ../../src/utils/libeoutils.a ../../src/libeo.a -lm + +OneMaxLibEA : OneMaxLibEA.o make_OneMax.o + c++ -g -o $@ OneMaxLibEA.o make_OneMax.o ../../src/utils/libeoutils.a ../../src/libeo.a -lm + +tar : ; tar czvf OneMax.tgz *.h *.cpp Makefile + +all : $(ALL) + +clean : ; /bin/rm *.o $(ALL) + +########## local dependencies +OneMaxEA.o : $(COMMON_SOURCES) OneMaxEA.cpp +OneMaxLibEA.o : $(COMMON_SOURCES) OneMaxLibEA.cpp +make_OneMax.o : make_OneMax.cpp eoOneMax.h diff --git a/eo/tutorial/Lesson5/OneMaxEA.cpp b/eo/tutorial/Lesson5/OneMaxEA.cpp new file mode 100644 index 00000000..1f3470f3 --- /dev/null +++ b/eo/tutorial/Lesson5/OneMaxEA.cpp @@ -0,0 +1,188 @@ +/** -*- 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 eoOneMax MUST derive from EO for some fitness + */ +#include "eoOneMax.h" + +/** definition of initilizqtion: + * class eoOneMaxInit MUST derive from eoInit + */ +#include "eoOneMaxInit.h" + +/** definition of evaluation: + * class eoOneMaxEvalFunc MUST derive from eoEvalFunc + * and should test for validity before doing any computation + * see tutorial/Templates/evalFunc.tmpl + */ +#include "eoOneMaxEvalFunc.h" + +// GENOTYPE eoOneMax ***MUST*** be templatized over the fitness + +//*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* +// START fitness type: double or eoMaximizingFitness if you are maximizing +// eoMinimizingFitness if you are minimizing +typedef eoMaximizingFitness MyFitT ; // type of fitness +// END fitness type +//*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* + +// Then define your EO objects using that fitness type +typedef eoOneMax Indi; // ***MUST*** derive from EO + +// create an initializer +#include "make_genotype_OneMax.h" +eoInit & make_genotype(eoParser& _parser, eoState&_state, Indi _eo) +{ + return do_make_genotype(_parser, _state, _eo); +} + +// and the variation operaotrs +#include "make_op_OneMax.h" +eoGenOp& make_op(eoParser& _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(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 + ////////////// + eoOneMaxEvalFunc 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; + } + return 0; +} diff --git a/eo/tutorial/Lesson5/OneMaxLibEA.cpp b/eo/tutorial/Lesson5/OneMaxLibEA.cpp new file mode 100644 index 00000000..42d25f92 --- /dev/null +++ b/eo/tutorial/Lesson5/OneMaxLibEA.cpp @@ -0,0 +1,162 @@ +/** -*- 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 for compiling after creating a +library. +See make_OneMax.cpp file. +*/ + +// 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 eoOneMax MUST derive from EO for some fitness + */ +#include "eoOneMax.h" + +/** definition of initilizqtion: + * class eoOneMaxInit MUST derive from eoInit + */ +#include "eoOneMaxInit.h" + +/** definition of evaluation: + * class eoOneMaxEvalFunc MUST derive from eoEvalFunc + * and should test for validity before doing any computation + * see tutorial/Templates/evalFunc.tmpl + */ +#include "eoOneMaxEvalFunc.h" + +// GENOTYPE eoOneMax ***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 eoOneMax Indi; // ***MUST*** derive from EO + +// create an initializer - done here and NOT in make_OneMax.cpp +// because it is NOT representation independent +#include "make_genotype_OneMax.h" +eoInit & make_genotype(eoParser& _parser, eoState&_state, Indi _eo) +{ + return do_make_genotype(_parser, _state, _eo); +} + +// same thing for the variation operaotrs +#include "make_op_OneMax.h" +eoGenOp& make_op(eoParser& _parser, eoState& _state, eoInit& _init) +{ + return do_make_op(_parser, _state, _init); +} + +// The representation independent routines are simply declared here + +// how to initialize the population +// it IS representation independent if an eoInit is given +eoPop& make_pop(eoParser& _parser, eoState& _state, eoInit & _init); + +// the stopping criterion +eoContinue& make_continue(eoParser& _parser, eoState& _state, eoEvalFuncCounter & _eval); + +// outputs (stats, population dumps, ...) +eoCheckPoint& make_checkpoint(eoParser& _parser, eoState& _state, eoEvalFuncCounter& _eval, eoContinue& _continue); + +// evolution engine (selection and replacement) +eoAlgo& make_algo_scalar(eoParser& _parser, eoState& _state, eoEvalFunc& _eval, eoContinue& _continue, eoGenOp& _op); + +// simple call to the algo. stays there for consistency reasons +// no template for that one +void run_ea(eoAlgo& _ga, eoPop& _pop); + +// checks for help demand, and writes the status file +// and make_help; in libutils - just a declaration, code in libeoutils.a +void make_help(eoParser & _parser); + +// now use all of the above, + representation dependent things +// from here on, no difference with eoOneMax.cpp +int main(int argc, char* argv[]) +{ + + try + { + eoParser parser(argc, argv); // for user-parameter reading + + eoState state; // keeps all things allocated + + // The fitness + ////////////// + eoOneMaxEvalFunc 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; + } + return 0; +} diff --git a/eo/tutorial/Lesson5/eoOneMax.h b/eo/tutorial/Lesson5/eoOneMax.h new file mode 100644 index 00000000..a85bb89f --- /dev/null +++ b/eo/tutorial/Lesson5/eoOneMax.h @@ -0,0 +1,111 @@ +/** -*- 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 _eoOneMax_h +#define _eoOneMax_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 eoOneMax: public EO { +public: + /** Ctor: you MUST provide a default ctor. + * though such individuals will generally be processed + * by some eoInit object + */ + eoOneMax() + { + // START Code of default Ctor of an eoOneMax object + // END Code of default Ctor of an eoOneMax object + } + + virtual ~eoOneMax() + { + // START Code of Destructor of an eoEASEAGenome object + // END Code of Destructor of an eoEASEAGenome object + } + + virtual string className() const { return "eoOneMax"; } + + /** printing... */ + void printOn(ostream& _os) const + { + // First write the fitness + EO::printOn(_os); + _os << ' '; + // 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) + */ + _os << b.size() << ' ' ; + for (unsigned i=0; i::readFrom(_is); + // START Code of input + + /** HINTS + * remember the eoOneMax object will come from the default ctor + * this is why having the sizes written out is useful + */ + unsigned s; + _is >> s; + b.resize(s); + for (unsigned i=0; i> bTmp; + b[i] = bTmp; + } + // END Code of input + } + + // accessing and setting values + void setB(vector & _b) + { + b=_b; + } + const vector & B() + { + return b; + } + +private: // put all data here + // START Private data of an eoOneMax object + std::vector b; + // END Private data of an eoOneMax object +}; + +#endif + diff --git a/eo/tutorial/Lesson5/eoOneMaxEvalFunc.h b/eo/tutorial/Lesson5/eoOneMaxEvalFunc.h new file mode 100644 index 00000000..b7f18746 --- /dev/null +++ b/eo/tutorial/Lesson5/eoOneMaxEvalFunc.h @@ -0,0 +1,68 @@ +/** -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*- + +The above line is usefulin Emacs-like editors + */ + +/* +Template for evaluator in EO, a functor that computes the fitness of an EO +========================================================================== +*/ + +#ifndef _eoOneMaxEvalFunc_h +#define _eoOneMaxEvalFunc_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 eoOneMaxEvalFunc : public eoEvalFunc +{ +public: + /// Ctor - no requirement +// START eventually add or modify the anyVariable argument + eoOneMaxEvalFunc() + // eoOneMaxEvalFunc( varType _anyVariable) : anyVariable(_anyVariable) +// END eventually add or modify the anyVariable argument + { + // START Code of Ctor of an eoOneMaxEvalFunc object + // END Code of Ctor of an eoOneMaxEvalFunc 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 eoOneMax object + const vector & b = _eo.B(); + fit = 0; + for (unsigned i=0; i + +/** + * 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 eoOneMaxInit: public eoInit { +public: + /// Ctor - no requirement +// START eventually add or modify the anyVariable argument +// eoOneMaxInit() + eoOneMaxInit( unsigned _vecSize) : vecSize(_vecSize) +// END eventually add or modify the anyVariable argument + { + // START Code of Ctor of an eoOneMaxInit object + // END Code of Ctor of an eoOneMaxInit 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 eoOneMax object + vector b(vecSize); + for (unsigned i=0; i + +/** + * 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 eoOneMaxMutation: public eoMonOp +{ +public: + /** + * Ctor - no requirement + */ +// START eventually add or modify the anyVariable argument + eoOneMaxMutation() + // eoOneMaxMutation( varType _anyVariable) : anyVariable(_anyVariable) +// END eventually add or modify the anyVariable argument + { + // START Code of Ctor of an eoOneMaxEvalFunc object + // END Code of Ctor of an eoOneMaxEvalFunc object + } + + /// The class name. Used to display statistics + string className() const { return "eoOneMaxMutation"; } + + /** + * modifies the parent + * @param _genotype The parent genotype (will be modified) + */ + bool operator()(GenotypeT & _genotype) + { + bool isModified; + // START code for mutation of the _genotype object + + /** Requirement + * if (_genotype has been modified) + * isModified = true; + * else + * isModified = false; + */ + return isModified; + // END code for mutation of the _genotype object + } + +private: +// START Private data of an eoOneMaxMutation object + // varType anyVariable; // for example ... +// END Private data of an eoOneMaxMutation object +}; + +#endif diff --git a/eo/tutorial/Lesson5/eoOneMaxQuadCrossover.h b/eo/tutorial/Lesson5/eoOneMaxQuadCrossover.h new file mode 100644 index 00000000..1a0c414f --- /dev/null +++ b/eo/tutorial/Lesson5/eoOneMaxQuadCrossover.h @@ -0,0 +1,70 @@ +/** -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*- + +The above line is usefulin Emacs-like editors + */ + +/* +Template for simple quadratic crossover operators +================================================= + +Quadratic crossover operators modify the both genotypes +*/ + +#ifndef eoOneMaxQuadCrossover_H +#define eoOneMaxQuadCrossover_H + +#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 + */ +template +class eoOneMaxQuadCrossover: public eoQuadOp +{ +public: + /** + * Ctor - no requirement + */ +// START eventually add or modify the anyVariable argument + eoOneMaxQuadCrossover() + // eoOneMaxQuadCrossover( varType _anyVariable) : anyVariable(_anyVariable) +// END eventually add or modify the anyVariable argument + { + // START Code of Ctor of an eoOneMaxEvalFunc object + // END Code of Ctor of an eoOneMaxEvalFunc object + } + + /// The class name. Used to display statistics + string className() const { return "eoOneMaxQuadCrossover"; } + + /** + * eoQuad crossover - modifies both parents + * @param _genotype1 The first parent + * @param _genotype2 The second parent + */ + bool operator()(GenotypeT& _genotype1, GenotypeT & _genotype2) + { + bool oneAtLeastIsModified; + // START code for crossover of _genotype1 and _genotype2 objects + + /** Requirement + * if (at least one genotype has been modified) // no way to distinguish + * oneAtLeastIsModified = true; + * else + * oneAtLeastIsModified = false; + */ + return oneAtLeastIsModified; + // END code for crossover of _genotype1 and _genotype2 objects + } + +private: +// START Private data of an eoOneMaxQuadCrossover object + // varType anyVariable; // for example ... +// END Private data of an eoOneMaxQuadCrossover object +}; + +#endif diff --git a/eo/tutorial/Lesson5/make_OneMax.cpp b/eo/tutorial/Lesson5/make_OneMax.cpp new file mode 100644 index 00000000..29fa78e6 --- /dev/null +++ b/eo/tutorial/Lesson5/make_OneMax.cpp @@ -0,0 +1,129 @@ +/** -*- 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 file that llows separate compilation of +everything that is representation independant (evolution engine and +general output) for an Evolutionary Algorithm with scalar fitness. + +It includes of course the definition of the genotype (eoOneMax.h) and +is written like the make_xxx.cpp files in dirs src/ga (for bitstrings) +and src/es (for real vectors). + +*/ + +// 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 eoOneMax MUST derive from EO for some fitness + */ +#include "eoOneMax.h" + +// create an initializer: this is NOT representation-independent +// and will be done in the main file +// However, should you decide to freeze that part, you could use the +// following (and remove it from the main file, of course!!!) +//------------------------------------------------------------------ +// #include "make_genotype_OneMax.h" +// eoInit> & make_genotype(eoParser& _parser, eoState&_state, eoOneMax _eo) +// { +// return do_make_genotype(_parser, _state, _eo); +// } + +// eoInit> & make_genotype(eoParser& _parser, eoState&_state, eoOneMax _eo) +// { +// return do_make_genotype(_parser, _state, _eo); +// } + +// same thing for the variation operaotrs +//--------------------------------------- +// #include "make_op_OneMax.h" +// eoGenOp>& make_op(eoParser& _parser, eoState& _state, eoInit>& _init) +// { +// return do_make_op(_parser, _state, _init); +// } + +// eoGenOp>& make_op(eoParser& _parser, eoState& _state, eoInit>& _init) +// { +// return do_make_op(_parser, _state, _init); +// } + +// The following modules use ***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); +} + +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); +} + +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); +} + +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); +} + +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 +void run_ea(eoAlgo >& _ga, eoPop >& _pop) +{ + do_run(_ga, _pop); +} + +void run_ea(eoAlgo >& _ga, eoPop >& _pop) +{ + do_run(_ga, _pop); +} + diff --git a/eo/tutorial/Lesson5/make_genotype_OneMax.h b/eo/tutorial/Lesson5/make_genotype_OneMax.h new file mode 100644 index 00000000..52ff9ebf --- /dev/null +++ b/eo/tutorial/Lesson5/make_genotype_OneMax.h @@ -0,0 +1,75 @@ +// -*- 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(); + + unsigned vecSize = _parser.createParam(unsigned(8), "VecSize", "Size of the bitstrings", 'v',"Representation").value(); + + // Then built the initializer - a pointer, stored in the eoState + eoInit* init = new eoOneMaxInit(vecSize); + // store in state + _state.storeFunctor(init); + // and return a reference + return *init; +} + +#endif diff --git a/eo/tutorial/Lesson5/make_op_OneMax.h b/eo/tutorial/Lesson5/make_op_OneMax.h new file mode 100644 index 00000000..d19c8930 --- /dev/null +++ b/eo/tutorial/Lesson5/make_op_OneMax.h @@ -0,0 +1,210 @@ +// -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*- + +//----------------------------------------------------------------------------- +// make_op_OneMax.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_OneMax_h +#define _make_op_OneMax_h + +// the operators +#include +#include +#include +#include +// combinations of simple eoOps (eoMonOp and eoQuadOp) +#include + +/** definition of mutation: + * class eoOneMaxMonop MUST derive from eoMonOp + */ +#include "eoOneMaxMutation.h" + +/** definition of crossover (either as eoBinOp (2->1) or eoQuadOp (2->2): + * class eoOneMaxBinCrossover MUST derive from eoBinOp + * OR + * class eoOneMaxQuadCrossover MUST derive from eoQuadOp + */ +// #include "eoOneMaxBinOp.h" +// OR +#include "eoOneMaxQuadCrossover.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 eoOneMax + * + * 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 eoOneMax +*/ + +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 eoOneMaxQuadCrossover /* (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 eoOneMaxSecondCrossover(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 eoOneMaxMutation/* (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 eoOneMaxSecondMutation(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