From b8d4e7faefbaa307155830cbb770f6f9c26aa665 Mon Sep 17 00:00:00 2001 From: evomarc Date: Wed, 29 Nov 2000 18:19:57 +0000 Subject: [PATCH] Initial version of the tutorial. Warning: all Makefile's are hand-made, and will only work in Linux --- eo/tutorial/Lesson1/FirstBitGA.cpp | 164 ++ eo/tutorial/Lesson1/FirstRealGA.cpp | 165 ++ eo/tutorial/Lesson1/Makefile | 12 + eo/tutorial/Lesson1/exercise3.cpp | 165 ++ eo/tutorial/Lesson2/FirstBitEA.cpp | 193 +++ eo/tutorial/Lesson2/FirstRealEA.cpp | 188 +++ eo/tutorial/Lesson2/Makefile | 12 + eo/tutorial/Lesson2/binary_value.h | 17 + eo/tutorial/Lesson2/exercise3.cpp | 195 +++ eo/tutorial/Lesson2/real_value.h | 18 + eo/tutorial/Lesson3/Makefile | 12 + eo/tutorial/Lesson3/SecondBitEA.cpp | 375 +++++ eo/tutorial/Lesson3/binary_value.h | 17 + eo/tutorial/Lesson3/exercise1.cpp | 384 +++++ eo/tutorial/html/EA_tutorial.jpg | Bin 0 -> 53765 bytes eo/tutorial/html/FirstBitEA.html | 368 +++++ eo/tutorial/html/FirstBitGA.html | 350 +++++ eo/tutorial/html/FirstRealEA.html | 366 +++++ eo/tutorial/html/FirstRealGA.html | 349 +++++ eo/tutorial/html/FirstRealGA_old.html | 278 ++++ eo/tutorial/html/Firstmerge.html | 287 ++++ eo/tutorial/html/NoWay.html | 74 + eo/tutorial/html/SecondBitEA.html | 612 ++++++++ eo/tutorial/html/beige009.jpg | Bin 0 -> 6643 bytes eo/tutorial/html/binary_value.html | 57 + eo/tutorial/html/costume.jpg | Bin 0 -> 213921 bytes eo/tutorial/html/debut.html | 21 + eo/tutorial/html/eoBottomUp.html | 74 + eo/tutorial/html/eoEngine.html | 59 + eo/tutorial/html/eoEval.html | 34 + eo/tutorial/html/eoGeneration.html | 19 + eo/tutorial/html/eoInit.html | 36 + eo/tutorial/html/eoIo.html | 25 + eo/tutorial/html/eoLesson1.html | 413 +++++ eo/tutorial/html/eoLesson2.html | 301 ++++ eo/tutorial/html/eoLesson3.html | 531 +++++++ eo/tutorial/html/eoOperators.html | 56 + eo/tutorial/html/eoOutput.html | 19 + eo/tutorial/html/eoProgramming.html | 256 ++++ eo/tutorial/html/eoRepresentation.html | 19 + eo/tutorial/html/eoSGA.html | 157 ++ eo/tutorial/html/eoSelect.html | 19 + eo/tutorial/html/eoStop.html | 25 + eo/tutorial/html/eoTopDown.html | 88 ++ eo/tutorial/html/eoTutorial.html | 178 +++ eo/tutorial/html/index.html | 178 +++ eo/tutorial/html/lesson1.ps | 1952 ++++++++++++++++++++++++ eo/tutorial/html/real_value.html | 56 + 48 files changed, 9174 insertions(+) create mode 100644 eo/tutorial/Lesson1/FirstBitGA.cpp create mode 100644 eo/tutorial/Lesson1/FirstRealGA.cpp create mode 100644 eo/tutorial/Lesson1/Makefile create mode 100644 eo/tutorial/Lesson1/exercise3.cpp create mode 100644 eo/tutorial/Lesson2/FirstBitEA.cpp create mode 100644 eo/tutorial/Lesson2/FirstRealEA.cpp create mode 100644 eo/tutorial/Lesson2/Makefile create mode 100644 eo/tutorial/Lesson2/binary_value.h create mode 100644 eo/tutorial/Lesson2/exercise3.cpp create mode 100644 eo/tutorial/Lesson2/real_value.h create mode 100644 eo/tutorial/Lesson3/Makefile create mode 100644 eo/tutorial/Lesson3/SecondBitEA.cpp create mode 100644 eo/tutorial/Lesson3/binary_value.h create mode 100644 eo/tutorial/Lesson3/exercise1.cpp create mode 100644 eo/tutorial/html/EA_tutorial.jpg create mode 100644 eo/tutorial/html/FirstBitEA.html create mode 100644 eo/tutorial/html/FirstBitGA.html create mode 100644 eo/tutorial/html/FirstRealEA.html create mode 100644 eo/tutorial/html/FirstRealGA.html create mode 100644 eo/tutorial/html/FirstRealGA_old.html create mode 100644 eo/tutorial/html/Firstmerge.html create mode 100644 eo/tutorial/html/NoWay.html create mode 100644 eo/tutorial/html/SecondBitEA.html create mode 100644 eo/tutorial/html/beige009.jpg create mode 100644 eo/tutorial/html/binary_value.html create mode 100644 eo/tutorial/html/costume.jpg create mode 100644 eo/tutorial/html/debut.html create mode 100644 eo/tutorial/html/eoBottomUp.html create mode 100644 eo/tutorial/html/eoEngine.html create mode 100644 eo/tutorial/html/eoEval.html create mode 100644 eo/tutorial/html/eoGeneration.html create mode 100644 eo/tutorial/html/eoInit.html create mode 100644 eo/tutorial/html/eoIo.html create mode 100644 eo/tutorial/html/eoLesson1.html create mode 100644 eo/tutorial/html/eoLesson2.html create mode 100644 eo/tutorial/html/eoLesson3.html create mode 100644 eo/tutorial/html/eoOperators.html create mode 100644 eo/tutorial/html/eoOutput.html create mode 100644 eo/tutorial/html/eoProgramming.html create mode 100644 eo/tutorial/html/eoRepresentation.html create mode 100644 eo/tutorial/html/eoSGA.html create mode 100644 eo/tutorial/html/eoSelect.html create mode 100644 eo/tutorial/html/eoStop.html create mode 100644 eo/tutorial/html/eoTopDown.html create mode 100644 eo/tutorial/html/eoTutorial.html create mode 100644 eo/tutorial/html/index.html create mode 100644 eo/tutorial/html/lesson1.ps create mode 100644 eo/tutorial/html/real_value.html diff --git a/eo/tutorial/Lesson1/FirstBitGA.cpp b/eo/tutorial/Lesson1/FirstBitGA.cpp new file mode 100644 index 000000000..db7dc22cd --- /dev/null +++ b/eo/tutorial/Lesson1/FirstBitGA.cpp @@ -0,0 +1,164 @@ +//----------------------------------------------------------------------------- +// FirstBitGA.cpp +//----------------------------------------------------------------------------- +//* +// An instance of a VERY simple Bitstring Genetic Algorithm +// +//----------------------------------------------------------------------------- +// standard includes +#include // runtime_error +#include // cout +#include // ostrstream, istrstream + +// the general include for eo + +#include + +// REPRESENTATION +//----------------------------------------------------------------------------- +// define your individuals +typedef eoBin Indi; // A bitstring with fitness double + +// EVAL +//----------------------------------------------------------------------------- +// a simple fitness function that computes the number of ones of a bitstring +// @param _indi A biststring individual + +double binary_value(const Indi & _indi) +{ + double sum = 0; + for (unsigned i = 0; i < _indi.size(); i++) + sum += _indi[i]; + return sum; +} +// GENERAL +//----------------------------------------------------------------------------- +void main_function(int argc, char **argv) +{ +// PARAMETRES + // all parameters are hard-coded! + const unsigned int SEED = 42; // seed for random number generator + const unsigned int T_SIZE = 3; // size for tournament selection + const unsigned int VEC_SIZE = 8; // Number of bits in genotypes + const unsigned int POP_SIZE = 20; // Size of population + const unsigned int MAX_GEN = 100; // Maximum number of generation before STOP + const float CROSS_RATE = 0.8; // Crossover rate + const double P_MUT_PER_BIT = 0.01; // probability of bit-flip mutation + const float MUT_RATE = 1.0; // mutation rate + +// GENERAL + ////////////////////////// + // Random seed + ////////////////////////// + //reproducible random seed: if you don't change SEED above, + // you'll aways get the same result, NOT a random run + rng.reseed(SEED); + +// EVAL + ///////////////////////////// + // Fitness function + //////////////////////////// + // Evaluation: from a plain C++ fn to an EvalFunc Object + eoEvalFuncPtr eval( binary_value ); + +// INIT + //////////////////////////////// + // Initilisation of population + //////////////////////////////// + + // declare the population + eoPop pop; + // fill it! + for (unsigned int igeno=0; igeno select(T_SIZE); // T_SIZE in [2,POP_SIZE] + +// REPLACE + // The simple GA evolution engine uses generational replacement + // so no replacement procedure is needed + +// OPERATORS + ////////////////////////////////////// + // The variation operators + ////////////////////////////////////// +// CROSSOVER + // 1-point mutation for bitstring + eoBinCrossover xover; +// MUTATION + // standard bit-flip mutation for bitstring + eoBinMutation mutation(P_MUT_PER_BIT); + +// STOP +// CHECKPOINT + ////////////////////////////////////// + // termination condition + ///////////////////////////////////// + // stop after MAX_GEN generations + eoGenContinue continuator(MAX_GEN); + +// GENERATION + ///////////////////////////////////////// + // the algorithm + //////////////////////////////////////// + // standard Generational GA requires as parameters + // selection, evaluation, crossover and mutation, stopping criterion + + + eoSGA gga(select, xover, CROSS_RATE, mutation, MUT_RATE, + eval, continuator); + + // Apply algo to pop - that's it! + gga(pop); + +// OUTPUT + // Print (sorted) intial population + pop.sort(); + cout << "FINAL Population\n" << pop << endl; +// GENERAL +} + // A main that catches the exceptions + +int main(int argc, char **argv) +{ +#ifdef _MSC_VER + // rng.reseed(42); + int flag = _CrtSetDbgFlag(_CRTDBG_LEAK_CHECK_DF); + flag |= _CRTDBG_LEAK_CHECK_DF; + _CrtSetDbgFlag(flag); +// _CrtSetBreakAlloc(100); +#endif + + try + { + main_function(argc, argv); + } + catch(exception& e) + { + cout << "Exception: " << e.what() << '\n'; + } + + return 1; +} diff --git a/eo/tutorial/Lesson1/FirstRealGA.cpp b/eo/tutorial/Lesson1/FirstRealGA.cpp new file mode 100644 index 000000000..ff1cadd3d --- /dev/null +++ b/eo/tutorial/Lesson1/FirstRealGA.cpp @@ -0,0 +1,165 @@ +//----------------------------------------------------------------------------- +// FirstRealGA.cpp +//----------------------------------------------------------------------------- +//* +// An instance of a VERY simple Real-coded Genetic Algorithm +// +//----------------------------------------------------------------------------- +// standard includes +#include // runtime_error +#include // cout +#include // ostrstream, istrstream + +// the general include for eo + +#include + +// REPRESENTATION +//----------------------------------------------------------------------------- +// define your individuals + typedef eoReal Indi; + +// EVAL +//----------------------------------------------------------------------------- +// a simple fitness function that computes the euclidian norm of a real vector +// @param _indi A real-valued individual + +double real_value(const Indi & _indi) +{ + double sum = 0; + for (unsigned i = 0; i < _indi.size(); i++) + sum += _indi[i]*_indi[i]; + return (-sum); // maximizing only +} +// GENERAL +//----------------------------------------------------------------------------- +void main_function(int argc, char **argv) +{ +// PARAMETRES + // all parameters are hard-coded! + const unsigned int SEED = 42; // seed for random number generator + const unsigned int VEC_SIZE = 8; // Number of object variables in genotypes + const unsigned int POP_SIZE = 20; // Size of population + const unsigned int T_SIZE = 3; // size for tournament selection + const unsigned int MAX_GEN = 500; // Maximum number of generation before STOP + const float CROSS_RATE = 0.8; // Crossover rate + const double EPSILON = 0.01; // range for real uniform mutation + const float MUT_RATE = 0.5; // mutation rate + +// GENERAL + ////////////////////////// + // Random seed + ////////////////////////// + //reproducible random seed: if you don't change SEED above, + // you'll aways get the same result, NOT a random run + rng.reseed(SEED); + +// EVAL + ///////////////////////////// + // Fitness function + //////////////////////////// + // Evaluation: from a plain C++ fn to an EvalFunc Object + eoEvalFuncPtr eval( real_value ); + +// INIT + //////////////////////////////// + // Initilisation of population + //////////////////////////////// + + // declare the population + eoPop pop; + // fill it! + for (unsigned int igeno=0; igeno select(T_SIZE); // T_SIZE in [2,POP_SIZE] + +// REPLACE + // eoSGA uses generational replacement by default + // so no replacement procedure has to be given + +// OPERATORS + ////////////////////////////////////// + // The variation operators + ////////////////////////////////////// +// CROSSOVER + // offspring(i) is a linear combination of parent(i) + eoArithmeticCrossover xover; +// MUTATION + // offspring(i) uniformly chosen in [parent(i)-epsilon, parent(i)+epsilon] + eoUniformMutation mutation(EPSILON); + +// STOP +// CHECKPOINT + ////////////////////////////////////// + // termination condition + ///////////////////////////////////// + // stop after MAX_GEN generations + eoGenContinue continuator(MAX_GEN); + +// GENERATION + ///////////////////////////////////////// + // the algorithm + //////////////////////////////////////// + // standard Generational GA requires + // selection, evaluation, crossover and mutation, stopping criterion + + + eoSGA gga(select, xover, CROSS_RATE, mutation, MUT_RATE, + eval, continuator); + + // Apply algo to pop - that's it! + gga(pop); + +// OUTPUT + // Print (sorted) intial population + pop.sort(); + cout << "FINAL Population\n" << pop << endl; +// GENERAL +} + +// A main that catches the exceptions + +int main(int argc, char **argv) +{ +#ifdef _MSC_VER + // rng.reseed(42); + int flag = _CrtSetDbgFlag(_CRTDBG_LEAK_CHECK_DF); + flag |= _CRTDBG_LEAK_CHECK_DF; + _CrtSetDbgFlag(flag); +// _CrtSetBreakAlloc(100); +#endif + + try + { + main_function(argc, argv); + } + catch(exception& e) + { + cout << "Exception: " << e.what() << '\n'; + } + + return 1; +} diff --git a/eo/tutorial/Lesson1/Makefile b/eo/tutorial/Lesson1/Makefile new file mode 100644 index 000000000..396873dea --- /dev/null +++ b/eo/tutorial/Lesson1/Makefile @@ -0,0 +1,12 @@ +.cpp: ; g++ -DPACKAGE=\"eo\" -DVERSION=\"0.9.1\" -I. -I../../src -Wall -g -o $@ $*.cpp ../../src/libeo.a ../../src/utils/libeoutils.a + +.cpp.o: ; g++ -DPACKAGE=\"eo\" -DVERSION=\"0.9.1\" -I. -I../../src -Wall -g -c $*.cpp + +firstGA = FirstRealGA FirstBitGA + +ALL = $(firstGA) exercise3 + +lesson1 : $(firstGA) + +clean : + @/bin/rm $(ALL) *.o *~ diff --git a/eo/tutorial/Lesson1/exercise3.cpp b/eo/tutorial/Lesson1/exercise3.cpp new file mode 100644 index 000000000..64ca5df01 --- /dev/null +++ b/eo/tutorial/Lesson1/exercise3.cpp @@ -0,0 +1,165 @@ +#include // runtime_error + +//----------------------------------------------------------------------------- +// FirstBitGA.cpp +//----------------------------------------------------------------------------- +//* +// An instance of a VERY simple Bitstring Genetic Algorithm +// +//----------------------------------------------------------------------------- +// standard includes + +#include // cout +#include // ostrstream, istrstream + +// the general include for eo + +#include + +//----------------------------------------------------------------------------- +// define your individuals +typedef eoBin Indi; // A bitstring with fitness double + +//----------------------------------------------------------------------------- +/** a simple fitness function that computes the number of ones of a bitstring + @param _indi A biststring individual +*/ + +double binary_value(const Indi & _indi) +{ + double sum = 0; + for (unsigned i = 0; i < _indi.size(); i++) + sum += _indi[i]; + return sum; +} + +//----------------------------------------------------------------------------- + +void main_function(int argc, char **argv) +{ + const unsigned int SEED = 42; // seed for random number generator + const unsigned int VEC_SIZE = 8; // Number of bits in genotypes + const unsigned int POP_SIZE = 20; // Size of population + const unsigned int MAX_GEN = 500; // Maximum number of generation before STOP + const float CROSS_RATE = 0.8; // Crossover rate + const double P_MUT_PER_BIT = 0.01; // probability of bit-flip mutation + const float MUT_RATE = 1.0; // mutation rate + + ////////////////////////// + // Random seed + ////////////////////////// + //reproducible random seed: if you don't change SEED above, + // you'll aways get the same result, NOT a random run + rng.reseed(SEED); + + ///////////////////////////// + // Fitness function + //////////////////////////// + // Evaluation: from a plain C++ fn to an EvalFunc Object + eoEvalFuncPtr eval( binary_value ); + + //////////////////////////////// + // Initilisation of population + //////////////////////////////// + + // declare the population + eoPop pop; + // fill it! + for (unsigned int igeno=0; igeno select; + + // could also use stochastic binary tournament selection + // + // const double RATE = 0.75; + // eoStochTournament select(RATE); // RATE in ]0.5,1] + // The robust tournament selection + const unsigned int T_SIZE = 3; // size for tournament selection + eoDetTournament select(T_SIZE); // T_SIZE in [2,POP_SIZE] + + // and of course the random selection + // eoSelectRandom select; + + // The simple GA evolution engine uses generational replacement + // so no replacement procedure is needed + + ////////////////////////////////////// + // termination condition + ///////////////////////////////////// + // stop after MAX_GEN generations + eoGenContinue continuator(MAX_GEN); + + + ////////////////////////////////////// + // The variation operators + ////////////////////////////////////// + // standard bit-flip mutation for bitstring + eoBinMutation mutation(P_MUT_PER_BIT); + // 1-point mutation for bitstring + eoBinCrossover xover; + + ///////////////////////////////////////// + // the algorithm + //////////////////////////////////////// + // standard Generational GA requires as parameters + // selection, evaluation, crossover and mutation, stopping criterion + + + eoSGA gga(select, xover, CROSS_RATE, mutation, MUT_RATE, + eval, continuator); + + // Apply algo to pop - that's it! + gga(pop); + + // Print (sorted) intial population + pop.sort(); + cout << "FINAL Population\n" << pop << endl; +} + +// A main that catches the exceptions + +int main(int argc, char **argv) +{ +#ifdef _MSC_VER + // rng.reseed(42); + int flag = _CrtSetDbgFlag(_CRTDBG_LEAK_CHECK_DF); + flag |= _CRTDBG_LEAK_CHECK_DF; + _CrtSetDbgFlag(flag); +// _CrtSetBreakAlloc(100); +#endif + + try + { + main_function(argc, argv); + } + catch(exception& e) + { + cout << "Exception: " << e.what() << '\n'; + } + + return 1; +} diff --git a/eo/tutorial/Lesson2/FirstBitEA.cpp b/eo/tutorial/Lesson2/FirstBitEA.cpp new file mode 100644 index 000000000..0d82a78fa --- /dev/null +++ b/eo/tutorial/Lesson2/FirstBitEA.cpp @@ -0,0 +1,193 @@ +//----------------------------------------------------------------------------- +// FirstBitEA.cpp +//----------------------------------------------------------------------------- +//* +// Still an instance of a VERY simple Bitstring Genetic Algorithm +// (see FirstBitGA.cpp) but now with Breeder - and Combined Ops +// +//----------------------------------------------------------------------------- +// standard includes +#include // runtime_error +#include // cout +#include // ostrstream, istrstream + +// the general include for eo +#include + +// REPRESENTATION +//----------------------------------------------------------------------------- +// define your individuals +typedef eoBin Indi; // A bitstring with fitness double + +// EVALFUNC +//----------------------------------------------------------------------------- +// a simple fitness function that computes the number of ones of a bitstring +// Now in a separate file, and declared as binary_value(const vector &) + +#include "binary_value.h" + +// GENERAL +//----------------------------------------------------------------------------- + +void main_function(int argc, char **argv) +{ +// PARAMETRES + const unsigned int SEED = 42; // seed for random number generator + const unsigned int T_SIZE = 3; // size for tournament selection + const unsigned int VEC_SIZE = 8; // Number of bits in genotypes + const unsigned int POP_SIZE = 20; // Size of population + + const unsigned int MAX_GEN = 500; // Maximum number of generation before STOP + const unsigned int MIN_GEN = 10; // Minimum number of generation before ... + const unsigned int STEADY_GEN = 50; // stop after STEADY_GEN gen. without improvelent + + const double P_CROSS = 0.8; // Crossover probability + const double P_MUT = 1.0; // mutation probability + + const double P_MUT_PER_BIT = 0.01; // internal probability for bit-flip mutation + // some parameters for chosing among different operators + const double onePointRate = 0.5; // rate for 1-pt Xover + const double twoPointsRate = 0.5; // rate for 2-pt Xover + const double URate = 0.5; // rate for Uniform Xover + const double bitFlipRate = 0.5; // rate for bit-flip mutation + const double oneBitRate = 0.5; // rate for one-bit mutation + +// GENERAL + ////////////////////////// + // Random seed + ////////////////////////// + //reproducible random seed: if you don't change SEED above, + // you'll aways get the same result, NOT a random run + rng.reseed(SEED); + +// EVAL + ///////////////////////////// + // Fitness function + //////////////////////////// + // Evaluation: from a plain C++ fn to an EvalFunc Object + // you need to give the full description of the function + eoEvalFuncPtr& > eval( binary_value ); + +// INIT + //////////////////////////////// + // Initilisation of population + //////////////////////////////// + + // based on boolean_generator class (see utils/rnd_generator.h) + eoInitFixedLength + random(VEC_SIZE, boolean_generator()); + // Initialization of the population + eoPop pop(POP_SIZE, random); + + // and evaluate it in one loop + apply(eval, pop); // STL syntax + +// OUTPUT + // sort pop before printing it! + pop.sort(); + // Print (sorted) intial population (raw printout) + cout << "Initial Population" << endl; + cout << pop; + +// ENGINE + ///////////////////////////////////// + // selection and replacement + //////////////////////////////////// +// SELECT + // The robust tournament selection + eoDetTournament selectOne(T_SIZE); // T_SIZE in [2,POP_SIZE] + // is now encapsulated in a eoSelectPerc (entage) + eoSelectPerc select(selectOne);// by default rate==1 + +// REPLACE + // And we now have the full slection/replacement - though with + // no replacement (== generational replacement) at the moment :-) + eoNoReplacement replace; + +// OPERATORS + ////////////////////////////////////// + // The variation operators + ////////////////////////////////////// +// CROSSOVER + // 1-point crossover for bitstring + eoBinCrossover xover1; + // uniform crossover for bitstring + eoBinUxOver xoverU; + // 2-pots xover + eoBinNxOver xover2(2); + // Combine them with relative rates + eoPropCombinedQuadOp xover(xover1, onePointRate); + xover.add(xoverU, URate); + xover.add(xover2, twoPointsRate, true); + +// MUTATION + // standard bit-flip mutation for bitstring + eoBinMutation mutationBitFlip(P_MUT_PER_BIT); + // mutate exactly 1 bit per individual + eoDetBitFlip mutationOneBit; + // Combine them with relative rates + eoPropCombinedMonOp mutation(mutationBitFlip, bitFlipRate); + mutation.add(mutationOneBit, oneBitRate, true); + + // The operators are encapsulated into an eoTRansform object + eoSGATransform transform(xover, P_CROSS, mutation, P_MUT); + +// STOP +// CHECKPOINT + ////////////////////////////////////// + // termination conditions: use more than one + ///////////////////////////////////// + // stop after MAX_GEN generations + eoGenContinue genCont(MAX_GEN); + // do MIN_GEN gen., then stop after STEADY_GEN gen. without improvement + eoSteadyFitContinue steadyCont(MIN_GEN, STEADY_GEN); + // stop when fitness reaches a target (here VEC_SIZE) + eoFitContinue fitCont(VEC_SIZE); + // do stop when one of the above says so + eoCombinedContinue continuator(genCont); + continuator.add(steadyCont); + continuator.add(fitCont); + +// GENERATION + ///////////////////////////////////////// + // the algorithm + //////////////////////////////////////// + + // Easy EA requires + // selection, transformation, eval, replacement, and stopping criterion + eoEasyEA gga(continuator, eval, select, transform, replace); + + // Apply algo to pop - that's it! + cout << "\n Here we go\n\n"; + gga(pop); + +// OUTPUT + // Print (sorted) intial population + pop.sort(); + cout << "FINAL Population\n" << pop << endl; +// GENERAL +} + +// A main that catches the exceptions + +int main(int argc, char **argv) +{ +#ifdef _MSC_VER + // rng.reseed(42); + int flag = _CrtSetDbgFlag(_CRTDBG_LEAK_CHECK_DF); + flag |= _CRTDBG_LEAK_CHECK_DF; + _CrtSetDbgFlag(flag); +// _CrtSetBreakAlloc(100); +#endif + + try + { + main_function(argc, argv); + } + catch(exception& e) + { + cout << "Exception: " << e.what() << '\n'; + } + + return 1; +} diff --git a/eo/tutorial/Lesson2/FirstRealEA.cpp b/eo/tutorial/Lesson2/FirstRealEA.cpp new file mode 100644 index 000000000..1d6979776 --- /dev/null +++ b/eo/tutorial/Lesson2/FirstRealEA.cpp @@ -0,0 +1,188 @@ +//----------------------------------------------------------------------------- +// FirstRealEA.cpp +//----------------------------------------------------------------------------- +//* +// Still an instance of a VERY simple Real-coded Genetic Algorithm +// (see FirstBitGA.cpp) but now with Breeder - and Combined Ops +// +//----------------------------------------------------------------------------- +// standard includes +#include // runtime_error +#include // cout +#include // ostrstream, istrstream + +// the general include for eo +#include + +// REPRESENTATION +//----------------------------------------------------------------------------- +// define your individuals +typedef eoReal Indi; + +// EVALFUNC +//----------------------------------------------------------------------------- +// a simple fitness function that computes the euclidian norm of a real vector +// Now in a separate file, and declared as binary_value(const vector &) + +#include "real_value.h" + +// GENERAL +//----------------------------------------------------------------------------- + +void main_function(int argc, char **argv) +{ +// PARAMETRES + const unsigned int SEED = 42; // seed for random number generator + const unsigned int T_SIZE = 3; // size for tournament selection + const unsigned int VEC_SIZE = 8; // Number of object variables in genotypes + const unsigned int POP_SIZE = 20; // Size of population + + const unsigned int MAX_GEN = 500; // Maximum number of generation before STOP + const unsigned int MIN_GEN = 10; // Minimum number of generation before ... + const unsigned int STEADY_GEN = 50; // stop after STEADY_GEN gen. without improvelent + + const float P_CROSS = 0.8; // Crossover probability + const float P_MUT = 0.5; // mutation probability + + const double EPSILON = 0.01; // range for real uniform mutation + // some parameters for chosing among different operators + const double segmentRate = 0.5; // rate for 1-pt Xover + const double arithmeticRate = 0.5; // rate for 2-pt Xover + const double uniformMutRate = 0.5; // rate for bit-flip mutation + const double detMutRate = 0.5; // rate for one-bit mutation + +// GENERAL + ////////////////////////// + // Random seed + ////////////////////////// + //reproducible random seed: if you don't change SEED above, + // you'll aways get the same result, NOT a random run + rng.reseed(SEED); + +// EVAL + ///////////////////////////// + // Fitness function + //////////////////////////// + // Evaluation: from a plain C++ fn to an EvalFunc Object + // you need to give the full description of the function + eoEvalFuncPtr& > eval( real_value ); + +// INIT + //////////////////////////////// + // Initilisation of population + //////////////////////////////// + // based on a uniform generator + eoInitFixedLength > + random(VEC_SIZE, uniform_generator(-1.0, 1.0)); + // Initialization of the population + eoPop pop(POP_SIZE, random); + + // and evaluate it in one loop + apply(eval, pop); // STL syntax + +// OUTPUT + // sort pop before printing it! + pop.sort(); + // Print (sorted) intial population (raw printout) + cout << "Initial Population" << endl; + cout << pop; + +// ENGINE + ///////////////////////////////////// + // selection and replacement + //////////////////////////////////// +// SELECT + // The robust tournament selection + eoDetTournament selectOne(T_SIZE); + // is now encapsulated in a eoSelectPerc (entage) + eoSelectPerc select(selectOne);// by default rate==1 + +// REPLACE + // And we now have the full slection/replacement - though with + // no replacement (== generational replacement) at the moment :-) + eoNoReplacement replace; + +// OPERATORS + ////////////////////////////////////// + // The variation operators + ////////////////////////////////////// +// CROSSOVER + // uniform chooce on segment made by the parents + eoSegmentCrossover xoverS; + // uniform choice in hypercube built by the parents + eoArithmeticCrossover xoverA; + // Combine them with relative rates + eoPropCombinedQuadOp xover(xoverS, segmentRate); + xover.add(xoverA, arithmeticRate, true); + +// MUTATION + // offspring(i) uniformly chosen in [parent(i)-epsilon, parent(i)+epsilon] + eoUniformMutation mutationU(EPSILON); + // k (=1) coordinates of parents are uniformly modified + eoDetUniformMutation mutationD(EPSILON); + // Combine them with relative rates + eoPropCombinedMonOp mutation(mutationU, uniformMutRate); + mutation.add(mutationD, detMutRate, true); + +// STOP +// CHECKPOINT + ////////////////////////////////////// + // termination conditions: use more than one + ///////////////////////////////////// + // stop after MAX_GEN generations + eoGenContinue genCont(MAX_GEN); + // do MIN_GEN gen., then stop after STEADY_GEN gen. without improvement + eoSteadyFitContinue steadyCont(MIN_GEN, STEADY_GEN); + // stop when fitness reaches a target (here VEC_SIZE) + eoFitContinue fitCont(0); + // do stop when one of the above says so + eoCombinedContinue continuator(genCont); + continuator.add(steadyCont); + continuator.add(fitCont); + + // The operators are encapsulated into an eoTRansform object + eoSGATransform transform(xover, P_CROSS, mutation, P_MUT); + +// GENERATION + ///////////////////////////////////////// + // the algorithm + //////////////////////////////////////// + + // Easy EA requires + // selection, transformation, eval, replacement, and stopping criterion + eoEasyEA gga(continuator, eval, select, transform, replace); + + // Apply algo to pop - that's it! + cout << "\n Here we go\n\n"; + gga(pop); + +// OUTPUT + // Print (sorted) intial population + pop.sort(); + cout << "FINAL Population\n" << pop << endl; +// GENERAL +} + +// A main that catches the exceptions + +int main(int argc, char **argv) +{ +#ifdef _MSC_VER + // rng.reseed(42); + int flag = _CrtSetDbgFlag(_CRTDBG_LEAK_CHECK_DF); + flag |= _CRTDBG_LEAK_CHECK_DF; + _CrtSetDbgFlag(flag); +// _CrtSetBreakAlloc(100); +#endif + + try + { + main_function(argc, argv); + } + catch(exception& e) + { + cout << "Exception: " << e.what() << '\n'; + } + + return 1; +} diff --git a/eo/tutorial/Lesson2/Makefile b/eo/tutorial/Lesson2/Makefile new file mode 100644 index 000000000..75b3a2ec4 --- /dev/null +++ b/eo/tutorial/Lesson2/Makefile @@ -0,0 +1,12 @@ +.cpp: ; g++ -DPACKAGE=\"eo\" -DVERSION=\"0.9.1\" -I. -I../../src -Wall -g -o $@ $*.cpp ../../src/libeo.a ../../src/utils/libeoutils.a + +.cpp.o: ; g++ -DPACKAGE=\"eo\" -DVERSION=\"0.9.1\" -I. -I../../src -Wall -g -c $*.cpp + +firstEA = FirstRealEA FirstBitEA + +ALL = $(firstEA) exercise1 exercise2 exercise3 + +lesson2 : $(firstEA) + +clean : + @/bin/rm $(ALL) *.o *~ diff --git a/eo/tutorial/Lesson2/binary_value.h b/eo/tutorial/Lesson2/binary_value.h new file mode 100644 index 000000000..a31c08644 --- /dev/null +++ b/eo/tutorial/Lesson2/binary_value.h @@ -0,0 +1,17 @@ +#include + +//----------------------------------------------------------------------------- + +/** Just a simple function that takes binary value of a chromosome and sets + the fitnes. + @param _chrom A binary chromosome +*/ +// INIT +double binary_value(const vector& _chrom) +{ + double sum = 0; + for (unsigned i = 0; i < _chrom.size(); i++) + sum += _chrom[i]; + return sum; +} + diff --git a/eo/tutorial/Lesson2/exercise3.cpp b/eo/tutorial/Lesson2/exercise3.cpp new file mode 100644 index 000000000..c8e7ab6c7 --- /dev/null +++ b/eo/tutorial/Lesson2/exercise3.cpp @@ -0,0 +1,195 @@ +//----------------------------------------------------------------------------- +// FirstBitEA.cpp +//----------------------------------------------------------------------------- +//* +// Still an instance of a VERY simple Bitstring Genetic Algorithm +// (see FirstBitGA.cpp) but now with Breeder - and Combined Ops +// +//----------------------------------------------------------------------------- +// standard includes +#include // runtime_error +#include // cout +#include // ostrstream, istrstream + +// the general include for eo +#include + +// REPRESENTATION +//----------------------------------------------------------------------------- +// define your individuals +typedef eoBin Indi; // A bitstring with fitness double + +// EVAL +//----------------------------------------------------------------------------- +// a simple fitness function that computes the number of ones of a bitstring +// Now in a separate file, and declared as binary_value(const vector &) + +#include "binary_value.h" + +// GENERAL +//----------------------------------------------------------------------------- + +void main_function(int argc, char **argv) +{ +// PARAMETRES + const unsigned int SEED = 42; // seed for random number generator + const unsigned int T_SIZE = 3; // size for tournament selection + const unsigned int VEC_SIZE = 8; // Number of bits in genotypes + const unsigned int POP_SIZE = 20; // Size of population + + const unsigned int MAX_GEN = 500; // Maximum number of generation before STOP + const unsigned int MIN_GEN = 10; // Minimum number of generation before ... + const unsigned int STEADY_GEN = 50; // stop after STEADY_GEN gen. without improvelent + + const double P_CROSS = 0.8; // Crossover probability + const double P_MUT = 1.0; // mutation probability + + const double P_MUT_PER_BIT = 0.01; // internal probability for bit-flip mutation + // some parameters for chosing among different operators + const double onePointRate = 0.5; // rate for 1-pt Xover + const double twoPointsRate = 0.5; // rate for 2-pt Xover + const double URate = 0.5; // rate for Uniform Xover + const double bitFlipRate = 0.5; // rate for bit-flip mutation + const double oneBitRate = 0.5; // rate for one-bit mutation + +// GENERAL + ////////////////////////// + // Random seed + ////////////////////////// + //reproducible random seed: if you don't change SEED above, + // you'll aways get the same result, NOT a random run + rng.reseed(SEED); + +// EVAL + ///////////////////////////// + // Fitness function + //////////////////////////// + // Evaluation: from a plain C++ fn to an EvalFunc Object + // you need to give the full description of the function + eoEvalFuncPtr& > eval( binary_value ); + +// INIT + //////////////////////////////// + // Initilisation of population + //////////////////////////////// + + // based on boolean_generator class (see utils/rnd_generator.h) + eoInitFixedLength + random(VEC_SIZE, boolean_generator()); + // Initialization of the population + eoPop pop(POP_SIZE, random); + + // and evaluate it in one loop + apply(eval, pop); // STL syntax + +// OUTPUT + // sort pop before printing it! + pop.sort(); + // Print (sorted) intial population (raw printout) + cout << "Initial Population" << endl; + cout << pop; + +// ENGINE + ///////////////////////////////////// + // selection and replacement + //////////////////////////////////// +// SELECT + // The robust tournament selection + eoDetTournament selectOne(T_SIZE); // T_SIZE in [2,POP_SIZE] + // solution solution solution solution solution solution solution + // modify the rate in the constructor + eoSelectPerc select(selectOne,2.0);// rate is second arg. + +// REPLACE + // solution solution solution solution solution solution solution + // eoCommaReplacement keeps the best among offspring + // eoPlusReplacement keeps the best among parents + offspring + // eoCommaReplacement replace; + eoPlusReplacement replace; + +// OPERATORS + ////////////////////////////////////// + // The variation operators + ////////////////////////////////////// +// CROSSOVER + // 1-point crossover for bitstring + eoBinCrossover xover1; + // uniform crossover for bitstring + eoBinUxOver xoverU; + // 2-pots xover + eoBinNxOver xover2(2); + // Combine them with relative rates + eoPropCombinedQuadOp xover(xover1, onePointRate); + xover.add(xoverU, URate); + xover.add(xover2, twoPointsRate, true); + +// MUTATION + // standard bit-flip mutation for bitstring + eoBinMutation mutationBitFlip(P_MUT_PER_BIT); + // mutate exactly 1 bit per individual + eoDetBitFlip mutationOneBit; + // Combine them with relative rates + eoPropCombinedMonOp mutation(mutationBitFlip, bitFlipRate); + mutation.add(mutationOneBit, oneBitRate, true); + + // The operators are encapsulated into an eoTRansform object + eoSGATransform transform(xover, P_CROSS, mutation, P_MUT); + +// STOP +// CHECKPOINT + ////////////////////////////////////// + // termination conditions: use more than one + ///////////////////////////////////// + // stop after MAX_GEN generations + eoGenContinue genCont(MAX_GEN); + // do MIN_GEN gen., then stop after STEADY_GEN gen. without improvement + eoSteadyFitContinue steadyCont(MIN_GEN, STEADY_GEN); + // stop when fitness reaches a target (here VEC_SIZE) + eoFitContinue fitCont(VEC_SIZE); + // do stop when one of the above says so + eoCombinedContinue continuator(genCont); + continuator.add(steadyCont); + continuator.add(fitCont); + +// GENERATION + ///////////////////////////////////////// + // the algorithm + //////////////////////////////////////// + + // Easy EA requires + // selection, transformation, eval, replacement, and stopping criterion + eoEasyEA gga(continuator, eval, select, transform, replace); + + // Apply algo to pop - that's it! + gga(pop); + +// OUTPUT + // Print (sorted) intial population + pop.sort(); + cout << "FINAL Population\n" << pop << endl; +// GENERAL +} + +// A main that catches the exceptions + +int main(int argc, char **argv) +{ +#ifdef _MSC_VER + // rng.reseed(42); + int flag = _CrtSetDbgFlag(_CRTDBG_LEAK_CHECK_DF); + flag |= _CRTDBG_LEAK_CHECK_DF; + _CrtSetDbgFlag(flag); +// _CrtSetBreakAlloc(100); +#endif + + try + { + main_function(argc, argv); + } + catch(exception& e) + { + cout << "Exception: " << e.what() << '\n'; + } + + return 1; +} diff --git a/eo/tutorial/Lesson2/real_value.h b/eo/tutorial/Lesson2/real_value.h new file mode 100644 index 000000000..17d96ede0 --- /dev/null +++ b/eo/tutorial/Lesson2/real_value.h @@ -0,0 +1,18 @@ +#include +//----------------------------------------------------------------------------- +/** Just a simple function that takes an vector and sets the fitnes + to the sphere function. Please use doubles not float!!! + @param _ind A floatingpoint vector +*/ + +// INIT +double real_value(const std::vector& _ind) +{ + double sum = 0; + for (unsigned i = 0; i < _ind.size(); i++) + sum += _ind[i] * _ind[i]; + return -sum; +} + + + diff --git a/eo/tutorial/Lesson3/Makefile b/eo/tutorial/Lesson3/Makefile new file mode 100644 index 000000000..c4d3ec8e2 --- /dev/null +++ b/eo/tutorial/Lesson3/Makefile @@ -0,0 +1,12 @@ +.cpp: ; g++ -DPACKAGE=\"eo\" -DVERSION=\"0.9.1\" -I. -I../../src -Wall -g -o $@ $*.cpp ../../src/libeo.a ../../src/utils/libeoutils.a + +.cpp.o: ; g++ -DPACKAGE=\"eo\" -DVERSION=\"0.9.1\" -I. -I../../src -Wall -g -c $*.cpp + +secondEA = SecondBitEA + +ALL = $(secondEA) exercise1 exercise2 exercise3 + +lesson3 : $(secondEA) + +clean : + @/bin/rm $(ALL) *.o *.sav *.xg *.status *~ diff --git a/eo/tutorial/Lesson3/SecondBitEA.cpp b/eo/tutorial/Lesson3/SecondBitEA.cpp new file mode 100644 index 000000000..457346a27 --- /dev/null +++ b/eo/tutorial/Lesson3/SecondBitEA.cpp @@ -0,0 +1,375 @@ +//----------------------------------------------------------------------------- +// SecondGA.cpp +//----------------------------------------------------------------------------- +//* +// Same code than FirstBitEA as far as Evolutionary Computation is concerned +// but now you learn to enter the parameters in a more flexible way +// and to twidle the output to your preferences! +//----------------------------------------------------------------------------- +// standard includes +#include // runtime_error +#include // cout +#include // ostrstream, istrstream +#include + +// the general include for eo +#include + +// EVAL +#include "binary_value.h" + +// REPRESENTATION +//----------------------------------------------------------------------------- +// define your genotype and fitness types +typedef eoBin Indi; + +// PARAMETRES +//----------------------------------------------------------------------------- +// instead of having all values of useful parameters as constants, read them: +// either on the command line (--option=value or -o=value) +// or in a parameter file (same syntax, order independent, +// # = usual comment character +// or in the environment (TODO) + +// note that the parameters are passed by reference so they can be updated +void read_param(int argc, char *argv[], + uint32 & _seed, + unsigned int & _vecSize, + unsigned int & _popSize, + unsigned int & _tSize, + double & _pCross, + double & _pMut, + string & _load_name, + unsigned int & _maxGen, + unsigned int & _minGen, + unsigned int & _steadyGen, + double & _onePointRate, + double & _twoPointsRate, + double & _uRate, + double & _pMutPerBit, + double & _bitFlipRate, + double & _oneBitRate + ) +{ + // define a parser from the command-line arguments + eoParser parser(argc, argv); + + // For each parameter, define Parameters directly in the parser, + // and assign the value to the variable + eoValueParam& seedParam = parser.createParam(time(0), "seed", "Random number seed", 'S'); + _seed = seedParam.value(); + + eoValueParam& vecSizeParam = parser.createParam(8, "vecSize", "Genotype size",'V', "Representation"); + _vecSize = vecSizeParam.value(); + + eoValueParam& popSizeParam = parser.createParam(10, "popSize", "Population size",'P', "Evolution"); + _popSize = popSizeParam.value(); + + eoValueParam& tSizeParam = parser.createParam(10, "tSize", "Tournament size",'T', "Evolution"); + _tSize = tSizeParam.value(); + + eoValueParam& load_nameParam = parser.createParam("", "Load","A save file to restart from",'L', "Persistence"); + _load_name = load_nameParam.value(); + + eoValueParam& maxGenParam = parser.createParam(100, "maxGen", "Maximum number of generations",'G', "Stopping criterion"); + _maxGen = maxGenParam.value(); + + eoValueParam& minGenParam = parser.createParam(100, "minGen", "Minimum number of generations",'g', "Stopping criterion"); + _minGen = minGenParam.value(); + + eoValueParam& steadyGenParam = parser.createParam(100, "steadyGen", "Number of generations with no improvement",'s', "Stopping criterion"); + _steadyGen = steadyGenParam.value(); + + eoValueParam& pCrossParam = parser.createParam(0.6, "pCross", "Probability of Crossover", 'C', "Genetic Operators"); + _pCross = pCrossParam.value(); + + eoValueParam& pMutParam = parser.createParam(0.1, "pMut", "Probability of Mutation", 'M', "Genetic Operators"); + _pMut = pMutParam.value(); + + eoValueParam& onePointRateParam = parser.createParam(1, "onePointRate", "Relative rate for one point crossover", '1', "Genetic Operators"); + _onePointRate = onePointRateParam.value(); + + eoValueParam& twoPointsRateParam = parser.createParam(1, "twoPointRate", "Relative rate for two point crossover", '2', "Genetic Operators"); + _twoPointsRate = twoPointsRateParam.value(); + + eoValueParam& uRateParam = parser.createParam(2, "uRate", "Relative rate for uniform crossover", 'U', "Genetic Operators"); + _uRate = uRateParam.value(); + + eoValueParam& pMutPerBitParam = parser.createParam(0.01, "pMutPerBit", "Probability of flipping 1 bit in bit-flip mutation", 'b', "Genetic Operators"); + _pMutPerBit = pMutPerBitParam.value(); + + eoValueParam& bitFlipRateParam = parser.createParam(0.01, "bitFlipRate", "Relative rate for bit-flip mutation", 'B', "Genetic Operators"); + _bitFlipRate = bitFlipRateParam.value(); + + eoValueParam& oneBitRateParam = parser.createParam(0.01, "oneBitRate", "Relative rate for deterministic bit-flip mutation", 'D', "Genetic Operators"); + _oneBitRate = oneBitRateParam.value(); + + // the name of the "status" file where all actual parameter values will be saved + string str_status = parser.ProgramName() + ".status"; + eoValueParam& status_nameParam = parser.createParam(str_status.c_str(), "status","Status file",'S', "Persistence"); + + // do the following AFTER ALL PARAMETERS HAVE BEEN PROCESSED + // i.e. in case you need parameters somewhere else, postpone these + if (parser.userNeedsHelp()) + { + parser.printHelp(cout); + exit(1); + } + if (status_nameParam.value() != "") + { + ofstream os(status_nameParam.value().c_str()); + os << parser; // and you can use that file as parameter file + } +} + +// GENERAL +// now the main_function: nothing changed, except input/output +void main_function(int argc, char **argv) +{ +// PARAMETRES + uint32 seed; + // decription of genotype + unsigned int vecSize; + // parameters for evolution engine + unsigned int popSize; + unsigned int tSize; + // operators probabilities at the algorithm level + double pCross; + double pMut; + // init and stop + string load_name; + unsigned int maxGen; + unsigned int minGen; + unsigned int steadyGen; + // rates for crossovers + double onePointRate; + double twoPointsRate; + double URate; + // rates and private parameters for mutations; + double pMutPerBit; + double bitFlipRate; + double oneBitRate; + + // Now read the parameters of the program + read_param(argc, argv, seed, vecSize, popSize, tSize, + pCross, pMut, load_name, maxGen, minGen, steadyGen, + onePointRate, twoPointsRate, URate, + pMutPerBit, bitFlipRate, oneBitRate ); + +// EVAL + ///////////////////////////// + // Fitness function + //////////////////////////// + // Evaluation: from a plain C++ fn to an EvalFunc Object ... + eoEvalFuncPtr& > plainEval( binary_value ); + // ... to an object that counts the nb of actual evaluations + eoEvalFuncCounter eval(plainEval); + +// INIT + //////////////////////////////// + // Initilisation of population + //////////////////////////////// + // Either load or initialize + // create an empty pop + eoPop pop; + // create a state for reading + eoState inState; // a state for loading - WITHOUT the parser + // register the rng and the pop in the state, so they can be loaded, + // and the present run will be the exact conitnuation of the saved run + // eventually with different parameters + inState.registerObject(rng); + inState.registerObject(pop); + + if (load_name != "") + { + inState.load(load_name); // load the pop and the rng + // the fitness is read in the file: + // do only evaluate the pop if the fitness has changed + } + else + { + rng.reseed(seed); + // a Indi random initializer + // based on boolean_generator class (see utils/rnd_generator.h) + eoInitFixedLength + random(vecSize, boolean_generator()); + + // Init pop from the randomizer: need to use the append function + pop.append(popSize, random); + // and evaluate pop (STL syntax) + apply(eval, pop); + } // end of initializatio of the population + +// OUTPUT + // sort pop for pretty printout + pop.sort(); + // Print (sorted) intial population (raw printout) + cout << "Initial Population" << endl << pop << endl; + +// ENGINE + ///////////////////////////////////// + // selection and replacement + //////////////////////////////////// +// SELECT + // The robust tournament selection + eoDetTournament selectOne(tSize); // tSize in [2,POPSIZE] + // is now encapsulated in a eoSelectPerc (entage) + eoSelectPerc select(selectOne);// by default rate==1 + +// REPLACE + // And we now have the full slection/replacement - though with + // no replacement (== generational replacement) at the moment :-) + eoNoReplacement replace; + +// OPERATORS + ////////////////////////////////////// + // The variation operators + ////////////////////////////////////// +// CROSSOVER + // 1-point crossover for bitstring + eoBinCrossover xover1; + // uniform crossover for bitstring + eoBinUxOver xoverU; + // 2-pots xover + eoBinNxOver xover2(2); + // Combine them with relative rates + eoPropCombinedQuadOp xover(xover1, onePointRate); + xover.add(xoverU, URate); + xover.add(xover2, twoPointsRate, true); + +// MUTATION + // standard bit-flip mutation for bitstring + eoBinMutation mutationBitFlip(pMutPerBit); + // mutate exactly 1 bit per individual + eoDetBitFlip mutationOneBit; + // Combine them with relative rates + eoPropCombinedMonOp mutation(mutationBitFlip, bitFlipRate); + mutation.add(mutationOneBit, oneBitRate, true); + + // The operators are encapsulated into an eoTRansform object + eoSGATransform transform(xover, pCross, mutation, pMut); + +// STOP + ////////////////////////////////////// + // termination condition see FirstBitEA.cpp + ///////////////////////////////////// + eoGenContinue genCont(maxGen); + eoSteadyFitContinue steadyCont(minGen, steadyGen); + eoFitContinue fitCont(vecSize); + eoCombinedContinue continuator(genCont); + continuator.add(steadyCont); + continuator.add(fitCont); + + +// CHECKPOINT + // but now you want to make many different things every generation + // (e.g. statistics, plots, ...). + // the class eoCheckPoint is dedicated to just that: + + // Declare a checkpoint (from a continuator: an eoCheckPoint + // IS AN eoContinue and will be called in the loop of all algorithms) + eoCheckPoint checkpoint(continuator); + + // Create a counter parameter + eoValueParam generationCounter(0, "Gen."); + + // Create an incrementor (sub-class of eoUpdater). Note that the + // parameter's value is passed by reference, + // so every time the incrementer is updated (every generation), + // the data in generationCounter will change. + eoIncrementor increment(generationCounter.value()); + + // Add it to the checkpoint, + // so the counter is updated (here, incremented) every generation + checkpoint.add(increment); + + // now some statistics on the population: + // Best fitness in population + eoBestFitnessStat bestStat; + // Second moment stats: average and stdev + eoSecondMomentStats SecondStat; + + // Add them to the checkpoint to get them called at the appropriate time + checkpoint.add(bestStat); + checkpoint.add(SecondStat); + + // The Stdout monitor will print parameters to the screen ... + eoStdoutMonitor monitor(false); + + // when called by the checkpoint (i.e. at every generation) + checkpoint.add(monitor); + + // the monitor will output a series of parameters: add them + monitor.add(generationCounter); + monitor.add(eval); // because now eval is an eoEvalFuncCounter! + monitor.add(bestStat); + monitor.add(SecondStat); + + // A file monitor: will print parameters to ... a File, yes, you got it! + eoFileMonitor fileMonitor("stats.xg", " "); + + // the checkpoint mechanism can handle multiple monitors + checkpoint.add(fileMonitor); + + // the fileMonitor can monitor parameters, too, but you must tell it! + fileMonitor.add(generationCounter); + fileMonitor.add(bestStat); + fileMonitor.add(SecondStat); + + // Last type of item the eoCheckpoint can handle: state savers: + eoState outState; + // Register the algorithm into the state (so it has something to save!!) + outState.registerObject(rng); + outState.registerObject(pop); + + // and feed the state to state savers + // save state every 100th generation + eoCountedStateSaver stateSaver1(100, outState, "generation"); + // save state every 1 seconds + eoTimedStateSaver stateSaver2(1, outState, "time"); + + // Don't forget to add the two savers to the checkpoint + checkpoint.add(stateSaver1); + checkpoint.add(stateSaver2); + // and that's it for the (control and) output + +// GENERATION + ///////////////////////////////////////// + // the algorithm + //////////////////////////////////////// + + // Easy EA requires + // selection, transformation, eval, replacement, and stopping criterion + eoEasyEA gga(checkpoint, eval, select, transform, replace); + + // Apply algo to pop - that's it! + gga(pop); + +// OUTPUT + // Print (sorted) intial population + pop.sort(); + cout << "FINAL Population\n" << pop << endl; +// GENERAL +} + +// A main that catches the exceptions +int main(int argc, char **argv) +{ +#ifdef _MSC_VER + int flag = _CrtSetDbgFlag(_CRTDBG_LEAK_CHECK_DF); + flag |= _CRTDBG_LEAK_CHECK_DF; + _CrtSetDbgFlag(flag); +// _CrtSetBreakAlloc(100); +#endif + + try + { + main_function(argc, argv); + } + catch(exception& e) + { + cout << "Exception: " << e.what() << '\n'; + } + + return 1; +} diff --git a/eo/tutorial/Lesson3/binary_value.h b/eo/tutorial/Lesson3/binary_value.h new file mode 100644 index 000000000..a31c08644 --- /dev/null +++ b/eo/tutorial/Lesson3/binary_value.h @@ -0,0 +1,17 @@ +#include + +//----------------------------------------------------------------------------- + +/** Just a simple function that takes binary value of a chromosome and sets + the fitnes. + @param _chrom A binary chromosome +*/ +// INIT +double binary_value(const vector& _chrom) +{ + double sum = 0; + for (unsigned i = 0; i < _chrom.size(); i++) + sum += _chrom[i]; + return sum; +} + diff --git a/eo/tutorial/Lesson3/exercise1.cpp b/eo/tutorial/Lesson3/exercise1.cpp new file mode 100644 index 000000000..984395302 --- /dev/null +++ b/eo/tutorial/Lesson3/exercise1.cpp @@ -0,0 +1,384 @@ +//----------------------------------------------------------------------------- +// SecondBitGA.cpp +//----------------------------------------------------------------------------- +//* +// Same code than FirstBitEA as far as Evolutionary Computation is concerned +// but now you learn to enter the parameters in a more flexible way +// and to twidle the output to your preferences! +//----------------------------------------------------------------------------- +// standard includes +#include // runtime_error +#include // cout +#include // ostrstream, istrstream +#include + +// the general include for eo +#include +#include + +// EVAL +#include "binary_value.h" + +// REPRESENTATION +//----------------------------------------------------------------------------- +// define your genotype and fitness types +typedef eoBin Indi; + +// PARAMETRES +//----------------------------------------------------------------------------- +// instead of having all values of useful parameters as constants, read them: +// either on the command line (--option=value or -o=value) +// or in a parameter file (same syntax, order independent, +// # = usual comment character +// or in the environment (TODO) + +// note that the parameters are passed by reference so they can be updated +void read_param(int argc, char *argv[], + uint32 & _seed, + unsigned int & _vecSize, + unsigned int & _popSize, + unsigned int & _tSize, + double & _pCross, + double & _pMut, + string & _load_name, + unsigned int & _maxGen, + unsigned int & _minGen, + unsigned int & _steadyGen, + double & _onePointRate, + double & _twoPointsRate, + double & _uRate, + double & _pMutPerBit, + double & _bitFlipRate, + double & _oneBitRate + ) +{ + // define a parser from the command-line arguments + eoParser parser(argc, argv); + + // For each parameter, define Parameters directly in the parser, + // and assign the value to the variable + eoValueParam& seedParam = parser.createParam(time(0), "seed", "Random number seed", 'S'); + _seed = seedParam.value(); + + eoValueParam& vecSizeParam = parser.createParam(8, "vecSize", "Genotype size",'V', "Representation"); + _vecSize = vecSizeParam.value(); + + eoValueParam& popSizeParam = parser.createParam(10, "popSize", "Population size",'P', "Evolution"); + _popSize = popSizeParam.value(); + + eoValueParam& tSizeParam = parser.createParam(10, "tSize", "Tournament size",'T', "Evolution"); + _tSize = tSizeParam.value(); + + eoValueParam& load_nameParam = parser.createParam("", "Load","A save file to restart from",'L', "Persistence"); + _load_name = load_nameParam.value(); + + eoValueParam& maxGenParam = parser.createParam(100, "maxGen", "Maximum number of generations",'G', "Stopping criterion"); + _maxGen = maxGenParam.value(); + + eoValueParam& minGenParam = parser.createParam(100, "minGen", "Minimum number of generations",'g', "Stopping criterion"); + _minGen = minGenParam.value(); + + eoValueParam& steadyGenParam = parser.createParam(100, "steadyGen", "Number of generations with no improvement",'s', "Stopping criterion"); + _steadyGen = steadyGenParam.value(); + + eoValueParam& pCrossParam = parser.createParam(0.6, "pCross", "Probability of Crossover", 'C', "Genetic Operators"); + _pCross = pCrossParam.value(); + + eoValueParam& pMutParam = parser.createParam(0.1, "pMut", "Probability of Mutation", 'M', "Genetic Operators"); + _pMut = pMutParam.value(); + + eoValueParam& onePointRateParam = parser.createParam(1, "onePointRate", "Relative rate for one point crossover", '1', "Genetic Operators"); + _onePointRate = onePointRateParam.value(); + + eoValueParam& twoPointsRateParam = parser.createParam(1, "twoPointRate", "Relative rate for two point crossover", '2', "Genetic Operators"); + _twoPointsRate = twoPointsRateParam.value(); + + eoValueParam& uRateParam = parser.createParam(2, "uRate", "Relative rate for uniform crossover", 'U', "Genetic Operators"); + _uRate = uRateParam.value(); + + eoValueParam& pMutPerBitParam = parser.createParam(0.01, "pMutPerBit", "Probability of flipping 1 bit in bit-flip mutation", 'b', "Genetic Operators"); + _pMutPerBit = pMutPerBitParam.value(); + + eoValueParam& bitFlipRateParam = parser.createParam(0.01, "bitFlipRate", "Relative rate for bit-flip mutation", 'B', "Genetic Operators"); + _bitFlipRate = bitFlipRateParam.value(); + + eoValueParam& oneBitRateParam = parser.createParam(0.01, "oneBitRate", "Relative rate for deterministic bit-flip mutation", 'D', "Genetic Operators"); + _oneBitRate = oneBitRateParam.value(); + + // the name of the "status" file where all actual parameter values will be saved + string str_status = parser.ProgramName() + ".status"; + eoValueParam& status_nameParam = parser.createParam(str_status.c_str(), "status","Status file",'S', "Persistence"); + + // do the following AFTER ALL PARAMETERS HAVE BEEN PROCESSED + // i.e. in case you need parameters somewhere else, postpone these + if (parser.userNeedsHelp()) + { + parser.printHelp(cout); + exit(1); + } + if (status_nameParam.value() != "") + { + ofstream os(status_nameParam.value().c_str()); + os << parser; // and you can use that file as parameter file + } +} + +// GENERAL +// now the main_function: nothing changed, except input/output +void main_function(int argc, char **argv) +{ +// PARAMETRES + uint32 seed; + // decription of genotype + unsigned int vecSize; + // parameters for evolution engine + unsigned int popSize; + unsigned int tSize; + // operators probabilities at the algorithm level + double pCross; + double pMut; + // init and stop + string load_name; + unsigned int maxGen; + unsigned int minGen; + unsigned int steadyGen; + // rates for crossovers + double onePointRate; + double twoPointsRate; + double URate; + // rates and private parameters for mutations; + double pMutPerBit; + double bitFlipRate; + double oneBitRate; + + // Now read the parameters of the program + read_param(argc, argv, seed, vecSize, popSize, tSize, + pCross, pMut, load_name, maxGen, minGen, steadyGen, + onePointRate, twoPointsRate, URate, + pMutPerBit, bitFlipRate, oneBitRate ); + +// EVAL + ///////////////////////////// + // Fitness function + //////////////////////////// + // Evaluation: from a plain C++ fn to an EvalFunc Object ... + eoEvalFuncPtr& > plainEval( binary_value ); + // ... to an object that counts the nb of actual evaluations + eoEvalFuncCounter eval(plainEval); + +// INIT + //////////////////////////////// + // Initilisation of population + //////////////////////////////// + // Either load or initialize + // create an empty pop + eoPop pop; + // create a state for reading + eoState inState; // a state for loading - WITHOUT the parser + // register the rng and the pop in the state, so they can be loaded, + // and the present run will be the exact conitnuation of the saved run + // eventually with different parameters + inState.registerObject(rng); + inState.registerObject(pop); + + if (load_name != "") + { + inState.load(load_name); // load the pop and the rng + // the fitness is read in the file: + // do only evaluate the pop if the fitness has changed + } + else + { + rng.reseed(seed); + // a Indi random initializer + // based on boolean_generator class (see utils/rnd_generator.h) + eoInitFixedLength + random(vecSize, boolean_generator()); + + // Init pop from the randomizer: need to use the append function + pop.append(popSize, random); + // and evaluate pop (STL syntax) + apply(eval, pop); + } // end of initializatio of the population + +// OUTPUT + // sort pop for pretty printout + pop.sort(); + // Print (sorted) intial population (raw printout) + cout << "Initial Population" << endl << pop << endl; + +// ENGINE + ///////////////////////////////////// + // selection and replacement + //////////////////////////////////// +// SELECT + // The robust tournament selection + eoDetTournament selectOne(tSize); // tSize in [2,POPSIZE] + // is now encapsulated in a eoSelectPerc (entage) + eoSelectPerc select(selectOne);// by default rate==1 + +// REPLACE + // And we now have the full slection/replacement - though with + // no replacement (== generational replacement) at the moment :-) + eoNoReplacement replace; + +// OPERATORS + ////////////////////////////////////// + // The variation operators + ////////////////////////////////////// +// CROSSOVER + // 1-point crossover for bitstring + eoBinCrossover xover1; + // uniform crossover for bitstring + eoBinUxOver xoverU; + // 2-pots xover + eoBinNxOver xover2(2); + // Combine them with relative rates + eoPropCombinedQuadOp xover(xover1, onePointRate); + xover.add(xoverU, URate); + xover.add(xover2, twoPointsRate, true); + +// MUTATION + // standard bit-flip mutation for bitstring + eoBinMutation mutationBitFlip(pMutPerBit); + // mutate exactly 1 bit per individual + eoDetBitFlip mutationOneBit; + // Combine them with relative rates + eoPropCombinedMonOp mutation(mutationBitFlip, bitFlipRate); + mutation.add(mutationOneBit, oneBitRate, true); + + // The operators are encapsulated into an eoTRansform object + eoSGATransform transform(xover, pCross, mutation, pMut); + +// STOP + ////////////////////////////////////// + // termination condition see FirstBitEA.cpp + ///////////////////////////////////// + eoGenContinue genCont(maxGen); + eoSteadyFitContinue steadyCont(minGen, steadyGen); + eoFitContinue fitCont(vecSize); + eoCombinedContinue continuator(genCont); + continuator.add(steadyCont); + continuator.add(fitCont); + + +// CHECKPOINT + // but now you want to make many different things every generation + // (e.g. statistics, plots, ...). + // the class eoCheckPoint is dedicated to just that: + + // Declare a checkpoint (from a continuator: an eoCheckPoint + // IS AN eoContinue and will be called in the loop of all algorithms) + eoCheckPoint checkpoint(continuator); + + // Create a counter parameter + eoValueParam generationCounter(0, "Gen."); + + // Create an incrementor (sub-class of eoUpdater). Note that the + // parameter's value is passed by reference, + // so every time the incrementer is updated (every generation), + // the data in generationCounter will change. + eoIncrementor increment(generationCounter.value()); + + // Add it to the checkpoint, + // so the counter is updated (here, incremented) every generation + checkpoint.add(increment); + + // now some statistics on the population: + // Best fitness in population + eoBestFitnessStat bestStat; + eoAverageStat averageStat; + // Second moment stats: average and stdev + eoSecondMomentStats SecondStat; + + // Add them to the checkpoint to get them called at the appropriate time + checkpoint.add(bestStat); + checkpoint.add(averageStat); + checkpoint.add(SecondStat); + + // The Stdout monitor will print parameters to the screen ... + eoStdoutMonitor monitor(false); + + // when called by the checkpoint (i.e. at every generation) + checkpoint.add(monitor); + + // the monitor will output a series of parameters: add them + monitor.add(generationCounter); + monitor.add(eval); // because now eval is an eoEvalFuncCounter! + monitor.add(bestStat); + monitor.add(SecondStat); + + // A file monitor: will print parameters to ... a File, yes, you got it! + eoFileMonitor fileMonitor("stats.xg", " "); + eoGnuplot1DMonitor gnuMonitor("best_average.xg"); + + // the checkpoint mechanism can handle multiple monitors + checkpoint.add(fileMonitor); + checkpoint.add(gnuMonitor); + + // the fileMonitor can monitor parameters, too, but you must tell it! + fileMonitor.add(generationCounter); + fileMonitor.add(bestStat); + fileMonitor.add(SecondStat); + // the fileMonitor can monitor parameters, too, but you must tell it! + gnuMonitor.add(eval); + gnuMonitor.add(bestStat); + gnuMonitor.add(averageStat); + + // Last type of item the eoCheckpoint can handle: state savers: + eoState outState; + // Register the algorithm into the state (so it has something to save!!) + outState.registerObject(rng); + outState.registerObject(pop); + + // and feed the state to state savers + // save state every 100th generation + eoCountedStateSaver stateSaver1(100, outState, "generation"); + // save state every 1 seconds + eoTimedStateSaver stateSaver2(1, outState, "time"); + + // Don't forget to add the two savers to the checkpoint + checkpoint.add(stateSaver1); + checkpoint.add(stateSaver2); + // and that's it for the (control and) output + +// GENERATION + ///////////////////////////////////////// + // the algorithm + //////////////////////////////////////// + + // Easy EA requires + // selection, transformation, eval, replacement, and stopping criterion + eoEasyEA gga(checkpoint, eval, select, transform, replace); + + // Apply algo to pop - that's it! + gga(pop); + +// OUTPUT + // Print (sorted) intial population + pop.sort(); + cout << "FINAL Population\n" << pop << endl; +// GENERAL +} + +// A main that catches the exceptions +int main(int argc, char **argv) +{ +#ifdef _MSC_VER + int flag = _CrtSetDbgFlag(_CRTDBG_LEAK_CHECK_DF); + flag |= _CRTDBG_LEAK_CHECK_DF; + _CrtSetDbgFlag(flag); +// _CrtSetBreakAlloc(100); +#endif + + try + { + main_function(argc, argv); + } + catch(exception& e) + { + cout << "Exception: " << e.what() << '\n'; + } + + return 1; +} diff --git a/eo/tutorial/html/EA_tutorial.jpg b/eo/tutorial/html/EA_tutorial.jpg new file mode 100644 index 0000000000000000000000000000000000000000..4a63e1ec75f73531eda46eaede45206f7b5a1cfe GIT binary patch literal 53765 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 + + + + + FirstBitEA.cpp + + + +Back to Lesson 2 - Tutorial +main page - Top-Down page - Bottom-up +page - Programming hints - EO +documentation +
+
+
+

+FirstBitEA.cpp

+Click on the figure to see the corresponding code.
+In the code, the colors are meaningfull
+The actual code is in boldface and the comment in normal face. +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
  + + + + + +
+//-----------------------------------------------------------------------------
+// FirstBitEA.cpp
+//-----------------------------------------------------------------------------
+//*
+// Still an instance of a VERY simple Bitstring Genetic Algorithm
+// (see FirstBitGA.cpp) but now with  Breeder - and Combined Ops
+//
+//-----------------------------------------------------------------------------
+// standard includes
+#include <stdexcept>  // runtime_error
+#include <iostream>    // cout
+#include <strstream>  // ostrstream, istrstream
+// the general include for eo
+#include <eo>
+
+
+ + + + +
+ +//-----------------------------------------------------------------------------
+// define your individuals
+typedef eoBin<double> Indi; // A bitstring with fitness double
+
+
+ + + + +
+ +//-----------------------------------------------------------------------------
+// a simple fitness function that computes the number of ones of a bitstring
+// Now in a separate file, and declared as binary_value(const vector<bool> &)
+#include "binary_value.h"
+
+
+ + + + +
+ +//-----------------------------------------------------------------------------
+void main_function(int argc, char **argv)
+{
+
+
+ + + + +
+ +  const unsigned int SEED = 42; // seed for random number generator
+  const unsigned int T_SIZE = 3; // size for tournament selection
+  const unsigned int VEC_SIZE = 8; // Number of bits in genotypes
+  const unsigned int POP_SIZE = 20; // Size of population
+  const unsigned int MAX_GEN = 500; // Maximum number of generation before STOP
+  const float CROSS_RATE = 0.8; // Crossover rate
+  const double P_MUT_PER_BIT = 0.01; // probability of bit-flip mutation
+  const float MUT_RATE = 1.0; // mutation rate
+  // some parameters for chosing among different operators
+  const double onePointRate = 0.5;        // rate for 1-pt Xover
+  const double twoPointsRate = 0.5;        // rate for 2-pt Xover
+  const double URate = 0.5;                      // rate for Uniform Xover
+  const double bitFlipRate = 0.5;          // rate for bit-flip mutation
+  const double oneBitRate = 0.5;            // rate for one-bit mutation
+
+
+ + + + +
+ +  //////////////////////////
+  //  Random seed
+  //////////////////////////
+  //reproducible random seed: if you don't change SEED above,
+  // you'll aways get the same result, NOT a random run
+  rng.reseed(SEED);
+
+
+ + + + +
+ +  /////////////////////////////
+  // Fitness function
+  ////////////////////////////
+  // Evaluation: from a plain C++ fn to an EvalFunc Object
+  // you need to give the full description of the function
+  eoEvalFuncPtr<Indi, double, const vector<bool>& > eval(  binary_value );
+
+
+ + + + +
+ +  ////////////////////////////////
+  // Initilisation of population
+  ////////////////////////////////
+  // based on boolean_generator class (see utils/rnd_generator.h)
+  eoInitFixedLength<Indi, boolean_generator>
+      random(VEC_SIZE, boolean_generator());
+  // Initialization of the population
+  eoPop<Indi> pop(POP_SIZE, random);
+  // and evaluate it in one loop
+  apply<Indi>(eval, pop); // STL syntax
+
+
+ + + + +
+ +  // sort pop before printing it!
+  pop.sort();
+  // Print (sorted) intial population (raw printout)
+  cout << "Initial Population" << endl;
+  cout << pop;
+
+
+ + + + +
+ +  /////////////////////////////////////
+  // selection and replacement
+  ////////////////////////////////////
+
+
+ + + + +
+ +  // The robust tournament selection
+  eoDetTournament<Indi> selectOne(T_SIZE);            // T_SIZE in [2,POP_SIZE]
+ +  // is now encapsulated in a eoSelectPerc (entage)
+  eoSelectPerc<Indi> select(selectOne);// by default rate==1
+
+
+ + + + +
+ +  // And we now have the full slection/replacement - though with
+  // no replacement (== generational replacement) at the moment :-)
+  eoNoReplacement<Indi> replace;
+
+
+ + + + +
+ +  //////////////////////////////////////
+  // The variation operators
+  //////////////////////////////////////
+
+
+ + + + +
+ +  // 1-point crossover for bitstring
+  eoBinCrossover<Indi> xover1;
+  // uniform crossover for bitstring
+  eoBinUxOver<Indi> xoverU;
+  // 2-pots xover
+  eoBinNxOver<Indi> xover2(2);
+  // Combine them with relative rates
+  eoPropCombinedQuadOp<Indi> xover(xover1, onePointRate);
+  xover.add(xoverU, URate);
+  xover.add(xover2, twoPointsRate, true);
+
+
+ + + + +
+ +  
+  // standard bit-flip mutation for bitstring
+  eoBinMutation<Indi>  mutationBitFlip(P_MUT_PER_BIT);
+  // mutate exactly 1 bit per individual
+  eoDetBitFlip<Indi> mutationOneBit;
+  // Combine them with relative rates
+  eoPropCombinedMonOp<Indi> mutation(mutationBitFlip, bitFlipRate);
+  mutation.add(mutationOneBit, oneBitRate, true);
+  
+ +  // The operators are  encapsulated into an eoTRansform object
+  eoSGATransform<Indi> transform(xover, CROSS_RATE, mutation, MUT_RATE);
+
+
+ + + + +
+ + +
+ + + + +
+ +  //////////////////////////////////////
+  // termination conditions: use more than one
+  /////////////////////////////////////
+  // stop after MAX_GEN generations
+  eoGenContinue<Indi> genCont(MAX_GEN);
+  // do MIN_GEN gen., then stop after STEADY_GEN gen. without improvement
+  eoSteadyFitContinue<Indi> steadyCont(MIN_GEN, STEADY_GEN);
+  // stop when fitness reaches a target (here VEC_SIZE)
+  eoFitContinue<Indi> fitCont(0);
+  // do stop when one of the above says so
+  eoCombinedContinue<Indi> continuator(genCont);
+  continuator.add(steadyCont);
+  continuator.add(fitCont);
+
+
+ + + + +
+ +  /////////////////////////////////////////
+  // the algorithm
+  ////////////////////////////////////////
+  // Easy EA requires
+  // selection, transformation, eval, replacement, and stopping criterion
+  eoEasyEA<Indi> gga(continuator, eval, select, transform, replace);
+  // Apply algo to pop - that's it!
+  gga(pop);
+  
+
+
+ + + + +
+ +  // Print (sorted) intial population
+  pop.sort();
+  cout << "FINAL Population\n" << pop << endl;
+
+
+ + + + +
+ +}
+// A main that catches the exceptions
+int main(int argc, char **argv)
+{
+#ifdef _MSC_VER
+  //  rng.reseed(42);
+      int flag = _CrtSetDbgFlag(_CRTDBG_LEAK_CHECK_DF);
+        flag |= _CRTDBG_LEAK_CHECK_DF;
+      _CrtSetDbgFlag(flag);
+//    _CrtSetBreakAlloc(100);
+#endif
+      try
+      {
+              main_function(argc, argv);
+      }
+      catch(exception& e)
+      {
+              cout << "Exception: " << e.what() << '\n';
+      }
+      return 1;
+}
+
+
Back to Lesson 2 - Tutorial +main page - Top-Down page - Bottom-up +page - Programming hints - EO +documentation +
+
+Marc Schoenauer
+
Last +modified: Sun Nov 19 22:26:27 2000 + + + diff --git a/eo/tutorial/html/FirstBitGA.html b/eo/tutorial/html/FirstBitGA.html new file mode 100644 index 000000000..05e859e92 --- /dev/null +++ b/eo/tutorial/html/FirstBitGA.html @@ -0,0 +1,350 @@ + + + + + + FirstBitGA.html + + + +Back to Lesson 1 - Tutorial +main page - Top-Down page - Bottom-up +page - Programming hints - EO +documentation +
+
+
+

+FirstBitGA.html

+Click on the figure to see the corresponding code.
+In the code, the colors are meaningfull
+The actual code is in boldface and the comment in normal face. +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
  + + + + + +
+//-----------------------------------------------------------------------------
+// FirstBitGA.cpp
+//-----------------------------------------------------------------------------
+//*
+// An instance of a VERY simple Bitstring Genetic Algorithm
+//
+//-----------------------------------------------------------------------------
+// standard includes
+#include <stdexcept>  // runtime_error
+#include <iostream>    // cout
+#include <strstream>  // ostrstream, istrstream
+// the general include for eo
+#include <eo>
+
+
+ + + + +
+ +//-----------------------------------------------------------------------------
+// define your individuals
+typedef eoBin<double> Indi;        // A bitstring with fitness double
+
+
+ + + + +
+ +//-----------------------------------------------------------------------------
+// a simple fitness function that computes the number of ones of a bitstring
+//  @param _indi A biststring individual
+ +double binary_value(const Indi & _indi)
+{
+  double sum = 0;
+  for (unsigned i = 0; i < _indi.size(); i++)
+      sum += _indi[i];
+  return sum;
+}
+
+
+ + + + +
+ +//-----------------------------------------------------------------------------
+void main_function(int argc, char **argv)
+{
+
+
+ + + + +
+ +  // all parameters are hard-coded!
+  const unsigned int SEED = 42;          // seed for random number generator
+  const unsigned int T_SIZE = 3;        // size for tournament selection
+  const unsigned int VEC_SIZE = 8;    // Number of bits in genotypes
+  const unsigned int POP_SIZE = 20;  // Size of population
+  const unsigned int MAX_GEN = 100;  // Maximum number of generation before STOP
+  const float CROSS_RATE = 0.8;          // Crossover rate
+  const double P_MUT_PER_BIT = 0.01; // probability of bit-flip mutation
+  const float MUT_RATE = 1.0;              // mutation rate
+
+
+ + + + +
+ + +  //////////////////////////
+  //  Random seed
+  //////////////////////////
+  //reproducible random seed: if you don't change SEED above,
+  // you'll aways get the same result, NOT a random run
+  rng.reseed(SEED);
+
+
+ + + + +
+ +  /////////////////////////////
+  // Fitness function
+  ////////////////////////////
+  // Evaluation: from a plain C++ fn to an EvalFunc Object
+  eoEvalFuncPtr<Indi> eval(  binary_value );
+
+
+ + + + +
+ +  ////////////////////////////////
+  // Initilisation of population
+  ////////////////////////////////
+  // declare the population
+  eoPop<Indi> pop;
+  // fill it!
+  for (unsigned int igeno=0; igeno<POP_SIZE; igeno++)
+      {
+          Indi v;                    // void individual, to be filled
+          for (unsigned ivar=0; ivar<VEC_SIZE; ivar++)
+              {
+                  bool r = rng.flip(); // new value, random in {0,1}
+                  v.push_back(r);          // append that random value to v
+              }
+          eval(v);                                // evaluate it
+          pop.push_back(v);              // and put it in the population
+      }
+
+
+ + + + +
+ +  // sort pop before printing it!
+  pop.sort();
+  // Print (sorted) intial population (raw printout)
+  cout << "Initial Population" << endl;
+  cout << pop;
+
+
+ + + + +
+ +  /////////////////////////////////////
+  // selection and replacement
+  ////////////////////////////////////
+
+
+ + + + +
+ +  // The robust tournament selection
+  eoDetTournament<Indi> select(T_SIZE);  // T_SIZE in [2,POP_SIZE]
+
+
+ + + + +
+ +  // The simple GA evolution engine uses generational replacement
+  // so no replacement procedure is needed
+
+
+ + + + +
+ + +
+ + + + +
+ +  //////////////////////////////////////
+  // The variation operators
+  //////////////////////////////////////
+
+
+ + + + +
+ +  // 1-point mutation for bitstring
+  eoBinCrossover<Indi> xover;
+
+
+ + + + +
+ +  
+  // standard bit-flip mutation for bitstring
+  eoBinMutation<Indi>  mutation(P_MUT_PER_BIT);
+
+
+ + + + +
+ +  //////////////////////////////////////
+  // termination condition
+  /////////////////////////////////////
+  // stop after MAX_GEN generations
+  eoGenContinue<Indi> continuator(MAX_GEN);
+  
+
+
+ + + + +
+ +  /////////////////////////////////////////
+  // the algorithm
+  ////////////////////////////////////////
+  // standard Generational GA requires as parameters
+  // selection, evaluation, crossover and mutation, stopping criterion
+
+  eoSGA<Indi> gga(select, xover, CROSS_RATE, mutation, MUT_RATE,
+                                  eval, continuator);
+  // Apply algo to pop - that's it!
+  gga(pop);
+  
+
+
+ + + + +
+ +  // Print (sorted) intial population
+  pop.sort();
+  cout << "FINAL Population\n" << pop << endl;
+
+
+ + + + +
+ +}
+ // A main that catches the exceptions
+int main(int argc, char **argv)
+{
+#ifdef _MSC_VER
+  //  rng.reseed(42);
+      int flag = _CrtSetDbgFlag(_CRTDBG_LEAK_CHECK_DF);
+        flag |= _CRTDBG_LEAK_CHECK_DF;
+      _CrtSetDbgFlag(flag);
+//    _CrtSetBreakAlloc(100);
+#endif
+      try
+      {
+              main_function(argc, argv);
+      }
+      catch(exception& e)
+      {
+              cout << "Exception: " << e.what() << '\n';
+      }
+      return 1;
+}
+
+
Back to Lesson 1 - Tutorial +main page - Top-Down page - Bottom-up +page - Programming hints - EO +documentation +
+
+Marc Schoenauer
+
Last +modified: Sun Nov 19 08:31:26 2000 + + + diff --git a/eo/tutorial/html/FirstRealEA.html b/eo/tutorial/html/FirstRealEA.html new file mode 100644 index 000000000..9b0372fd0 --- /dev/null +++ b/eo/tutorial/html/FirstRealEA.html @@ -0,0 +1,366 @@ + + + + + + FirstRealEA.cpp + + +Back to Lesson 2 - Tutorial +main page - Top-Down page - Bottom-up +page - Programming hints - EO +documentation +
+
+
+

+FirstRealEA.cpp

+Click on the figure to see the corresponding code.
+In the code, the colors are meaningfull
+The actual code is in boldface and the comment in normal face. +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
  + + + + + +
+//-----------------------------------------------------------------------------
+// FirstRealEA.cpp
+//-----------------------------------------------------------------------------
+//*
+// Still an instance of a VERY simple Real-coded  Genetic Algorithm
+// (see FirstBitGA.cpp) but now with  Breeder - and Combined Ops
+//
+//-----------------------------------------------------------------------------
+// standard includes
+#include <stdexcept>  // runtime_error
+#include <iostream>    // cout
+#include <strstream>  // ostrstream, istrstream
+// the general include for eo
+#include <eo>
+
+
+ + + + +
+ +//-----------------------------------------------------------------------------
+// define your individuals
+typedef eoReal<double> Indi;
+
+
+ + + + +
+ +//-----------------------------------------------------------------------------
+// a simple fitness function that computes the euclidian norm of a real vector
+// Now in a separate file, and declared as binary_value(const vector<bool> &)
+#include "real_value.h"
+
+
+ + + + +
+ +//-----------------------------------------------------------------------------
+void main_function(int argc, char **argv)
+{
+
+
+ + + + +
+ +  const unsigned int SEED = 42; // seed for random number generator
+  const unsigned int T_SIZE = 3; // size for tournament selection
+  const unsigned int VEC_SIZE = 8; // Number of object variables in genotypes
+  const unsigned int POP_SIZE = 20; // Size of population
+  const unsigned int MAX_GEN = 500; // Maximum number of generation before STOP
+  const unsigned int MIN_GEN = 10;  // Minimum number of generation before ...
+  const unsigned int STEADY_GEN = 50; // stop after STEADY_GEN gen. without improvelent
+  const float P_CROSS = 0.8; // Crossover probability
+  const float P_MUT = 0.5; // mutation probability
+  const double EPSILON = 0.01; // range for real uniform mutation
+  // some parameters for chosing among different operators
+  const double segmentRate = 0.5;        // rate for 1-pt Xover
+  const double arithmeticRate = 0.5;        // rate for 2-pt Xover
+  const double uniformMutRate = 0.5;          // rate for bit-flip mutation
+  const double detMutRate = 0.5;            // rate for one-bit mutation
+
+
+ + + + +
+ +  //////////////////////////
+  //  Random seed
+  //////////////////////////
+  //reproducible random seed: if you don't change SEED above,
+  // you'll aways get the same result, NOT a random run
+  rng.reseed(SEED);
+
+
+ + + + +
+ +  /////////////////////////////
+  // Fitness function
+  ////////////////////////////
+  // Evaluation: from a plain C++ fn to an EvalFunc Object
+  // you need to give the full description of the function
+  eoEvalFuncPtr<Indi, double, const vector<double>& > eval(  real_value );
+
+
+ + + + +
+ +  ////////////////////////////////
+  // Initilisation of population
+  ////////////////////////////////
+  // based on a uniform generator
+  eoInitFixedLength<Indi, uniform_generator<double> >
+          random(VEC_SIZE, uniform_generator<double>(-1.0, 1.0));
+    // Initialization of the population
+  eoPop<Indi> pop(POP_SIZE, random);
+
+  // and evaluate it in one loop
+  apply<Indi>(eval, pop); // STL syntax
+
+
+ + + + +
+ +  // sort pop before printing it!
+  pop.sort();
+  // Print (sorted) intial population (raw printout)
+  cout << "Initial Population" << endl;
+  cout << pop;
+
+
+ + + + +
+ +  /////////////////////////////////////
+  // selection and replacement
+  ////////////////////////////////////
+
+
+ + + + +
+ +  // The robust tournament selection
+  eoDetTournament<Indi> selectOne(T_SIZE);
+ +  // is now encapsulated in a eoSelectPerc (entage)
+  eoSelectPerc<Indi> select(selectOne);// by default rate==1
+
+
+ + + + +
+ +  // And we now have the full slection/replacement - though with
+  // no replacement (== generational replacement) at the moment :-)
+  eoNoReplacement<Indi> replace;
+
+
+ + + + +
+ +  //////////////////////////////////////
+  // The variation operators
+  //////////////////////////////////////
+
+
+ + + + +
+ +  // uniform chooce on segment made by the parents
+  eoSegmentCrossover<Indi> xoverS;
+  // uniform choice in hypercube built by the parents
+  eoArithmeticCrossover<Indi> xoverA;
+  // Combine them with relative rates
+  eoPropCombinedQuadOp<Indi> xover(xoverS, segmentRate);
+  xover.add(xoverA, arithmeticRate, true);
+
+
+ + + + +
+ +  
+  // offspring(i) uniformly chosen in [parent(i)-epsilon, parent(i)+epsilon]
+  eoUniformMutation<Indi>  mutationU(EPSILON);
+  // k (=1) coordinates of parents are uniformly modified
+  eoDetUniformMutation<Indi>  mutationD(EPSILON);
+  // Combine them with relative rates
+  eoPropCombinedMonOp<Indi> mutation(mutationU, uniformMutRate);
+  mutation.add(mutationD, detMutRate, true);
+  
+  // The operators are  encapsulated into an eoTRansform object
+  eoSGATransform<Indi> transform(xover, P_CROSS, mutation, P_MUT);
+
+
+ + + + +
+ + +
+ + + + +
+ +  //////////////////////////////////////
+  // termination conditions: use more than one
+  /////////////////////////////////////
+  // stop after MAX_GEN generations
+  eoGenContinue<Indi> genCont(MAX_GEN);
+  // do MIN_GEN gen., then stop after STEADY_GEN gen. without improvement
+  eoSteadyFitContinue<Indi> steadyCont(MIN_GEN, STEADY_GEN);
+  // stop when fitness reaches a target (here VEC_SIZE)
+  eoFitContinue<Indi> fitCont(0);
+  // do stop when one of the above says so
+  eoCombinedContinue<Indi> continuator(genCont);
+  continuator.add(steadyCont);
+  continuator.add(fitCont);
+
+
+ + + + +
+ +  /////////////////////////////////////////
+  // the algorithm
+  ////////////////////////////////////////
+  // Easy EA requires
+  // selection, transformation, eval, replacement, and stopping criterion
+  eoEasyEA<Indi> gga(continuator, eval, select, transform, replace);
+  // Apply algo to pop - that's it!
+  cout << "\n              Here we go\n\n";
+  gga(pop);
+  
+
+
+ + + + +
+ +  // Print (sorted) intial population
+  pop.sort();
+  cout << "FINAL Population\n" << pop << endl;
+
+
+ + + + +
+ +}
+// A main that catches the exceptions
+int main(int argc, char **argv)
+{
+#ifdef _MSC_VER
+  //  rng.reseed(42);
+      int flag = _CrtSetDbgFlag(_CRTDBG_LEAK_CHECK_DF);
+        flag |= _CRTDBG_LEAK_CHECK_DF;
+      _CrtSetDbgFlag(flag);
+//    _CrtSetBreakAlloc(100);
+#endif
+      try
+      {
+              main_function(argc, argv);
+      }
+      catch(exception& e)
+      {
+              cout << "Exception: " << e.what() << '\n';
+      }
+      return 1;
+}
+
+
Back to Lesson 2 - Tutorial +main page - Top-Down page - Bottom-up +page - Programming hints - EO +documentation +
+
+Marc Schoenauer
+
Last +modified: Wed Nov 29 07:38:36 2000 + + + diff --git a/eo/tutorial/html/FirstRealGA.html b/eo/tutorial/html/FirstRealGA.html new file mode 100644 index 000000000..eaeecc284 --- /dev/null +++ b/eo/tutorial/html/FirstRealGA.html @@ -0,0 +1,349 @@ + + + + + + ../FirstRealGA.html + + + +Back to Lesson 1 - Tutorial +main page - Top-Down page - Bottom-up +page - Programming hints - EO +documentation +
+
+
+

+../FirstRealGA.html

+Click on the figure to see the corresponding code.
+In the code, the colors are meaningfull
+The actual code is in boldface and the comment in normal face. +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
  + + + + + +
+//-----------------------------------------------------------------------------
+// FirstRealGA.cpp
+//-----------------------------------------------------------------------------
+//*
+// An instance of a VERY simple Real-coded Genetic Algorithm
+//
+//-----------------------------------------------------------------------------
+// standard includes
+#include <stdexcept>  // runtime_error
+#include <iostream>    // cout
+#include <strstream>  // ostrstream, istrstream
+// the general include for eo
+#include <eo>
+
+
+ + + + +
+ +//-----------------------------------------------------------------------------
+// define your individuals
+ typedef eoReal<double> Indi;
+
+
+ + + + +
+ +//-----------------------------------------------------------------------------
+// a simple fitness function that computes the euclidian norm of a real vector
+//      @param _indi A real-valued individual
+ +double real_value(const Indi & _indi)
+{
+  double sum = 0;
+  for (unsigned i = 0; i < _indi.size(); i++)
+          sum += _indi[i]*_indi[i];
+  return (-sum);                      // maximizing only
+}
+
+
+ + + + +
+ +//-----------------------------------------------------------------------------
+void main_function(int argc, char **argv)
+{
+
+
+ + + + +
+ +  // all parameters are hard-coded!
+  const unsigned int SEED = 42; // seed for random number generator
+  const unsigned int VEC_SIZE = 8; // Number of object variables in genotypes
+  const unsigned int POP_SIZE = 20; // Size of population
+  const unsigned int T_SIZE = 3; // size for tournament selection
+  const unsigned int MAX_GEN = 500; // Maximum number of generation before STOP
+  const float CROSS_RATE = 0.8; // Crossover rate
+  const double EPSILON = 0.01;  // range for real uniform mutation
+  const float MUT_RATE = 0.5;    // mutation rate
+
+
+ + + + +
+ + +  //////////////////////////
+  //  Random seed
+  //////////////////////////
+  //reproducible random seed: if you don't change SEED above,
+  // you'll aways get the same result, NOT a random run
+  rng.reseed(SEED);
+
+
+ + + + +
+ +  /////////////////////////////
+  // Fitness function
+  ////////////////////////////
+  // Evaluation: from a plain C++ fn to an EvalFunc Object
+  eoEvalFuncPtr<Indi> eval(  real_value );
+
+
+ + + + +
+ +  ////////////////////////////////
+  // Initilisation of population
+  ////////////////////////////////
+  // declare the population
+  eoPop<Indi> pop;
+  // fill it!
+  for (unsigned int igeno=0; igeno<POP_SIZE; igeno++)
+      {
+          Indi v;                  // void individual, to be filled
+          for (unsigned ivar=0; ivar<VEC_SIZE; ivar++)
+              {
+                  double r = 2*rng.uniform() - 1; // new value, random in [-1,1)
+                  v.push_back(r);            // append that random value to v
+              }
+          eval(v);                                  // evaluate it
+          pop.push_back(v);                // and put it in the population
+      }
+
+
+ + + + +
+ +  // sort pop before printing it!
+  pop.sort();
+  // Print (sorted) intial population (raw printout)
+  cout << "Initial Population" << endl;
+  cout << pop;
+
+
+ + + + +
+ +  /////////////////////////////////////
+  // selection and replacement
+  ////////////////////////////////////
+
+
+ + + + +
+ +  // The robust tournament selection
+  eoDetTournament<Indi> select(T_SIZE);            // T_SIZE in [2,POP_SIZE]
+
+
+ + + + +
+ +  // eoSGA uses generational replacement by default
+  // so no replacement procedure has to be given
+
+
+ + + + +
+ + +
+ + + + +
+ +  //////////////////////////////////////
+  // termination condition
+  /////////////////////////////////////
+  // stop after MAX_GEN generations
+  eoGenContinue<Indi> continuator(MAX_GEN);
+  
+
+
+ + + + +
+ +  //////////////////////////////////////
+  // The variation operators
+  //////////////////////////////////////
+
+
+ + + + +
+ +  // offspring(i) uniformly chosen in [parent(i)-epsilon, parent(i)+epsilon]
+  eoUniformMutation<Indi>  mutation(EPSILON);
+
+
+ + + + +
+ +  // offspring(i) is a linear combination of parent(i)
+  eoArithmeticCrossover<Indi> xover;
+
+
+ + + + +
+ +  /////////////////////////////////////////
+  // the algorithm
+  ////////////////////////////////////////
+  // standard Generational GA requires
+  // selection, evaluation, crossover and mutation, stopping criterion
+
+  eoSGA<Indi> gga(select, xover, CROSS_RATE, mutation, MUT_RATE,
+                                    eval, continuator);
+  // Apply algo to pop - that's it!
+  gga(pop);
+  
+
+
+ + + + +
+ +  // Print (sorted) intial population
+  pop.sort();
+  cout << "FINAL Population\n" << pop << endl;
+
+
+ + + + +
+ +}
+// A main that catches the exceptions
+int main(int argc, char **argv)
+{
+#ifdef _MSC_VER
+  //  rng.reseed(42);
+      int flag = _CrtSetDbgFlag(_CRTDBG_LEAK_CHECK_DF);
+        flag |= _CRTDBG_LEAK_CHECK_DF;
+      _CrtSetDbgFlag(flag);
+//    _CrtSetBreakAlloc(100);
+#endif
+      try
+      {
+              main_function(argc, argv);
+      }
+      catch(exception& e)
+      {
+              cout << "Exception: " << e.what() << '\n';
+      }
+      return 1;
+}
+
+
Back to Lesson 1 - Tutorial +main page - Top-Down page - Bottom-up +page - Programming hints - EO +documentation +
+
+Marc Schoenauer
+
Last +modified: Sun Nov 19 08:31:29 2000 + + + diff --git a/eo/tutorial/html/FirstRealGA_old.html b/eo/tutorial/html/FirstRealGA_old.html new file mode 100644 index 000000000..0609d8c64 --- /dev/null +++ b/eo/tutorial/html/FirstRealGA_old.html @@ -0,0 +1,278 @@ + + + + + + First Real GA + + +Back to Lesson 1 - Tutorial +main page - Top-Down page - Bottom-up +page - Programming hints - EO +documentation +
+
+
+

+A First Real GA

+Click on the figure to see the corresponding code. Tutorial comments are +in variable length fonts, after the code. +
+

+ +

//----------------------------------------------------------------------------- +

#include +<stdexcept > // runtime_error +

//----------------------------------------------------------------------------- +
// FirstRealGA.cpp +
//----------------------------------------------------------------------------- +
//* +
// An instance of a +VERY simple Real-coded Genetic Algorithm +
// +
//----------------------------------------------------------------------------- +
// standard includes +

#include +<iostream>// cout +
#include +<strstream>// ostrstream, istrstream +

// the general include +for eo +

#include +<eo> +

// specific incluse, +as Real is not (yet) in the standard eo source dir +
#include +"eoeal.h" +
#include +"eoRealOp.h" +

//----------------------------------------------------------------------------- +
// define your individual: +

typedef +eoReal<double> Indi; +

You say here that you will be handling arrays +of doubles, whose fitness is a double +
Note that this makes Indi derive from STL +class vector<double> +
//----------------------------------------------------------------------------- +
/** a simple fitness +function that computes the euclidian norm of a real vector +
    @param +_indi A real-valued individual +
*/ +

double +real_value(const Indi & _indi) +
{ +
  +double sum = 0; +
  +for (unsigned i = 0; i < _indi.size(); i++) +
      +sum += _indi[i]*_indi[i]; +
  +return (-sum);   // maximizing +
} +

This simple function computes the sum of the squares of the variables +(remember Indi is here a vector of doubles) +
//----------------------------------------------------------------------------- +

void +main_function(int argc, char **argv) +
{ +
const +unsigned int SEED = 42;// seed for random number generator +
const +unsigned int VEC_SIZE = 8; // Number of object variables in genotypes +
const +unsigned int POP_SIZE = 20; // Size of population +
const +unsigned int T_SIZE = 3; // size for tournament selection +
const +unsigned int MAX_GEN = 500; // Maximum number of generation before STOP +
const +float CROSS_RATE = 0.8; // Crossover rate +
const +double EPSILON = 0.01; // range for real uniform mutation +
const +float MUT_RATE = 0.5; // mutation rate +
  +

////////////////////////// +
// Random seed +
////////////////////////// +
//reproducible random +seed: if you don't change SEED above, +
// you'll aways get +the same result, NOT a random run +
rng.reseed(SEED); +

///////////////////////////// +
// Fitness function +
//////////////////////////// +
// Evaluation: from +a plain C++ fn to an EvalFunc Object +
eoEvalFuncPtr<Indi> +eval( real_value ); +

This encapsulate the C++ function real_value into a functor +object +

//////////////////////////////// +
// Initilisation of +population +
//////////////////////////////// +

// declare the population +
eoPop<Indi> +pop; +

Declares a population +object, which is basically an STL +vector<Indi> +

// fill it! +
for +(unsigned int igeno=0; igeno<POP_SIZE; igeno++) +
  +{ +
    +Indi v; // generate a random individual +
    +for (unsigned ivar=0; ivar<VEC_SIZE; ivar++) +
      +{ +
        +double r = 2*rng.uniform() - 1; // new value, random in [-1,1) +
        +v.push_back(r); // +
      +} +
    +eval(v); // evaluate it +
    +pop.push_back(v); // and put it in the population +
  +} +

This initialization of the population is straightforward +
rng.uniform() generates a double uniformly +in [0,1), +
v.push_back simply appends its argument +at the end of STL vector v +
eval(v)evaluates individal v +the functor way, calling eval.operator()(v) +

// sort pop before printing +it! +
pop.sort(); +

// Print (sorted) intial +population (raw printout) +
cout +<< "Initial Population" << endl; +
cout +<< pop; +

If you looked at eoPop +inheritance diagram, you noticed that it derives from eoPrintable: +hence you can stream them using the << operator. Of course, Indis +are EO objects +, which also are eoPrintable, and the << operator for eoPop +uses the << operator for Indi. +

///////////////////////////////////// +
// +selection and replacement +
//////////////////////////////////// +
// The well-known roulette +selection +
// +The robust tournament selection +
eoDetTournament<Indi> +select(T_SIZE); // SIZE in [2,POP_SIZE] +

// +eoSGA uses generational replacement by default +
// so no replacement +procedure has to be given +

////////////////////////////////////// +
// termination condition +
///////////////////////////////////// +
// stop after MAX_GEN +generations +
eoGenContinue<Indi> +continuator(MAX_GEN); +

This class is called eoGenContinue +because the main loop of all eoAlgo +says ... while continuator(pop) +

////////////////////////////////////// +
// +The variation operators +
////////////////////////////////////// +

// +offspring(i) uniformly chosen in [parent(i)-epsilon, parent(i)+epsilon] +
eoUniformMutation<Indi>  +mutation(EPSILON); +
// +offspring(i) is a linear combination of parent(i) +
eoArithmeticCrossover<Indi> +xover; +

The variation operators are respectively +an eoMonOp +(unary operator) and an eoQuadOp +(binary operator that modifies both its arguments). +

///////////////////////////////////////// +
// the algorithm +
//////////////////////////////////////// +
// standard Generational +GA requires +
// selection, evaluation, +crossover and mutation, stopping criterion +
  +

eoSGA<Indi> +gga(select, xover, CROSS_RATE, mutation, MUT_RATE, +
eval, +continuator); +

// Apply algo to pop +- that's it! +
gga(pop); +

This simple algorithm of class eoSGA is a functor +object, and running the algorithm amounts to call the operator() +on the initial population! +

// Print (sorted) intial +population (raw printout) +
pop.sort(); +
cout +<< "FINAL Population\n" << pop << endl; +

that's it - just print the final population and you're done!!! +

} +

// +A main that catches the exceptions - do not modify! +
int +main(int argc, char **argv) +
{ +
#ifdef +_MSC_VER +
// +rng.reseed(42); +
int +flag = _CrtSetDbgFlag(_CRTDBG_LEAK_CHECK_DF); +
flag +|= _CRTDBG_LEAK_CHECK_DF; +
_CrtSetDbgFlag(flag); +
// +_CrtSetBreakAlloc(100); +
#endif +

try +
{ +
main_function(argc, +argv); +
} +
catch(exception& +e) +
{ +
cout +<< "Exception: " << e.what() << '\n'; +
} +

return +1; +
} +

+


Back to Lesson 1 - Tutorial +main page - Top-Down page - Bottom-up +page - Programming hints - EO +documentation +
+
+Marc Schoenauer
+ +
Last +modified: Wed Nov 6 17:22:43 CET 2000 + + diff --git a/eo/tutorial/html/Firstmerge.html b/eo/tutorial/html/Firstmerge.html new file mode 100644 index 000000000..1aca91949 --- /dev/null +++ b/eo/tutorial/html/Firstmerge.html @@ -0,0 +1,287 @@ + + + + + + Differences + + +Back to Lesson 1 - +Tutorial +main page - +Top-Down page - Bottom-up +page - Programming hints - EO +documentation +
+
+
+

+FirstBitGA and FirstRealGA: differences

+Below is a comparison of the codes for both algorithms (comments have been +removed). +
Warning: the pink +background here denotes the differences, not the section  of +the algorithm, which is only recalled by the color of the text! +
These differences are limited to +
    +
  • +the declaration of the type of the genotypes,
  • + +
  • +the fitness function (what did you expect +:-),
  • + +
  • +the initialization (and if you look carefully, +you'll find out that only a small part of the initialization is different, +as both genotypes are eoFixedLength objects) and of course
  • + +
  • +the choice of variation operators (including +the parameter for the mutation).
  • +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
#include +<stdexcept > +
#include <iostream> +
#include <strstream> +
#include <eo>
#include +<stdexcept > +
#include <iostream> +
#include <strstream> +
#include <eo>
typedef +eoReal<double> Indi;typedef +eoBin<double> Indi;
double +real_value(const Indi & _indi) +
{ +
  double +sum = 0; +
  for (unsigned +i = 0; i < _indi.size(); i++) +
      +sum += _indi[i]*_indi[i]; +
  return +(-sum);   // maximizing +
}
double +binary_value(const Indi & _indi) +
{ +
  double +sum = 0; +
  for (unsigned +i = 0; i < _indi.size(); i++) +
      +sum += _indi[i]; +
  return +(sum); +
}
void +main_function(int argc, char **argv) +
{ +
const unsigned +int SEED = 42; +
const unsigned +int VEC_SIZE = 8; +
const unsigned +int POP_SIZE = 20; +
const unsigned +int T_SIZE = 3; +
const unsigned +int MAX_GEN = 500; +
const float +CROSS_RATE = 0.8; +
const float +MUT_RATE = 0.5;
void +main_function(int argc, char **argv) +
{ +
const unsigned +int SEED = 42; +
const unsigned +int VEC_SIZE = 8; +
const unsigned +int POP_SIZE = 20; +
const unsigned +int T_SIZE = 3; +
const unsigned +int MAX_GEN = 500; +
const float +CROSS_RATE = 0.8; +
const float +MUT_RATE = 0.5;
const +double EPSILON = 0.01;const +double P_MUT_PER_BIT = 0.01;
eoEvalFuncPtr<Indi> +eval(real_value);eoEvalFuncPtr<Indi> +eval(binary_value);
eoPop<Indi> +pop; +
for (unsigned +int igeno=0; igeno<POP_SIZE; igeno++) +
  { +
    +Indi v; +
    +for (unsigned ivar=0; ivar<VEC_SIZE; ivar++) +
      +{
eoPop<Indi> +pop; +
for (unsigned +int igeno=0; igeno<POP_SIZE; igeno++) +
  { +
    +Indi v; +
    +for (unsigned ivar=0; ivar<VEC_SIZE; ivar++) +
      +{
        +double r = 2*rng.uniform() - 1;        +bool r = rng.flip(); 
        +v.push_back(r); // +
      +} +
    +eval(v); +
    +pop.push_back(v); +
  } +
pop.sort(); +
cout << +"Initial Population" << endl; +
cout << +pop; +
eoDetTournament<Indi> +select(T_SIZE); +
eoGenContinue<Indi> +continuator(MAX_GEN);
        +v.push_back(r); // +
      +} +
    +eval(v); +
    +pop.push_back(v); +
  } +
pop.sort(); +
cout << +"Initial Population" << endl; +
cout << +pop; +
eoDetTournament<Indi> +select(T_SIZE); +
eoGenContinue<Indi> +continuator(MAX_GEN);
eoUniformMutation<Indi>  +mutation(EPSILON); +
eoArithmeticCrossover<Indi> +xover;
eoBinMutation<Indi>  +mutation(P_MUT_PER_BIT); +
eoBinCrossover<Indi> +xover;
+
eoSGA<Indi> +gga(select, xover, CROSS_RATE, +
                +mutation, MUT_RATE, eval, continuator); +
gga(pop); +
pop.sort(); +
cout << +"FINAL Population\n" << pop << endl; +
} +
int main(int +argc, char **argv) +
{ +
... [technical +code removed] +
}
+
eoSGA<Indi> +gga(select, xover, CROSS_RATE, +
                +mutation, MUT_RATE, +
eval, continuator); +
gga(pop); +
pop.sort(); +
cout << +"FINAL Population\n" << pop << endl; +
} +
int main(int +argc, char **argv) +
{ +
[... technical +code removed ] +
}
+ +
Back to Lesson 1 - +Tutorial +main page - +Top-Down page - Bottom-up +page - Programming hints - EO +documentation +
+
+
+Marc Schoenauer
+ +
Last +modified: Tue Nov 7 07:49:47 CET 2000 + + diff --git a/eo/tutorial/html/NoWay.html b/eo/tutorial/html/NoWay.html new file mode 100644 index 000000000..607269531 --- /dev/null +++ b/eo/tutorial/html/NoWay.html @@ -0,0 +1,74 @@ + + + + + + Tutorial: Solutions + + +Tutorial main page - +Top-Down +page - Bottom-up page - Programming +hints -EO +documentation +
+
+
+

+Tutorial:

+ +
Solutions of exercises
+ +

No, we won't +provide +any +hypertext link directly to the correct code, so you get a chance +to find out the solution by yourself without immediately going there  +:-))) +

What you should do: +

    +
  • +copy the code of an example onto another name (e.g. mytest.cpp)
  • + +
  • +edit and modify mytest.cpp +according to the corresponding instructions of the exercise
  • + +
  • +compile mytest.cpp by typing +make mytest at system prompt, +and you will hopefully get an executable file named mytest +(for Unix systems: if eventually someone tells me how to do that in Windows, +apart that you'll probably end up with an executable file named mytest.exe...).
  • +
+ +
+
What you may do later: +

All solutions to exercises are in the same +sub-dir of the Tutorial directory than the example files (i.e. +Lesson1 for Lesson1, yes!). Hence you may browse through the code, eventually +modifying it, and then simply type, in the corresponding directory, +
... % make exerciseN +
which will compile file exerciseN.cpp +into executable exerciseN +(for Unix systems: if eventually someone tells me how to do that in Windows, +you'll probably end up with an executable file named exerciseN.exe). +

+


+
What you may not do: +
Complain that it does not work under Windows :-)
+ +
Tutorial main page - +Top-Down +page - Bottom-up page - Programming +hints - EO +documentation +
+
+
+Marc Schoenauer
+ +
Last +modified: Fri Nov 3 18:49:12 CET 2000 + + diff --git a/eo/tutorial/html/SecondBitEA.html b/eo/tutorial/html/SecondBitEA.html new file mode 100644 index 000000000..e5fa3868e --- /dev/null +++ b/eo/tutorial/html/SecondBitEA.html @@ -0,0 +1,612 @@ + + + + + + SecondBitEA.cpp + + + +Back to Lesson 3 - Tutorial +main page - Top-Down page - Bottom-up +page - Programming hints - EO +documentation +
+
+
+

+SecondBitEA.cpp

+Click on the figure to see the corresponding code. +
In the code, the colors are meaningfull +
The actual code is in boldface and the comment in normal face. +

For this particular program, as all new lines are concerned with program +parameter input and information output, the font +color for program-parameter-related sections will refer +to the section where the parameters are used whereas the background +color will remain blue. +

+
+ + + + +
//----------------------------------------------------------------------------- +
// SecondGA.cpp +
//----------------------------------------------------------------------------- +
//* +
// Same code than FirstBitEA as far as Evolutionary +Computation is concerned +
// but now you learn to enter the parameters +in a more flexible way +
// and to twidle the output to your preferences! +
//----------------------------------------------------------------------------- +
// standard includes +
#include <stdexcept>  // runtime_error  +
#include <iostream>   // +cout +
#include <strstream>  // ostrstream, +istrstream +
#include <fstream> +
// the general include for eo +
#include <eo> +
// specific includes +
#include "eoSGATransform.h" +
#include "eoPropCombinedOp.h"
+ + + + + +
#include "binary_value.h"
+ + + + + +
//----------------------------------------------------------------------------- +
// define your genotype and fitness types +
typedef eoBin<double> Indi;
+ + + + + +
//----------------------------------------------------------------------------- +
// instead of having all values of useful +parameters as constants, read them: +
// either on the command line (--option=value +or -o=value) +
//        +or in a parameter file (same syntax, order independent,  +
//                                                        +# = usual comment character  +
//        +or in the environment (TODO) +
// note that the parameters are passed by +reference so they can be updated +
void read_param(int argc, char *argv[],  +
uint32 & +_seed, +
unsigned int & _vecSize, +
unsigned int & _popSize, +
unsigned int & _tSize, +
double & _pCross, +
double & _pMut, +
string & _load_name, +
unsigned int & _maxGen, +
unsigned int & _minGen, +
unsigned int & _steadyGen, +
double & _onePointRate,  +
double & _twoPointsRate,  +
double & _uRate,  +
double & _pMutPerBit,  +
double & _bitFlipRate,  +
double & _oneBitRate +
) +
+
// define a +parser from the command-line arguments +
     eoParser parser(argc, +argv); +
     // For each +parameter, define Parameters directly in the parser,  +
     // and assign +the value to the variable +
    +eoValueParam<uint32>& seedParam = parser.createParam<uint32>(time(0), +"seed", "Random number seed", 'S'); +
     +_seed = seedParam.value(); +

     eoValueParam<unsigned +int>& vecSizeParam = parser.createParam<unsigned int>(8, "vecSize", +"Genotype size",'V', "Representation"); +
     _vecSize = vecSizeParam.value(); +

     eoValueParam<unsigned +int>& popSizeParam = parser.createParam<unsigned int>(10, "popSize", +"Population size",'P', "Evolution"); +
     _popSize = popSizeParam.value(); +
     eoValueParam<unsigned +int>& tSizeParam = parser.createParam<unsigned int>(10, "tSize", +"Tournament size",'T', "Evolution"); +
     _tSize = tSizeParam.value(); +
+
    eoValueParam<string>& +load_nameParam = parser.createParam<string>("", "Load","A save file +to restart from",'L', "Persistence"); +
     _load_name = +load_nameParam.value(); +

     eoValueParam<unsigned +int>& maxGenParam = parser.createParam<unsigned int>(100, "maxGen", +"Maximum number of generations",'G', "Stopping criterion"); +
     _maxGen = maxGenParam.value(); +
     eoValueParam<unsigned +int>& minGenParam = parser.createParam<unsigned int>(100, "minGen", +"Minimum number of generations",'g', "Stopping criterion"); +
     _minGen = minGenParam.value(); +
     eoValueParam<unsigned +int>& steadyGenParam = parser.createParam<unsigned int>(100, "steadyGen", +"Number of generations with no improvement",'s', "Stopping criterion"); +
     _steadyGen = +steadyGenParam.value(); +

     eoValueParam<double>& +pCrossParam = parser.createParam<double>(0.6, "pCross", "Probability +of Crossover", 'C', "Genetic Operators");  +
     _pCross = pCrossParam.value(); +
     eoValueParam<double>& +pMutParam = parser.createParam<double>(0.1, "pMut", "Probability of +Mutation", 'M', "Genetic Operators"); +
     _pMut = pMutParam.value(); +
     eoValueParam<double>& +onePointRateParam = parser.createParam<double>(1, "onePointRate", "Relative +rate for one point crossover", '1', "Genetic Operators"); +
     _onePointRate += onePointRateParam.value(); +
     eoValueParam<double>& +twoPointsRateParam = parser.createParam<double>(1, "twoPointRate", "Relative +rate for two point crossover", '2', "Genetic Operators"); +
     _twoPointsRate += twoPointsRateParam.value(); +
     eoValueParam<double>& +uRateParam = parser.createParam<double>(2, "uRate", "Relative rate for +uniform crossover", 'U', "Genetic Operators"); +
     _uRate =  +uRateParam.value(); +
     eoValueParam<double>& +pMutPerBitParam = parser.createParam<double>(0.01, "pMutPerBit", "Probability +of flipping 1 bit in bit-flip mutation", 'b', "Genetic Operators"); +
     _pMutPerBit = +pMutPerBitParam.value(); +
     eoValueParam<double>& +bitFlipRateParam = parser.createParam<double>(0.01, "bitFlipRate", "Relative +rate for bit-flip mutation", 'B', "Genetic Operators"); +
     _bitFlipRate +=  bitFlipRateParam.value(); +
     eoValueParam<double>& +oneBitRateParam = parser.createParam<double>(0.01, "oneBitRate", "Relative +rate for deterministic bit-flip mutation", 'D', "Genetic Operators"); +
         +_oneBitRate = oneBitRateParam.value(); +

     // the name +of the "status" file where all actual parameter values will be saved +
     string str_status += parser.ProgramName() + ".status"; +
     eoValueParam<string>& +status_nameParam = parser.createParam<string>(str_status.c_str(), "status","Status +file",'S', "Persistence"); +
   // do the following AFTER +ALL PARAMETERS HAVE BEEN PROCESSED +
   // i.e. in case you need +parameters somewhere else, postpone these +
     if (parser.userNeedsHelp()) +
         +{ +
             +parser.printHelp(cout); +
             +exit(1); +
         +} +
     if (status_nameParam.value() +!= "") +
         +{ +
ofstream os(status_nameParam.value().c_str()); +
os << parser; // and you can +use that file as parameter file +
         +} +
}

+ + + + + +
// now the main_function: nothing changed, +except input/output +
void main_function(int argc, char **argv) +
{
+ + + + + +
   +uint32 seed; +
   // decription of genotype +
   unsigned int vecSize; +
   // parameters for evolution +engine +
   unsigned int popSize; +
   unsigned int tSize; +
   // operators probabilities +at the algorithm level +
   double pCross; +
   double pMut; +
   // init and stop +
   string load_name; +
   unsigned int maxGen; +
   unsigned int minGen; +
   unsigned int steadyGen; +
   // rates for crossovers +
   double onePointRate; +
   double twoPointsRate; +
   double URate; +
   // rates and private +parameters for mutations; +
   double pMutPerBit; +
   double bitFlipRate; +
   double oneBitRate; +
   // Now read the parameters +of the program +
     read_param(argc, +argv, seed, vecSize, popSize, tSize, +
           +pCross, pMut, load_name, maxGen, minGen, steadyGen, +
           +onePointRate, twoPointsRate, URate,  +
           +pMutPerBit, bitFlipRate, oneBitRate );
+ + + + + +
 ///////////////////////////// +
 // Fitness function +
 //////////////////////////// +
 // Evaluation: from a plain +C++ fn to an EvalFunc Object ... +
 eoEvalFuncPtr<Indi, double, const +vector<bool>& > plainEval( binary_value ); +
// ... to an object +that counts the nb of actual evaluations +
 eoEvalFuncCounter<Indi> eval(plainEval);
+ + + + + +
 //////////////////////////////// +
 // Initilisation of population +
 //////////////////////////////// +
 // Either load or initialize +
 // create an empty pop +
 eoPop<Indi> pop; +
 // create a state for reading +
 eoState inState; // a state +for loading - WITHOUT the parser +
// register the rng +and the pop in the state, so they can be loaded, +
 // and the present run will +be the exact conitnuation of the saved run +
 // eventually with different +parameters +
 inState.registerObject(rng); +
 inState.registerObject(pop); +

if (load_name +!= "") +
     { +
         +inState.load(load_name); //  load the pop and the rng +
        +// the fitness is read in the file:  +
        +// do only evaluate the pop if the fitness has changed +
     } +
 else +
     { +
         +rng.reseed(seed); +
        +// a Indi random initializer +
        +// based on boolean_generator class (see utils/rnd_generator.h) +
         +eoInitFixedLength<Indi, boolean_generator>  +
random(vecSize, boolean_generator()); +
        +// Init pop from the randomizer: need to use the append function +
         +pop.append(popSize, random);  +
        +// and evaluate pop (STL syntax)  +
         +apply<Indi>(eval, pop); +
     } // end +of initializatio of the population

+ + + + + +
 // sort pop for pretty printout +
 pop.sort(); +
 // Print (sorted) intial population +(raw printout) +
 cout << "Initial Population" +<< endl << pop << endl;
+ + + + + +
 ///////////////////////////////////// +
 // selection and replacement +
 ////////////////////////////////////
+ + + + + +
 // The robust tournament selection +
 eoDetTournament<Indi> selectOne(tSize);           +// tSize in [2,POPSIZE] +
 // is now encapsulated in a +eoSelectPerc (entage) +
 eoSelectPerc<Indi> select(selectOne);// +by default rate==1
+ + + + + +
 // And we now have the full +slection/replacement - though with  +
 // no replacement (== generational +replacement) at the moment :-) +
 eoNoReplacement<Indi> replace; 
+ + + + + +
 ////////////////////////////////////// +
 // The variation operators +
 //////////////////////////////////////
+ + + + + +
 // 1-point crossover for bitstring +
 eoBinCrossover<Indi> xover1; +
 // uniform crossover for bitstring +
 eoBinUxOver<Indi> xoverU; +
 // 2-pots xover +
 eoBinNxOver<Indi> xover2(2); +
 // Combine them with relative +rates +
 eoPropCombinedQuadOp<Indi> xover(xover1, +onePointRate); +
 xover.add(xoverU, URate); +
 xover.add(xover2, twoPointsRate, +true);
+ + + + + +
 // standard bit-flip mutation +for bitstring +
 eoBinMutation<Indi>  mutationBitFlip(pMutPerBit); +
 // mutate exactly 1 bit per +individual +
 eoDetBitFlip<Indi> mutationOneBit;  +
 // Combine them with relative +rates +
 eoPropCombinedMonOp<Indi> mutation(mutationBitFlip, +bitFlipRate); +
 mutation.add(mutationOneBit, oneBitRate, +true); +
 // The operators are  encapsulated +into an eoTRansform object +
 eoSGATransform<Indi> transform(xover, +pCross, mutation, pMut);
+ + + + + +
 ////////////////////////////////////// +
 // termination condition see +FirstBitEA.cpp +
 ///////////////////////////////////// +
 eoGenContinue<Indi> genCont(maxGen); +
 eoSteadyFitContinue<Indi> steadyCont(minGen, +steadyGen); +
 eoFitContinue<Indi> fitCont(vecSize); +
 eoCombinedContinue<Indi> continuator(genCont); +
 continuator.add(steadyCont); +
 continuator.add(fitCont);
+ + + + + +
 // but now you want to make +many different things every generation  +
 // (e.g. statistics, plots, +...). +
 // the class eoCheckPoint is +dedicated to just that: +
 // Declare a checkpoint (from +a continuator: an eoCheckPoint  +
 // IS AN eoContinue and will +be called in the loop of all algorithms) +
 eoCheckPoint<Indi> checkpoint(continuator); +

    +// Create a counter parameter +
     eoValueParam<unsigned> +generationCounter(0, "Gen."); +

    +// Create an incrementor (sub-class of eoUpdater). Note that the  +
     // parameter's +value is passed by reference,  +
     // so every +time the incrementer is updated (every generation), +
     // the data +in generationCounter will change. +
     eoIncrementor<unsigned> +increment(generationCounter.value()); +
    +// Add it to the checkpoint,  +
     // so the +counter is updated (here, incremented) every generation +
     checkpoint.add(increment); +
    +// now some statistics on the population: +
     // Best fitness +in population +
     eoBestFitnessStat<Indi> +bestStat; +
     // Second +moment stats: average and stdev +
     eoSecondMomentStats<Indi> +SecondStat; +
    +// Add them to the checkpoint to get them called at the appropriate +time +
     checkpoint.add(bestStat); +
     checkpoint.add(SecondStat); +
     // The Stdout +monitor will print parameters to the screen ... +
     +eoStdoutMonitor monitor(false); +

     // when called +by the checkpoint (i.e. at every generation) +
     +checkpoint.add(monitor); +
     // the monitor +will output a series of parameters: add them  +
     +monitor.add(generationCounter); + +
     monitor.add(eval); +// +because now eval is an eoEvalFuncCounter! +
     monitor.add(bestStat); +
     monitor.add(SecondStat); +
     // A file +monitor: will print parameters to ... a File, yes, you got it! +
     eoFileMonitor +fileMonitor("stats.xg", " "); +

     // the checkpoint +mechanism can handle multiple monitors +
     checkpoint.add(fileMonitor); +
     // the fileMonitor +can monitor parameters, too, but you must tell it! +
     fileMonitor.add(generationCounter); +
     fileMonitor.add(bestStat); +
     fileMonitor.add(SecondStat); +
     // Last type +of item the eoCheckpoint can handle: state savers: +
     +eoState outState; +
     // Register +the algorithm into the state (so it has something to save!!) +
     +outState.registerObject(rng); +
     outState.registerObject(pop); +
     // and feed +the state to state savers +
    +// save state every 100th  generation +
     eoCountedStateSaver +stateSaver1(100, outState, "generation");  +
     // save state +every 1 seconds  +
     eoTimedStateSaver    +stateSaver2(1, outState, "time");  +
    +// Don't forget to add the two savers to the checkpoint +
     checkpoint.add(stateSaver1); +
     checkpoint.add(stateSaver2); +
     // and that's +it for the (control and) output

+ + + + + +
 ///////////////////////////////////////// +
 // the algorithm +
 //////////////////////////////////////// +
 // Easy EA requires  +
 // selection, transformation, +eval, replacement, and stopping criterion +
 eoEasyEA<Indi> gga(checkpoint, +eval, select, transform, replace); +
 // Apply algo to pop - that's +it! +
 gga(pop);
+ + + + + +
 // Print (sorted) final population +
 pop.sort(); +
 cout << "FINAL Population\n" +<< pop << endl;
+ + + + + +
} +
// A main that catches the exceptions +
int main(int argc, char **argv) +
{ +
#ifdef _MSC_VER +
     int flag = _CrtSetDbgFlag(_CRTDBG_LEAK_CHECK_DF); +
       flag +|= _CRTDBG_LEAK_CHECK_DF; +
     _CrtSetDbgFlag(flag); +
//    _CrtSetBreakAlloc(100); +
#endif +
     try +
     { +
             +main_function(argc, argv); +
     } +
     catch(exception& +e) +
     { +
             +cout << "Exception: " << e.what() << '\n'; +
     } +
     return 1; +
}
+ +


Back to Lesson 3 - Tutorial +main page - Top-Down page - Bottom-up +page - Programming hints - EO +documentation +
+
+Marc Schoenauer
+ +
Last modified: Sun Nov +26 09:31:04 2000 + + diff --git a/eo/tutorial/html/beige009.jpg b/eo/tutorial/html/beige009.jpg new file mode 100644 index 0000000000000000000000000000000000000000..594c01d8e1b01adbdd88852e6c591f789cf21d6e GIT binary patch literal 6643 zcmbtYcU05KxBn(VAWA}2S$av}7gvf@=~YMoi3Z;;3+Re~BnC;468Hg2m7>x@7U>{H zu;C)oi}a>~KoAfTq)8D&mxw^}qWj8u@4R=;JLla$?wor+cV<5Gz2`e~XL#ehX+X@u z4r2#^z#z~`&`AK`u|az0@T4G8Af7~4($&-kPFrKnLfF7}5&IqifB=5%-|Y`<>pKJp z|ImE(-KQ@0!#d25{ae64BES4F(16y}t9-y~smy`P+9vwac0^Ioe-(&QD zcr^ag^JC1fd>a7BeCGe7K$gD4|0Bfv|6t$e7WkVP7y$ED0l1Yn>532F9nGH(#G3@- z0TE$gVW_YO6e=QqxR?|i z4ww3_;8K5g5&ypoz-tA>g@In67XnfNz~Uf?IEdE?vf%SO1o|O-s^0~|Prtw+K_Ox2 z;UoOy{#OtLfFb`5iUA-25Ckj$J|rY4d${Tc12h3M(mJ{5R&S$KC|H!sDG@aGEU7l^Md!8_WMBw$A|xA)@SoYd*eGmS*%3hJUU+e?bfTPx<-yL#vwnU z_PK(xcBGf1S^RF`e5N}&=uIkH-D=ZW4s9~w*(AP;!`)O3dOjK9mYKV;eW!;koR<11 zZhVb+5q_{KRV&lIXfdK%OWMNW`ol}y^i7WwPFPC5G1;}XgdY4-7|ta_?{K+W<5B-a zp9{c`z*>4`4*KpC3Me=~Fw(-ad@|PM=!SKUHuqcchcWJfCv`+Zbc>7F2$1L9pUhrD zpN31@QQ@g_@eKFWQL6m=Vh0DGqiurymEH;T1tDRLLvc%)_s%Xi1wK>|M|CKOw3!PP zNZ@KGU1f9S;IUF3wtH1V9Pd(i0J2=LB8+Nr0yi3Nb0lw%Ma3~(?ksC;C39c77tWd7 zD|CzOJANTZW6IR)Aldj;cT9pk6y=^|{DS;>?iG36Da*dg(rt-~foxq-ou?1`#g6^N z{Utie2dUMZXqOhVg`4!0X*FwldCfG^kiZmwmF!g&7$i?$<{%z$8e<`eWc_$rJcaC) z1|X8A#0K%u=4#JD!*zPIE+!+vHP zks@}{LYD`eQ5j^EMU`B^UDmny1icW7LIu<_!NU8iAHekAA8IMZ>=t9rX&!v_3wu+R zaN1H$l&s37I{1DXUN|r-H^s!}S*?0mnx&<2F}9uNKn^TIFbhm49&?PPC4kre4~`Wf=Kl0vBV6+35}pGtl* zdY7t-%dTsB?J8#qzlqctw1kjNLj}4|j9EtMy`h%OpcM{;5QZ1}^{QfDaRrvBIr@78 z6{4F_YkhBw!@MFQMhs2+e5WoX%solUXiLZ8WjwK4<`8S{Pl&Olm0xui{f6p=sq7c5>j^@@GCzGTrdIy| zA^(vp`*5=C&3Y?$~YO3Q{$exa(+_Wb|x=^WzKj~_Ugf_<}Z#(LATAOW!gvZ)t z`KlbOCOKA5J{gR|HQTR^FW6v*l&uC>$~DIJa`=L^^72W~Y$rvuM310h)hFtom3^bw z0Pe^nz0JQRKPWnb2!F6h7?pCwm{{(7wM#~wc?Vf#dM(wc?_vCW5?sg4m7)aV2ZlH+ zP$o#GL3Q~U2jdh(nDj~fNEg*fR_-7RF-VIFpOj0~N`Lz7fb+0_#wsS8a-pcK#W)RF z(Eh9u_Z0>#m=a(Pp;29U!`q@IA&LPq9iHg%R!{a=ZQ>41R?s&P^UanA%x6}Y;|0rJ zL&v%-2l^g7+Zhhp_2N(=Wf<5Fsb{h(z25nkYQr_W=yX!Zxzon{zF-O_uo{zcKQ#rdXti zXf&yVBR%Gjh)MX_7sVK-+qoN{GOkvGyNFFrjd`+hbbcrIP7EoG`%xOfCMHwnU%Tj6p0p)rpWf9PHsYW$E`5KK7kWQGB2<^|6IkrX?~W{#TgA z7ZfTkM9k6Kuzody=D0#3VeWU{D4p@oGVR?TG=dgraK0(t~reE;SgF z!a*LO%wK)37HM%WJoVG1`(^&`Et*2D11Q}l>0W!9j$S88A#Xj6>GaAm`3AyN=pOZ) zG8&@qhu<_~BNiO!?bic!1#< zh;g)c;tkOuVoRO+_KGGa+uX)7J^9wk#M~4Dv0z{@?%c$lrkA>3^Qxj=WUkZQu#wN1 z_`}j(j%ea-p~$|tkOPU?4-(!yzz3;gey5F~xuF!p19H^00u!4PNui%JukXC>jG2s| zTq(e$c0^NY6XSMydB1&z)63GFu9vsb_nqi|#I*WYdvZn?p7~Y7)Co^LCXjf|O@7*h zmMi>CgC$qDZt+;E)@xn1uD}X{Z9ZktLY4U-Kz&}FIcF>c>I^OY0va|K)I-gb+ItPG zNev)mgQc4ZC9;rU{vVf?xq(2qmcFYU5rN2@Ke)P!{WHE zFW`%p^_#W?9#(&;AM9i5b2!+>t*1(GD0e>pXO&AB(n7{P8m&y?ayEYbF!Gt2p?ri? z_Grd8m5Y0=OBtGS)kCv-7$?U|49PW9Js$ASC?|1v%xq4hhw`&IPCZVkHes)^Zk>9U z^h{5@BE+oSuDwl_iG^ijN}Y$T$m`k%!2WmcAJ-{R4#~oW{xQm-E2fv zqEyZjbKwJ_0_zFw(kz=K#eCanIxN-XNt2kpc*$Xp(J}E)1#j1aPVz<^0?gE9f!c> z#$OsE$m)|@PJ(l64mQ9jdVJp6K2*LkW`O>$+!K0=Ouw?CL zJWd@H9ps3XKxYgVYMe6N>r6t=Y9w7RytfWHN6mWv*HG8TvdswU`#P&itbbpdu5xSY zOq=@4ip$Accq*0VE>pG(4(NnX(^#~MV`|PcXWsiggJ^X3pNUhD3m7JBuc4poa z_@SW(0*rWuaayfhP z;KIxoiOVUhofMqQDbK(v|GC~A#_W>AVu$w|ir?1y`R#n~44Vvu_P_P7vz(Q(}1ZuDLp(-6@@P|HBd={~lSSSgg!(-Kx-SRXsk;0Z8+-(D^5tACh`D`#Y-S`a$ev0 z=b~cvlybXjKk}3+CM;n`_4hVicVe=LDS56WLp$=VKnSREwkUuytm!4xhdd$2@>8A? zGdf$NkUT>6B`a#k!A+@@xAG z8NmZXt-lBj1qP!~$pW9IOsJtYDzA-HYT)R#OZ4WoqPiTW?5R^h+sEY2Mi^_Ptoi_~vY{?T`_fD$&}byBVfz^3y;pt8??nHnc7H zpT}a?1T8U+x8*K^;*0LiV-@p!O>4VQ0bFe4Q^@aZRF%I>^bnK&AiQ_N2EB&z8!L!# zu&VHUrfp*TDvUf*>(XIwAw?^hW_f_j+DTQcGWy_Pm;icTDt8PL$$U6bFjb*w zD?V=55*zcJDMs0WL>Js->KS9z<7stM)5vFOtRW>)PuN`7qhsSkb?LGL`45^`$9$_+ z5G$J)r{=Qc)V-jhTtWoL^g3qT9E2 zK&PIh$TYM)lE1|-f(ExGT?J*VSaXxpxiD+D;ZY7q-9K$OJzUthbSHJ%q$!7gO__OT z1@nUp%;#PMU$K|@S{fW2t61OI2tyw}OM1xm5Y3pIr~WB*nyn?O-JPy2`;sGYIBq&3t1gB~n?C#{b~0TpnAjlgHuOUkj%c_h=eN_7zmv6nLsv2+V%Ay3x#qqSl5(i{#v-EBHkSQX zETYuh)1)?|{#kVRH6Nu7u>lkDzdqFKx_dzbeb&rUV~|=pKp6R8&3yo$FH;)A=;;kPr~A}UuOm0oVv4)Hx}9%O zwI`V9iq)KLyEjMLyAUEaJsLBA*uf*ADrSFr{otJvM|41P92PZjp2&V;rCF$iPlBoi z1+0$HipSiyJ3|$E*3qZRLq@Cg51Pygj!AbdNmo;S%nzn3(kKMR+QB@n9^Qo3dd>$!d%P-uU=9bYs?KuRCSJEll0EUs8QS_;b)9 zEwb)aR$25=SwG?w{CSz3-q#f|spPO>D?D2gYQ`OOTc{I#a9DNB_^wU3;Bwg})luDb z2L!Z@yrZ)duA{9*adRu!PG$rn6r6 z_-N#Hjt^Q*|AU(iYlZH|_3PD1Y9b1i2wxGUHwFz7Y(v(uqM_O$8B_Wa;f}8B;iI%ccajx-hR1 z0`4k&`$zr9R?~DheWLxruH`_*)AcB{DP4-2Jz1Pkh%qh=PK`eE$JTa8(R9|H&`U-w zdcrQA{-A3>VYKbDobydJs*{AppEcf({8bcnH@MI~q2+Yh-4}28yXwn~%kp#%w66-f zlf{7)#U{Zh$j)`q%js|eV`_m*A+;e<_xcaDJ%bb!^MH{upU%uCFb@#?WPN5QI{+`) zss=b{s>oND74#3|a77nG>~_{DCU)r=8c#!cfSRO#=?mHBo^<`9TVWIv=bu04|!=r|z!g_ZU4duey*c7lodkjSwPH9lS?{QWy>9zyH%&AUxrD zhmWO@)9TIKImw)4)`Q_vO=8Ol3%tecdF88Y>$dF zh%ChT*0UDT+~JTWiwVP1%}mR8=1mXO+imn2>&6l^%oJxHd8G!PikmTxI^jyZB!v!H7VW{MIrE5h^>O$8h1 z52_@!5*s_xKEHCf9#}a0L5ptJg5VdijBW9{YaFn>03Ms+^wXu;O(YL!{CR;+6ImOc zX5TfsPx*x@C+(ej`kAg#(+uLJf)X@bHL=|! z@rsK6BPV=PZ0EIwV!f@77yhKLuFfCCg?OstcK4V9wu*vEXhSyUM|j=bvc{mkxm#_Y zoHXTboUNfMcQ&>v{MwJdhs9pv`Bk7}^T%1G>Vg7oB=UP- H-ur(A-Dy?` literal 0 HcmV?d00001 diff --git a/eo/tutorial/html/binary_value.html b/eo/tutorial/html/binary_value.html new file mode 100644 index 000000000..5fd4134c0 --- /dev/null +++ b/eo/tutorial/html/binary_value.html @@ -0,0 +1,57 @@ + + + + + + binary_value.h + + +Back to Lesson 2 - Tutorial +main page - Top-Down page - Bottom-up +page - Programming hints - EO +documentation +
+
+
+

+binary_value.h

+ + + + + +
#include <eo> +
//----------------------------------------------------------------------------- +
/** Just a simple function that takes binary +value of a chromosome and sets +
     the fitnes. +
     @param _chrom A +binary chromosome  +
*/
+ + + + + +
double binary_value(const vector<bool>& +_chrom) +
{ +
 double sum = 0; +
 for (unsigned i = 0; i < _chrom.size(); +i++) +
     sum += _chrom[i]; +
 return sum; +
}
+ +
Back to Lesson 2 - Tutorial +main page - Top-Down page - Bottom-up +page - Programming hints - EO +documentation +
+
+Marc Schoenauer
+ +
Last modified: Wed Nov +29 09:03:09 2000 + + diff --git a/eo/tutorial/html/costume.jpg b/eo/tutorial/html/costume.jpg new file mode 100644 index 0000000000000000000000000000000000000000..b29768e45c471a19b4a5dd956ee418995d2f05ec GIT binary patch literal 213921 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 Mlj + + + TITRE + + + +Tutorial main page - +Top-Down +page - Bottom-up page - Programming +hints - EO documentation +
+


+ + +
+

TITRE

+
+ + +

diff --git a/eo/tutorial/html/eoBottomUp.html b/eo/tutorial/html/eoBottomUp.html new file mode 100644 index 000000000..aa150ab50 --- /dev/null +++ b/eo/tutorial/html/eoBottomUp.html @@ -0,0 +1,74 @@ + + + + + + EO - The Bottom-Up approach + + +Tutorial main page - +Top-Down +page - Bottom-up page - Programming +hints - EO documentation +
+


+
+

+EO - Bottom-Up approach

+ +


Congratualtions - You have chosen the bottom-up approach!  +From here you will be allowed to browse into the different components of +an Evolutionary Algorithm, and to see how to program your favorite using +the EO library. + +

+Table of Content

+ +
+

+ +

Yes, this is the table of content of this part +of the EO tutorial. If you don't already know what this symbolic + representation of an EA means, you should try here. Otherwise, click on the figure +to go directly to the corresponding section of the tutorial. +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+


+
Tutorial main page - Top-Down +page - Bottom-up page - Programming +hints - EO documentation +
+
+
+Marc Schoenauer
+ +
Last +modified: Mon Oct 30 07:28:36 CET 2000 + + diff --git a/eo/tutorial/html/eoEngine.html b/eo/tutorial/html/eoEngine.html new file mode 100644 index 000000000..d7de5460c --- /dev/null +++ b/eo/tutorial/html/eoEngine.html @@ -0,0 +1,59 @@ + + + + + + Genetic Engine + + + + +
+

+Evolution Engine

+ +


Contents +

    +
  • +Introduction
  • + +
  • +Selection
  • + +
  • +Replacement
  • + +
  • +Popular evolution engines
  • +
+ +


The term evolution engine denotes the different parts that simulate +the Darwinism in Evolutionary Algorithms. +

+

The fittest individuals are more likely to +reproduce and survive.

+ +

Darwinism takes place in two different phases of an EA, though in many +popular variants, only one phase is activated. +

Selection is the Darwinistic choice of parents +that will be allowed to reproduce. +
Replacement takes place after reproduction, +and is the Darwinistic choice of those individuals that will survive, +i.e. become the parents of the next generation. +

Selection +
  +

Replacement +
  +

Popular +evolution engines +
  +
  +

+


+
+Marc Schoenauer
+ +
Last +modified: Mon Oct 30 18:15:17 CET 2000 + + diff --git a/eo/tutorial/html/eoEval.html b/eo/tutorial/html/eoEval.html new file mode 100644 index 000000000..7d61f7e74 --- /dev/null +++ b/eo/tutorial/html/eoEval.html @@ -0,0 +1,34 @@ + + + + Evaluation + + + +Tutorial main page - +Top-Down +page - Bottom-up page - Programming +hints - EO documentation +
+
+ +
+

Evaluation

+
+ + + +
+
+Tutorial main page - +Top-Down +page - Bottom-up page - Programming +hints - EO documentation +
+
Marc Schoenauer
+ + +Last modified: Mon Nov 6 10:54:33 CET 2000 + + + diff --git a/eo/tutorial/html/eoGeneration.html b/eo/tutorial/html/eoGeneration.html new file mode 100644 index 000000000..1c59d3726 --- /dev/null +++ b/eo/tutorial/html/eoGeneration.html @@ -0,0 +1,19 @@ + + + + Generation + + + +

Generation

+ + + +
+
Marc Schoenauer
+ + +Last modified: Mon Oct 30 19:29:29 CET 2000 + + + diff --git a/eo/tutorial/html/eoInit.html b/eo/tutorial/html/eoInit.html new file mode 100644 index 000000000..10fa0f44a --- /dev/null +++ b/eo/tutorial/html/eoInit.html @@ -0,0 +1,36 @@ + + + + Initialization + + +Tutorial main page - +Top-Down +page - Bottom-up page - Programming +hints - EO documentation +
+
+ + +
+

+Initialization

+ + + + + +
+
+Tutorial main page - Top-Down +page - Bottom-up page - Programming +hints - EO documentation +
+
+Marc Schoenauer
+ + +Last modified: Mon Nov 6 11:25:18 CET 2000 + + + diff --git a/eo/tutorial/html/eoIo.html b/eo/tutorial/html/eoIo.html new file mode 100644 index 000000000..4e37700f4 --- /dev/null +++ b/eo/tutorial/html/eoIo.html @@ -0,0 +1,25 @@ + + + + Input / Output + + + +

Input / Output

+ +

+ +

Stopping criteria

+ +

+ +

Displaying statistics

+ +
+
Marc Schoenauer
+ + +Last modified: Tue Oct 31 18:32:22 CET 2000 + + + diff --git a/eo/tutorial/html/eoLesson1.html b/eo/tutorial/html/eoLesson1.html new file mode 100644 index 000000000..e7bf1589e --- /dev/null +++ b/eo/tutorial/html/eoLesson1.html @@ -0,0 +1,413 @@ + + + + + + Tutorial: Lesson 1 + + +Lesson 2 - +Tutorial +main page - +Top-Down page - Bottom-up +page - Programming hints -EO +documentation +
+
+
+

+Tutorial: Lesson 1

+This lesson will let you +
    +
  • +run your first Evolutionary Algorithm written within +EO Library, choosing between evolving bitstrings, +or evolving vectors of real numbers,
  • + +
  • +browse through the code of these algorithms, or
  • + +
  • +follow the guided tour.
  • +
+Later you will be asked to +
    +
  • +write your own fitness function,
  • + +
  • +use different kinds of selection procedures +in the framework of a generational GA evolution engine,
  • + +
  • +check that EO let you separate the representation +from the evolution engine.
  • +
+ +

+I want to run an Evolutionary Algorithm +now

+You can choose to run a standard bitstring Genetic +Algorithm (as defined in Goldberg's book) or a standard real-valued +genetic algorithm, as proposed in Micahlewicz's book. +

If you have not already done what was recommended in the Tutorial +main page , do it NOW. Then go +to the Lesson1 sub-dir of the tutorial dir, and simply type at the system +prompt +

(myname@myhost) EOdir/Tutorial/Lesson1 % FirstRealGA +
or +
(myname@myhost) EOdir/Tutorial/Lesson1 % FirstBitGA +

and something should happen. +

+What is happening?

+At the moment, the FirstBitGA maximizes the +number of ones in the bitstring (also calls the OneMaxfunction, +whose solution is, as you can guess, +11111111), +and the FirstRealGA is maximizing (the default +action for EO is to maximize) the inverse of the sum (i.e. minimizing the +sum) of the square of its variables (also called the sphere +function, whose solution is ... all zeroes). +

And what you see on the screen when running one of these two programs +is, in each case, the initial and final population of an Evolutionary run, +one individual per line, its fitness first, then the number of items (bits +or real numbers) of the genotype, and the genotype itself. The final population +hopefully contains the solution in the discrete case, and is close to it +in the continuous case. +

You need now to take a look at either programs +by browsing alone through the  sources for FirstBitGA +and FirstRealGA, or follow the guided tour +below, or go directly to the exercises. +

+Browsing the code:

+ +
    +
  • +General includes:Like +all C-like code, the file starts with include directives (Bit +- Real). Apart from standard includes, +the spedific file to include is eo: +this is a file that contains the list of the most important EO files.
  • + +
      +
  • +Representation: +you then have to delclare the type of individuals you will be handling. +All evolution-related objects you will need are templatized w.r.t. the +type of individuals.
  • + + + +
  • +Fitness function: +the code for the fitness function is included in the file. It must take +as argument a reference to an individual (at the moment).
  • + +
      +
    • +Bit This function simply computes +the number of ones of the bitstring (it's called the OneMax function). +The optimum is of course the all-ones bitstring.
    • + +
    • +Real This function simply computes +the inverse of the sum of the squares of all variables (also called the +sphere function). The optimum is of course the all-zeroes vector.
    • + +
       
    + +
  • +Parameters: +all parameters of the algorithm are declared here (Bit +- Real), and their values and +assigned. Of course, this means that you will need to recompile to change +these values - see Lesson 3 to get rid of that heavy requirement.
  • + +
      +
  • +Random seeding: +Random numbers play an important role in Evolutionary Algorithms. See in +EO +programming hints more details about how this is simulated in EO - +but as far as you are concerned now, remember that the global +Random Number Generator is called rng +and should be used everywhere you need a realization of a random variable +of known law. Moreover, this RNG requires a seed, +which is set here (Bit - Real): +everytime you run the algorithm with the same +seed, you will get the same +result. Hence, to test the robustness of your +algorithm, you should run it with different seeds. This is rather time +consuming in the present programs, so we suggest that you wait until Lesson +3 to do so.
  • + +
      +
  • +Fitness function encapsulation: EO +is based on the notion of functors +- hence you now need to encapsulate your fitness function into a functor +object. This is what is done here (Bit +- Real).
  • + +
      +
  • +Initialization: +to initialize the population, first declare an empty object of class eoPop<Indi>, +which is basically an STL vector<Indi>, +then fill it with Indi's. And remember that +v.push_back +simply appends its argument at the end of STL +vector v.
  • + + + +
  • +Output: take +a snapshot at the initial population (Bit +- Real). Sort it first, so the best +individuals are first, and display it. Note that an eoPop has a << +method, which means that a simple os +<< pop streams the pop +onto the ostream os. +This is true for all objects of of class eoPrintable +(most EO objects) through the method printOn +(which is then called by the << +operator).
  • + +
      +
  • +Evolution engine: +The selection/replacement mechanism (Bit +- Real) is a simple generational +GA here: a simple selector, and a generational replacement. The eoDetTournament +has been chosen as a robust selection, and the generational replacement +(all parents are replaced by the offspring) is hard-coded in the eoSGA +algorithm.
  • + +
      +
  • +Variation operators: +in the simple algorithm considered here, individuals undergo crossover +and mutation. +In EO, these operators are (functor) +objects of class eoQuadOp +(binary operator that modifies both its arguments) and eoMonOp +(unary operator).  These operators are applied in turn to all selected +parents, according to user-defined probabilities.  These probabilities +are defined with all other parameters, and will +be passed to the eoSGAalgorithm.
  • + +
      +
    • +Bit The crossover eoBinCrossover +is the standard 1-point crossover, and eoBinMutation +is the standard bit-flip mutation that randomly +flips all bits with a given probability P_MUT_PER_BIT.
    • + +
      Warning: the P_MUT_PER_BIT +probability is an internal parameter of the +eoBinMutation, +it is NOT the probability of mutation +at the individual level. EO corrects what can be viewed as an inconsistency +in Holland's original work, further used in Goldberg's book by separating +the probability of mutation for each individual (independent of the type +of mutation that will be applied) from the probability of flipping each +bit, which is specific of the bit-flip mutation.  Hence, to run the +same algorithm as Goldberg's SGA, the mutation probability (at individual +level) is 1, and the probability of flipping each bit is P_MUT_PER_BIT. +
    • +Real The crossover eoArithmeticCrossover +is the standard arithmetic crossover for real-valued +vectors, that chooses a point randomly on the segment between both parents +(also termed BLX-0). eoUniformMutation +is the uniform mutation for real-valued vectors +that choses a new value for each variable uniformly on an interval centered +on the parent value. The width of the interval is an internal +parameter of the object, here called EPSILON.
    • + +
       
    + +
  • +Stopping criterion: +Specify a maximum number of generations +to run (Bit - Real): +the simplest of all stopping criteria at the moment, using an object of +a sub-class of class eoContinue.
  • + +
      +
  • +The algorithm: the +simple algorithm that is used here, called  eoSGA +requires +as parameters a selector, +a crossover and +the associated crossover rate, +a mutation and +the associated mutation rate, +and a stopping criterion. +Take a look at the corresponding +constructor +of the class eoSGA: +it only initializes its private data +with the parameters. Now look at the operator() +method - the one that is called in the code for FirstBitGA +or FirstRealGA - and you'll find +out that is is as simple as it sounds.
  • + +
      +
  • +Output: After +running the algorithm, output the sorted final population (Bit +- Real) - and look at the best +individual: this is the result of the algorithm.
  • + +
      +
  • +Main body: for +technical reasons (intercepting the exceptions), we need a main like this +one (Bit - Real)., +and you should not touch it unless you know what you are doing. Simply +note that this main calls the function main_function, which we have been +discussing up to now!
  • +
+ +

+Exercise 1: maximize your +own function

+This is very easy - if your search space is that of bitstring or of unbounded +real numbers. +
    +
  • +Go to the tutorial directory, and copy the +program you want to modify onto mytest.cpp.
  • + +
  • +Edit mytest.cpp +with any text editor:
  • + +
  • +Modify the fitness function itself (binary_value +in FirstBitGA,real_value +in  FirstRealGA)
  • + +
  • +Compile the program by typing make +mytest at system prompt
  • + +
  • +Run the new program by entering the command +mytest +at system prompt.
  • +
+ +

+Exercise 2: check the differences between both programs

+Go and take a look at the code for these programs (Bit +- Real). Use the symbolic representation +of an Evolutionary Algorithm (you should understand that figure now, otherwise +go there and come back) to understand how each +part of the EA is coded. Try to spot the differences between both codes: +there are not so many! +
After you've tried that alone, take a look at the solution +:-) +
  +

+Exercise 3: change the selection procedure

+This is rather straightforward ... if you know what other types of selection +are available! +
At the moment, let's only consider only the following simple ones: +
    +
  • +You already know the tournament selection
  • + +
    Syntax:  eoDetTournament<Indi> +select(T_SIZE);   // T_SIZE in [2,POP_SIZE) +
  • +Try the well-known roulette wheel
  • + +
     Syntax:    eoProportional<Indi> +select; +
  • +Or the stochastic binary tournament
  • + +
    Syntax:  eoStochTournament<Indi> +select(RATE);     // RATE in ]0.5,1] +
  • +and of course the random selection should +give bad results!
  • + +
    Syntax:  eoSelectRandom<Indi> +select;
+Note that all these classes of eoObjects are derived from the abstract +class +eoSelectOne. +

Lessons: +

    +
  • +in EO, all actions are performed by functor +objects (this section is the last time in this tutorial that there +is a direct link to the EO Programming hints +page - though the link at top and bottom of all pages will remain there).
  • + +
  • +in EO, all object you will usually need to manipulate are templatized +w.r.t. the type of the individual you are handling.
  • + +
  • +The type of the individual is itself templatized +w.r.t. the type of fitness (double by default).
  • + +
  • +In EO (actually, in EC!) initialization and variation +operators are representation-dependent, while +the evolution engine is representation-independent +(well, like any rule, this one does have some exceptions).
  • + +
  • +Changing the fitness function, or the selection +procedure inside the generational GA evolution engine is straightforward.
  • + +
  • +remember, all solutions to exercises are in +the same sub-dir of dir Tutorial than the lesson itself (see here).
  • +
+ +
Lesson 2 - +Tutorial +main page - +Top-Down page - Bottom-up +page - Programming hints - EO +documentation +
+
+
+Marc Schoenauer
+ +
Last +modified: Fri Nov 3 18:49:12 CET 2000 + + diff --git a/eo/tutorial/html/eoLesson2.html b/eo/tutorial/html/eoLesson2.html new file mode 100644 index 000000000..4bf3e37ec --- /dev/null +++ b/eo/tutorial/html/eoLesson2.html @@ -0,0 +1,301 @@ + + + + + + Tutorial: Lesson 2 + + + +Lesson 1 - +Lesson +3 - +Main page - +Top-Down +- Bottom-up - Hints +- EO +documentation +
+
+
+

+Tutorial Lesson 2: more encapsulations

+In this lesson, the same Evolutionary Algorithm will be rewritten in a +much more general context. +
First, look at the changes that have been done +to the algorithms. Then benefit from the new features by +
    +
  • +minimizing (and not only maximize) the fitness
  • + +
  • +combining several +operators of the same type
  • + +
  • +combining several +stopping criteria
  • + +
  • +use alternate selection/replacement +engines, deviating from the pure generational GA
  • +
+ +


Again, two basic algorithms are provided, namely FirstBitEA +and FirstRealEA. +
To compile and run them, go to the Lesson2 +sub-directory of the tutorial dir and simply type make. +Both examples should get compiled, and you can then run them by calling +their name from the system prompt. +

Note the slim difference in names, from GA +to EA: the behavior of these  EAs is +almost identical to that of their GA counterpart, at least with the default +settings that are provided. But their potentialities for easy modifications +are much larger, both in terms of variation operators +and of evolution engine (i.e. selection/replacement +mechanism).  +


Changes +

Browse through the code, and discover them one after the other: +

    +
  • +The fitness function +now +lies in a separate file +(Bit +- Real). But, more important, its +argument is a vector<bool> or a vector<double>, +and not an unknown type. This will allow to use the same file for any EO +object that is a sub-class of the corresponding STL vector class.
  • + +

    Note: Also, +a non-templatized fitness can be compiled +separately (not done here) into an object +file once and forall (remember +that templates forbid that). +
      +

  • +The encapsulation +of +the fitness (Bit +- Real) looks more complicated: you +have to declare 3 template arguments: the type of EO object it will be +applied to, the return type and the type of argument the function actually +requires.
  • + +

    Note: In the +previous files (Bit - Real) +, the last 2 types were deduced from the first (2nd argument = fitness +type of EO object, third = first). +
      +

  • +Both the above modifications makes it very easy to +minimize +rather than maximize a fitness function (see Exercise +1).
  • + +
      +
  • +The initialization +of the population is now encapsulatedinto +a separate initializer (based +on a boolean generator or a double-number +generator -see random_generators.h) +that is then used in the constructor of the population to build the individuals. +You can also use different initializers and call them in turn through the +call to pop.append() function +(see Exercise 2).
  • + +

    Note: Don't +forget to evaluate the population: +the eoPop has no idea of the eval function, so it has to be done from outside!!! +
      +

  • +You can now use +different +crossover +and mutation +operatorsin the same algorithm +(Bit - Real), +choosing among them according to +relative +rates. The class eoPropCombinedxxxOp, +where +xxx is either Mon (for mutation, of class eoMonOp) +or Quad (for crossovers, of class eoQuadOp), +is derived from the corresponding eoxxxOp class. When applying the eoPropCombinedxxxOp, +one of the eoxxxOp it contains is chosen by a roulette +wheel, according to their respective rates, and is applied to the arguments.
  • + +

    Note: A third optional argument +in method add is a boolean +(defaulted to false). When true, the actual rates for all operators are +displayed on the screen as percentages: you don't have to input rates that +sum up to 1, all rates are scaled anyway. +

    Note: The operators have to be encapsulated +into an eoTransform object +(Bit - Real) +to be passed to the eoEasyEA algorihtm. +The eoSGATransform is a simple +eoTransform +that does exactly the same thing than eoSGA: +each pair from the selected parents undergoes the crossover +operator with given probablity, and all individuals (after crossover +eventually) undergo mutation with given probability. +The arguments to the eoSGATransform +are an eoQuadOp with its probability +and an eoMonOp with the associated +probability. +
      +

  • +You can use combinations +of +several stopping criteria by using an object of the class eoCombinedContinue +(Bit +- Real). Initialize it with an object +of class eoContinue, and +addas +many of other such objects as you wish. And as an eoCombinedContinue +is +aneoContinue, +simply pass it to the algorithm (Bit +- Real).
  • + +
      +
  • +The +full selection/replacement mechanism is +now in place through the eoEasyEA +algorithm.
  • + +
    This means that you can use different selectors. +which was already true in Lesson 1, but also different replacement +strategies (see Exercise 3) whereas generational +replacement was hard-coded in the algorithm eoSGA +used in Lesson1. +

    Beware that we have to encapsulate  (Bit +- Real) the eoDetTournament, +which is of class eoSelectOne (i.e. allows +to select one individual from a population, its operator() +returning a single individual) into an object of the eoSelectPerc +(perc stands for percentage) which allows to select a ... percentage of +a population (his operator()  +returns a population). This was done internally in the  constructor +of eoSGA  - see lesson1.

+ +
Exercice +1: minimizing +
Modify the algorithm so that it minimizes the +fitness. +
    +
  • +For the bitstring case, you only have to modify the +declaration +of the representation, using eoMinimizingFitness +instead of double. +But is that really all? Give it a try, look at the output, and do it right +the second time!!!
  • + +
  • +For the real-valued problem, you also need to modify +the file real_value.h so +that it returns the sum of squares instead of its inverse. And again there +is something else to modify...
  • +
+Exercice +2: initialization +
Use different initializers: for instance, on +the real-valued sphere function minimization, try to initialize half of +the population in [-2,-1] and the other half in [1,2], with and without +the segment and arithmetic crossovers (and for large values of VEC_SIZE, +the size of the vectors). Amazing, isn't it! Explain that result. +

Exercice +3:  replacement +
You can now twidle the number of offspring that +will be generated from the parents. But of course you need to adjust the +replacement to keep a constant population size. +

    +
  • +To modify the number +of offspring, use the second argument of the +encapsulator +(Bit - Real) +of the selector +of class eoSelectOne +into an eoSelectPerc object. For instance, try
  • + +
                    +eoSelectPerc<Indi> select(selectOne,2.0) +
    to generate twice as many offspring as there +are parents. +
  • +To keep a constant population +size, you can use either the eoCommaReplacement +class, or the eoPlusReplacement. +The former selects the best offspring to replace the parents, the latter +selects the best among parents+offspring. Of course you cannot use eoCommaReplacement +if you have less offspring than parents!
  • + +
    Now if you use eoSelectRandom +as selector with a rate of +lambda, you end up with exactly the (mu+lambda) +or +(mu,lambda) strategies from Evolution +Strategies. +
  • +Question: what do you +get if you have use a rate of 1/POP_SIZE for the selection, and an eoPlusReplacement +strategy? Yes, you get almost the replace_worst Steady-State GA, though +rather inefficient, as you sort the population at every generation, which +could be avoided - and will be in a later lesson).
  • + +
  • +Homework: Write the +eoCommaPlusReplacement +that would start by taking the best of the offspring, and if some are still +missing to keep the population size constant, take the best of the parents. +Write the eoConservativeReplacement +that starts by taking a percentage of the parents (the best ones) and then +adds the best from the offspring. In both cases, send +use the code as we haven't done that yet (and +hence there is no solution available at the moment - Nov. 29 :-)
  • +
+Remember: all solutions +are in the same sub-directory of the Tutorial dir than the examples (i.e. +here Lesson2), and are described here. +

+


+
Lessons learned: +
    +
  • +How to write a fitness function that only +needs a genotype, not a full individual. Moreover you can compile it separately.
  • + +
    How to initialize the population using +random generators +
  • +How to use other evolution engine than the +simple generational GA.
  • + +
  • +How to combine different objects of the same kind into a single object +that you can use like a simple basic object (operators +and stopping criteria here).
  • +
+ +
Lesson 1 - +Lesson +3 - +Main page - +Top-Down +- Bottom-up - Hints +- EO +documentation +
+
+
+Marc Schoenauer
+ +
Last +modified: Fri Nov 3 18:49:12 CET 2000 + + diff --git a/eo/tutorial/html/eoLesson3.html b/eo/tutorial/html/eoLesson3.html new file mode 100644 index 000000000..a7b08a2bc --- /dev/null +++ b/eo/tutorial/html/eoLesson3.html @@ -0,0 +1,531 @@ + + + + + + Tutorial: Lesson 3 + + +Lesson 2 - +Lesson +4 - +Main page - +Top-Down +- Bottom-up - Hints +- EO documentation +
+
+
+

+Tutorial Lesson 3: input/output

+In this lesson, you will still use the same Evolutionary Algorithm, BUT +in a much more user-friendly way. You +will discover how to +
    +
  • +input parameters on the command-line or from a text +file
  • + +
  • +save the population to disk, together with every part +of the algrithm you could think of - so you can decide to reload +everything later to continue the same run, eventually with different parameters.
  • + +
  • +generate statistics on the populations, and output +them to the screen, text or graphic, or to a file (or to any other +device you might want to use).
  • +
+First, but you should now have done it without being told, go into the +Lesson3 +sub-dir of the tutorial dir and type +make. +This will compile the SecondBitEA +program (and, some day, SecondRealEA). +

You can then either +

    +
  • +browse the corresponding code (only SecondBitEA +available right now, but you can figure out how SecondRealEA will look +like),
  • + +
  • +look at the summary of changes,
  • + +
  • +or find out directly explanations about the new features: the eoParser, +eoState +and eoCheckpoint classes.
  • +
+ +


+


+
Changes +
As already said, the behavior of the algorithm +will be exactly the same as the previous one as far as optimization is +concerned. Only the input (of algorithm parameters) and output (of program +results) will be very different. +
Hence, the sections corresponding to the fitness +function, the initialization, the +variation +operators, the evolution engine +and the algorithm itself are +almost identical (apart from variable name changes). +
    +
  • +Fitness function: +there is an additional line +after the encapsulation of our binary_function +into an eoEvalFunc +object, which again encapsulate the eoEvalFunc +into an eoEvalFuncCounter. +As its name says, thisobject will, in addition to computing the fitness, +count the actual +number of evaluations: the fitness of non-modified individuals is of course +not recomputed - and this is taken care of by this object. Moreover, it +can be later used for displays +in eoMonitor objects, as done in the checkpoint +section.
  • + +
  • +The initialization +section has been extended to account for the possibility to re-load +a previously saved population. This is achieved +through an eoState object, if the corresponding program +parameter is set.
  • + +
  • +The +variation +operators and the evolution engine  +sections are similar to the ones in Lesson2
  • + +
  • +The parameter section  +is completely different from the previous one. All variables corresponding +to program parameters +are now declared +in the main_function +(as before), but their values are set in a new +function, called read_param. +See the eoParser description for more details.
  • + +
  • +The stopping criterion +section, has in fact now become the checkpoint section, as it involves +much more than just stopping criteria. See all details in the eoCheckpoint +paragraph below.
  • +
+ +
eoParser: +parameter input +
The first two examples of Lessons 1 and 2 had +a very crude way to set parameter values: they were hard-coded, and you +had to recompile the whole program to change a single value. We shall now +see now to set parameter values in a flexible way (though we're still looking +for volunteers to create a Graphical User Interface :-) +
Two base classes are used for that purpose: +
    +
  • +The eoValueParam +class, templatized by the type of the variable +you want to handle (i.e. integer, double, +yourPrivateClass, ...). In this lesson, +we will not go into details: e.g. we will not tell you that the +eoValueParam +is actually a templatized sub-class of abstract class eoParam (oups, I +said it!), nor will we deal with parameters outside their use from an eoParser. +See the parameter section of the Bottom-up tutorial, or wait until lesson +4).
  • + +
  • +The eoParser +class, whose only purpose is the input of parameters.
  • +
+Modifying parameter values at run-time: +
Using an eoParser object, the parameter values +are read, by order of priority +
    +
  1. +from the command-line
  2. + +
  3. +from a text file
  4. + +
  5. +from the environement
  6. + +
  7. +from default values
  8. +
+The syntax of parameter reading is a keyword-based +syntax, now traditional in the Unix world: +
    +
  • +in EO, each parameter is designated by a (long) keyword, +and optionally by a short (1 character) keyword.
  • + +
      +
  • +the general syntax to modify parameter value at run-time is (either from +the command-line or in a text file)
  • + +
                        +--longKeyword=value     +or     -c=value    +if 'c' is the short keyword +
      +
  • +so, after compiling the executable for Lesson 3 (make +lesson3 at system prompt in Unix), you can try to type +in
  • + +
                         +SecondBitEA +
    and see the algorithm run as before (OneMax optimized on 8-bits bitstrings). +But you can now type in +
                         +SecondBitEA --vecSize=100 +
    and see the output of the optimization of OneMax on 100-bit bitstings. +
      +
  • +Take a look at all available parameters by typing in
  • + +
                         +SecondBitEA --help +
    or by going into the code: all parameter inputs have been grouped in +the +read_param function. +
      +
  • +After running the algorithm, a new file has been created, named SecondBitEA.status: +it contains the list of all actual parameters used, and can directly be +used as parameter input file: change the file name (e.g. to SecondBitEA.param), +edit it, change whichever parameter you want, and type in
  • + +
                          + +SecondBitEA @SecondBitEA.param +
    and you will see all values that you defined into the file taken into +account. +
      +
  • +The priority remains to the command-line, +so you can still override the values in the parameter file by giving a +new value directly on the command-line.
  • +
+Programming parameter input: +
the code of SeconBitEA provides examples of parameters reading. Lets +take the example of the random number generator seed. +
    +
  • +You first need to declare it +in the main_function. As parameter +reading will be done in the read_param +function, you need to pass it the variable seed. Note that read_param receives +it by reference, as it is going +to modify its value!
  • + +
  • +In read_param, you need first to declare +an eoParser object (it needs the standard argc and argv in its constructor).
  • + +
    Then, declare a parameter +of type uint32 (32-bits integer), +and read it  directly from the parser, using method create_param. +The arguments are obvious: default value, long keyword, comment (that will +appear in the help message and in the output "status" file if any). +
  • +Finally, you need to assign the +value to the variable _seed (hence modifying the original seed variable).
  • +
+ +
+
eoState: +saving and loading +
You might have noticed in the  read_param +described above a new parameter +named load_name. +Now if you go to the init section of +the code, you will see an alternative way of initializing +the population: if load_name is an empty string, +then we do as in the preceding example and use an eoInitFixedLength object. +However, if a load_name name was entered, the population is read through +the inState.load(load_name) +instruction. Moreover, the comment says "Loading pop and +rng". +

This is made possible using the eoState +class. eoState +objects maintain references to eoObjects +that have both an input method (readFrom) +and an output method (printOn), +i.e. that derive from the base class eoPersistent. +You must first register +object into a state, and can then save them to a (text) file, and later +read them from that file using the load +method, as done here. +
Of course, you can call the save +method for an eoState +object anywhere in the code. But the checkpointing +mechanism offers you better ways to do that - and it's so easy .... +

+


eoCheckpoint: +every generation I'd like to ... +
The checkpointing mechanism is a very powerfull +construct to perform some systematic actions +every generation - like saving things +(using eoState objects described above), computing statistics +on the population, updating +dynamical parameters or displaying +information. +

eoCheckpoint +objects are eoContinue +objects that contain pointers to different +types of objects. When their operator() +method is called (i.e. every generation in the examples up to now), they +first call the operator() +methods of all object they contain, and then return their result as an +eoContinue +object (i.e. should we continue or stop). +
Programming: To +do something every generation, you simply need to add +an object whose operator() +does what you want to the eoState that you will use as continuator in the +algorithm. +
+


eoCheckpoint: +Stopping +
The eoContinue +part of an eoCheckpoint +is a single object, passed to the +constructor. If you want more that one stopping criterion, use an eoCombinedContinue +object as described in Lesson2. +
+
+
eoCheckpoint: Computing +statistics +
Statistics are computed using eoStat +objects, i.e. functor objects whose operator() +receives as argument a reference to a population as argument, and can hence +compute whatever is needed over that population. eoStat +objects are templatized +over the type of what they compute (e.g. double, +or pair<double>, +or ...). But looking at the inheritance +diagram of the eoStat +class, you find that eoStat +objects are also eoValueParam +objects. And this allows eoStat +to be used within eoMonitor +object, and hence displayed +to the user! +

Available statistics: Some widely +used statistics are already available (and of course you can build you +own!). +

    +
  • +eoBestFitnessStat returns +the fitness value of the best individual in the population (of type FitnessType, +whatever this is).
  • + +
  • +eoAverageStat and eoSecondMomentStat +respectiveley return the average (type double, assumes that FitnessType +is castable to a double) and a pair made of the average and the standard +deviation (type pair<double>) +of the fitnesses in the populations.
  • + +
  • +eoDiversityStat returns the +diversity in the population: asssuming that there is a distance function +defined among individuals, it returns the average inter-individuals distance. +See also Exercise 2.
  • +
+Programming: To compute some statistics +within your algorithm, simply declare +the corresponding eoStat objects, and add +them to the eoCheckpoint you +use in the algorithm. +

Note: actually, there are 2 disctinct +classes that compute and gove access to statistics: eoStat +and eoSortedStat. As its name +indicate, the latter is used whenever computing the statistics require +a sorted population: not only this avoids to sort the population many times, +but also it avoids changing the order of the population at all as eoSortedStat +work on a temporary vector of fitnesses . But as +far as their usage is concerned, its makes no difference. +
+


+
eoCheckpoint: Displaying +eoParameters +
The eoMonitor +objects are used to display a set of eoValueParam +objects. +

Available monitors: A few monitors +are available in th eEO distribution: +

    +
  • +eoStdoutMonitor displays its +parameters in text format on the screen. The +(optional) boolean value in the constructor modifies the output: when true +(the default), vebose output is used, with one line per parameter. When +false, parcimonious output displays one line for all parameters.
  • + +
  • +eoStdoutMonitor writes its +parameters in text format in a file. A file +name is required in the constructor, and an optional separator character +can be added (default is ','). Note that the file is overwritten by next +call to the same program.
  • + +
  • +eoGnuplot1DMonitor displays +its parameters in graphical format on the screen +by calling the gnuplot program, +and as of today, only works in the Unix version of EO (as always, volunteers +are welcome to port that to MS Windows). It takes an optional filename +as input, as communication of data with gnuplot +is done through a file. If no filename is provided, the file will be erased +at the end of the run, while it is otherwise kept (though it will be overwritten +by next call to the same program).
  • +
+ +


Programming: To display something +while the algorithm is running, you need to declare +an eoMonitor object, add +some objects (that must be eoValueParam +objects) to that monitor, and of course add +the monitor to the eoCheckpoint +you use in the algorithm. +
+


+
eoCheckpoint: Updating +things +
The last type of objects that  eoCheckpoint +can handle are eoUpdater +objects. You should simply encapsulate in an eoUpdater +anything you wish to do which does not fit into one of the above category. +Note that their operator() method +does not receive any argument. +

Available monitors: A few updaters +are available in the EO distribution: +

    +
  • +eoIncrementor A simple updater +which maintains a counter (an eoValueParam +that needs to be created beforehand, and passed in the constructor). It +is incremented everytime the operator() +method is called (every generation at the moment). You can of course also +give an increment in the constructor (1 by default).
  • + +
  • +eoCountedStateSaver +and eoTimedStateSaver can +be used to save some existing eoState +(see above) to a file regularly, either based on the +generation count (e.g. every 4 generations) or based on the clock (e.g. +every 5 seconds).
  • +
+Programming: +
A very simple example of using an eoUpdater +is given in the code for SecondBitEA: First declare +an eoValueParam object, then +use +it to construct an eoIncrementor +that you must add to the eoCheckpoint +in order to activate its update. You can then use the parameter for your +purpose, for instance as a first coordinate for a monitor. +
Note also how to use the statesavers: first declare +a state, then register +whatever you think necessary to that state, then pass +the state to some state-saver - and don't forget to add +the statesavers to the current eoCheckpoint. +
+
+
Exercice 1: +
    +
  • +The code of SecondBitEA +display things in the current window in text format. Replace the eoFileMonitor +by an eoGnuplot1DMonitor +and watch the graphical output (Unix +systems with gnuplot +installed only, sorry).
  • + +
  • +Note that you must also replace the eoSecondMomentStat +by an eoAverageStat, +otherwise the standard deviations won't make any sense here.
  • + +
  • +Please try to understand why the average is always +0 before taking alook at the solution (file exercise1.cpp).
  • + +
  • +Then run
  • + +
              +exercise1 --vecSize=1000 --maxGen=1000 +
    to get a chance to see something hapenning before +the program ends!
+ +
Exercice 2: +
Write the eoDiversityStat +stat computation and test it. Thanks to send us the code! +
+
+
Exercice 3: +
Write the code for an eoGnuplot1DwithErrorbarsMonitor +that would take into account the standard deviations and display them as +errorbars. +
Again, send us the code afterwards, thanks :-) +
+
+
Lessons learned: +
    +
  • +Value of program parameters can be set at run-time +using the eoParser +class.
  • + +
  • +Snapshots of the algorithms can easily +be saved (and restored) +thanks to the eoState +class.
  • + +
  • +The eoCheckpoint +mechanism let you do things every generation +without modifying existing algorithms, by simply writing the necessary +code and encapsulating it into an object that eoCheckpoint +is aware of, that are at the moment the following:
  • + +
  • +computing statistics, displaying +parameters +(e.g. statistics),  saving the +(eo)State +of the program.
  • +
+In next lesson you will find out that many adaptive +techniques (the state-of-the-art in Evolutionary Computation) can easily +be programmed through the eoUpdater +construct. +
+
Lesson 2 - +Lesson +4 - +Main page - +Top-Down +- Bottom-up - Hints +- EO documentation +
+
+
+Marc Schoenauer
+ +
Last +modified: Mon Nov 27 8:49:12 CET 2000 + + diff --git a/eo/tutorial/html/eoOperators.html b/eo/tutorial/html/eoOperators.html new file mode 100644 index 000000000..5803ae132 --- /dev/null +++ b/eo/tutorial/html/eoOperators.html @@ -0,0 +1,56 @@ + + + + + + Variation Operators + + + +

+Variation Operators

+Variation operators modify individuals, or, equivalently, move them in +the search space. They are almost always stochastic, +i.e. they generate random variations. Variation operators are classified +depending on the number of arguments they use and/or modify. +

Variation operators involving two individuals are called +crossover operators. +They can either modify one of the parents according +to the material of the other parent, or modify both parents. In EO, the +former are called Binary operators and the latter Quadratic operators. +
  +

Variation operators involving one single individual are called mutation +operators. +

Note that in EO you can define and use variatio operators that generate +any number of offspring fromany number of parents. These are called general +operators, and require advanced knowledge of EO. +

Crossover +
Crossover operators involve two parents, and can modify one of them, +or both of them. +

Using crossover operators +

Mutation +
Mutation operators modify one single individual. The corresponding +EO class is called eoMonOp. +

+Using mutation operators

+The standard EO genotypes (bistrings and real vectors) have pre-defined +mutation operators. +
  +

+Writing a mutation operator

+  +

  +

General +Operators +
  +
  +
  +

+


+
+Marc Schoenauer
+ +
Last +modified: Mon Oct 30 18:24:39 CET 2000 + + diff --git a/eo/tutorial/html/eoOutput.html b/eo/tutorial/html/eoOutput.html new file mode 100644 index 000000000..2a9bc810a --- /dev/null +++ b/eo/tutorial/html/eoOutput.html @@ -0,0 +1,19 @@ + + + + Output + + + +

Output

+ + + +
+
Marc Schoenauer
+ + +Last modified: Mon Oct 30 19:29:19 CET 2000 + + + diff --git a/eo/tutorial/html/eoProgramming.html b/eo/tutorial/html/eoProgramming.html new file mode 100644 index 000000000..7bae8b387 --- /dev/null +++ b/eo/tutorial/html/eoProgramming.html @@ -0,0 +1,256 @@ + + + + + + EO Programming guide + + +Tutorial main page - +Top-Down +page - Bottom-up page - Programming +hints - EO +documentation +
+
+
+

+EO Programming guide

+Templates, +Functors, +STL +Library, random numbers, EO programming style! +
+
+
Templates +
Most EO code si written using templates. This allows to write generic +code, i.e. involving a class which doesn't have to be known when writing +the code -- but only when compiling it. In some sense this is similar to +naming variables in algebra: you can write a lot of equations involving +some variable $x$ without knowing even it if will be an integer or a float +(or a matrix or ...). The main basic type that is templatized in EO is +the fitness: an EO object is some object which has a fitness of some type +F that can be anything. The definition for that is (seeEO.h) +

template<F> class EO +

The idea is that, later in your code, you can declare for instance as +in FirstBitGA.cpp +

typedef eoBin<double> +Genotype; +

meaning that in that file, you will manipulate as Genotype +objects that are EO objects whosefitness +is a double. +

Whereas the advantages are obvious (writing generic reusable code instead +of having to rewrite the same pieces of code for different types), there +are some drawbacks: namely, it makes some of the compiler error messages +hard to understand; and it forbids the compilation of most parts of EO +into an object library file, as the actual types are not known in advance. +

+


+
Functors +

Though EO is a library, it contains almost no functions! +
EO only contains functors, that are objects which have a method called +operator(). +Such objects are used  as if they were a function, but the big differences +are that +

    +
  • +functors are functions with private data
  • + +
  • +you can have different funtors objects of the same class, i.e. you can +use the same functionality with different parameters
  • + +
  • +you can heave a hierarchy of functors objects, which means that you have +a hierarchy of functions with defaults behaviors and specialized sub-functions
  • + +
  • +...
  • +
+Functors are so intimately linked to EO that a base class (eoFunctorBase) +has been designed to hold all functors. This base class is itself divided +into three derived class. These classes tell you immediately what kind +of arguments the operator() method requires +and what kind of result it produces. See EO conventions, +and +the inheritance diagram of class +eoFunctorBase. +

Example +

A good example is given by the eoEvalFuncPtr +class +

class MyClass +
{ ... +
    void operator()(ArgType +arg) +
       { +
            +// do what you have to do +
       } +
}; // end of class declaration +

is used  later in the code in something  like +
  +

ArgType myArgument; +
MyClass myObject;    // myObject +is an object of class MyClass ... +
myObject(myArgument);  // calls method +operator() of object myObject with argument myArgument ... +
  +
  +
  +

+Why not plain C functions?

+Consider for instance variation operators. Of course, we could declare +them as function acting on some objects. +

Blabla +

+


+
A very brief +introduction to STL +

All EO heavily relies on STL, the Standard +Template Library. +
But you don't have to know more than a few words +of STL to use EO (like with "hello", "please" and "goodbye" you +can survive in a foreign country :-) and even to contribute to new EO features. +

You will only find here the basics of STL that you will need to understand +most of EO code - and to guess what the parts you don't understand are +actually doing. Don't worry, I don't +understand everything :-) +

STL provides the user with container +and algorithms. And you can apply (almost) +all algorithms on (almost) all containers. +

Containers +
Containers are high level data types used to hold simpler data - the +most widely used example of a container is the vector +construct. +
The use of STL containers relieve the user from memory management. +

    +
  • +vector The +most widely used container is a one-dimensional array of items.
  • + +
    Data manipulation: suppose v +is an STL vector<AtomType>. +Then +
    v[i] +is the ith element of v, as in standard C arrays +
    v.size() +is the number of elements of v +
    v.push_back(atom) +appends the atom +at end of v, +provided of course that atom +is of type AtomType +
    blabla +
  • +pair
  • + +
    This simple container allows you to hold two +data types together. It is very handy for temporary data handling. Assuming +p is a pair<AtomType1, +AtomType2>, +
    p.first() +and p.second()  +refer to the encapsulated data, of respective types AtomType1and +AtomType2. +
  • +Blabla
  • +
+There are many other types of containers that are not used in EO and that +we will not present here. +

STL Algorithms +
Algorithms are functions acting on containers - the most widely used +example of a STL algorithm is the sort +function. +
Blabla +

Drawbacks +
The main drawback I see in using STL is that it makes it almost +impossible +to use a debugger normally: whereas acess to data is made simple +to the progammer, data structures are actually so complex, and debuggers +so willing to display everything that you get lines of template instanciation +when asking your debugger what is inside some container! For instance I +could never visualize some +v[i] +with gbd, v +being an STL vector! +
But there nonehteless are so many advantages !!! +

+


+
Random +numbers +
Evolutionary Algorithms make intensive use of random numbers. Random +numbers are simulated in computers by using pseudo-random +number generators (RNGs for short), i.e. functions that return series of +numbers who look random (w.r.t. some statistical criteria). +

To make sure the random number generator is as good as possible, and +to ensure reproducibility of the results across diffrerent platforms, EO +has its own RNG, the ``Mersenne Twister'' +random number generator MT19937 (thanks to Takuji +Nishimura, see eoRNG.h +comments). +

Though you can define and use as many RNGs as you wish in EO, the library +also provides you with a global RNG termed rng: using only that single +RNG in all calls to random numbers allows one to be able to reproduce +a given run: +

    +
  • +as strange it seems for a random algorithm, it is mandatory for debugging +purposes
  • + +
  • +random numbers are computed starting from a seed - starting from the same +seed will lead to the same series of pseudo-random numbers, and hence to +the same results of the algorithms. All examples in this tutorial will +use the RNG seeding procedure, see e.g. in Lesson1.
  • + +
  • +to simulate "true" random runs, you can just seed the RNG with a machine-clock +realted number, e.g. calling time(0), as done for isntance in Lesson3 +(and after).
  • +
+As RNGs only produce (by definition) numbers that are uniformly distributed +integers between 0 and some maximal number, EO provides you with random +numbers follwing different probability distribution +(e.g. floating point following normal +distribution). +

EO also provides random_generators +that can be used in STL call to generate series of random numbers, as in +eoPop +initializers. +

+


+
EO conventions +and naming style +
A few naming conventions should help you to navigate more easily through +EO: +
    +
  • +The name of local varoiables shoudl start with a lower case letter
  • + +
  • +The name of the parameters to a function shoudl start with an underscore +(_)
  • + +
    The initialization parameters of constructors, for instance,  +shoudl be named from the names of the variables they are used to initialize. +
  • +The names of classes should start with eo + an Uppercase letter
  • + +
  • +Blabla
  • +
+ +
+
Tutorial main page - Top-Down +page - Bottom-up page - Programming +hints - EO +documentation +
+
+
+Marc Schoenauer
+ +
Last +modified: Mon Nov 6 07:01:57 CET 2000 + + diff --git a/eo/tutorial/html/eoRepresentation.html b/eo/tutorial/html/eoRepresentation.html new file mode 100644 index 000000000..f572f1b41 --- /dev/null +++ b/eo/tutorial/html/eoRepresentation.html @@ -0,0 +1,19 @@ + + + + Representation + + + +

Representation

+ + + +
+
Marc Schoenauer
+ + +Last modified: Mon Oct 30 19:28:01 CET 2000 + + + diff --git a/eo/tutorial/html/eoSGA.html b/eo/tutorial/html/eoSGA.html new file mode 100644 index 000000000..2d22f7946 --- /dev/null +++ b/eo/tutorial/html/eoSGA.html @@ -0,0 +1,157 @@ + + + + + + eoSGA.h + + +Back to Lesson 1 - Tutorial +main page - Top-Down page - Bottom-up +page - Programming hints - EO +documentation +
+
+
+

+eoSGA.h

+ + + + + +
//----------------------------------------------------------------------------- +
// eoSGA.h +
//----------------------------------------------------------------------------- +
#ifndef _eoSGA_h +
#define _eoSGA_h +
#include <eoOp.h> +
#include <eoContinue.h> +
#include <eoPop.h> +
#include <eoSelectOne.h> +
#include <eoSelectPerc.h> +
#include <eoEvalFunc.h> +
#include <eoAlgo.h> +
#include <apply.h> +
/** The Simple Genetic Algorithm, following +Holland and Goldberg  +
*  Needs a selector (class eoSelectOne) +a crossover (eoQuadratic,  +
*      i.e. a 2->2 +operator) and a mutation with their respective rates,  +
*      of course +an evaluation function (eoEvalFunc) and a continuator  +
*      (eoContinue) +which gives the stopping criterion. Performs full +
*      generational +replacement. +
*/  +
template <class EOT> +
class eoSGA : public eoAlgo<EOT> +
{ +
public : +
 // added this second ctor as +I didn't like the ordering of the parameters +
 // in the one above. Any objection +:-) MS +
eoSGA( +
       eoSelectOne<EOT>& +_select, +
       eoQuadraticOp<EOT>& +_cross, float _crate, +
       eoMonOp<EOT>& +_mutate, float _mrate, +
       eoEvalFunc<EOT>& +_eval, +
       eoContinue<EOT>& +_cont) +
     : cont(_cont),  +
       mutate(_mutate),  +
       mutationRate(_mrate), +
       cross(_cross), +
       crossoverRate(_crate), +
       select(_select), +
       eval(_eval) +{}
+ + + + + +
 void operator()(eoPop<EOT>& +_pop) +
 { +
    eoPop<EOT> offspring; +
    do { +
         +select(_pop, offspring); +
         +unsigned i; +
         +for (i=0; i<_pop.size()/2; i++)  +
             +{   // generates 2 offspring from two parents +
                 +if ( rng.flip(crossoverRate) )  +
                   +{  +
                       +cross(offspring[2*i], offspring[2*i+1]); +
                   +} +
             +} +
         +for (i=0; i < _pop.size(); i++)  +
             +{ +
                 +if (rng.flip(mutationRate) )  +
                     +{ +
                         +mutate(offspring[i]); +
                     +} +
             +} +
         +_pop.swap(offspring); +
         +apply<EOT>(eval, _pop); +
     } while (cont(_pop)); +
 } +
 
+ + + + + +
private : +
 eoContinue<EOT>& cont; +
 eoMonOp<EOT>& mutate; +
 float mutationRate; +
 eoQuadraticOp<EOT>& cross; +
 float crossoverRate; +
 eoSelectPerc<EOT> select; +
 eoEvalFunc<EOT>& eval;
+ + + + + +
}; +
#endif
+ +
Back to Lesson 1 - Tutorial +main page - Top-Down page - Bottom-up +page - Programming hints - EO +documentation +
+
+Marc Schoenauer
+ +
Last modified: Sun Nov +19 19:36:21 2000 + + diff --git a/eo/tutorial/html/eoSelect.html b/eo/tutorial/html/eoSelect.html new file mode 100644 index 000000000..a415b460c --- /dev/null +++ b/eo/tutorial/html/eoSelect.html @@ -0,0 +1,19 @@ + + + + Selection + + + +

Selection

+ + + +
+
Marc Schoenauer
+ + +Last modified: Mon Oct 30 17:51:55 CET 2000 + + + diff --git a/eo/tutorial/html/eoStop.html b/eo/tutorial/html/eoStop.html new file mode 100644 index 000000000..4e37700f4 --- /dev/null +++ b/eo/tutorial/html/eoStop.html @@ -0,0 +1,25 @@ + + + + Input / Output + + + +

Input / Output

+ +

+ +

Stopping criteria

+ +

+ +

Displaying statistics

+ +
+
Marc Schoenauer
+ + +Last modified: Tue Oct 31 18:32:22 CET 2000 + + + diff --git a/eo/tutorial/html/eoTopDown.html b/eo/tutorial/html/eoTopDown.html new file mode 100644 index 000000000..1e8470f3c --- /dev/null +++ b/eo/tutorial/html/eoTopDown.html @@ -0,0 +1,88 @@ + + + + + + EO - The Top-Down approach + + +Tutorial main page +- +Top-Down +page - Bottom-up page - Programming +hints - EO +documentation +
+
+
+

+EO - The Top-Down approach

+ +


Congratulations - You have chosen the top-down approach!  This +means that you want to start from something that already works, and gradually +learn about the more complex constructs. We have prepared a series of "lessons" +for you. +

    +
  • +Lesson 1 - a gentle introduction to the EO +way: your first steps into EO representations +using a simple generational GA. Please, spend +the necessary time on that one, since all basic constructs presented +there are used throughout EO.
  • + +
  • +Lesson 2 - encapsulate, +encapsulate, and try more sophisticated selection/replacement +mechanisms, as well as multiple  operators
  • + +
  • +Lesson 3 - The same algorithms, but with improved +input/outputs: user-friendly input (i.e. without +the need to recompile!) of algorithm parameters, +and checkpointing (display +of on-line statistics, save +and +restore +populations, +restart stopped runs, +...).
  • + +


    Current version (Nov. 29, 2000) stops here, but here are the plans +(sujected to many changes, of course!) +
      +

  • +Lesson 4 - More about checkpointing: write your first adaptive +mechanism, and find out how easy it is to update +and monitor dynamic +parameters
  • + +
  • +Lesson 5 - more general operators: e.g. binary, n-ary, or even specific +mate selection (your brain and my beauty)!
  • + +
  • +Lesson 6 - why not go parallel? From the simple asynchronous SSGA to the +more sophisticated island model (no totally distributed population yet).
  • + +
  • +Lesson 7 - ...
  • +
+Of course, in each lesson, you have links to the Bottom-Up page of the +corresponding component of an EA you are modifying. +
( ... Well, to tell you the truth, as of today, november 28, this is +not true :-) +
+
+
Tutorial main page - Top-Down +page - Bottom-up page - Programming +hints - EO +documentation +
+
+
+Marc Schoenauer
+ +
Last modified: Fri Nov 28 +2000  + + diff --git a/eo/tutorial/html/eoTutorial.html b/eo/tutorial/html/eoTutorial.html new file mode 100644 index 000000000..7f9d20942 --- /dev/null +++ b/eo/tutorial/html/eoTutorial.html @@ -0,0 +1,178 @@ + + + + + + Tutorial EO + + +Top-Down page - Bottom-up +page - Programming hints - EO +documentation +
+
+

+EO Tutorial

+Welcome to EO - the Evolving Objects library. What is this tutorial good +for? +
Well,  the short term idea here is to help you build +your own Evolutionary Algorithms using EO - while the long term +idea is that you will be able to contribute to EO, and ultimately write +our +EAs :-) +

+About this tutorial

+This tutorial can be used in 2 different ways: top-down and bottom-up. +
    +
  • +Top-down means you start from a very +simple, ready-to-run algorithm, and gradually modify it, making +it both more powerful and more complex.
  • + +
  • +Bottom-up means you start by examining the +components +of an EA one by one, down to the level of complexity you feel comfortable +with, and then build the whole algorithm using those components you need +(or the one you are mastering). Such approach might be viewed as going +through a simplified user guide, too.
  • +
+However, it is strongly recommended +that you take some time on the first lesson of the Top-down approach to +get familiar with the basic concepts that are used throughout EO. Anyway, +as of today, November 29, the Bottom-up page is not written yet :-) +

Related documents +

    +
  • +There are of course a few (very few) programming +hints that you should know.
  • + +
  • +THe EO documentation - automatically +generated from the comments in the code - is very helpful, to get an idea +of the inheritance diagrams of EO classes, and to quickly reach some specific +part of the code.
  • + +
    The top page of each class documentation is for instance the inheritance +diagram of the class, and you'll learn a lot by simply looking at it. +
  • +And, last but not least, we assume you know approximately that an Evolutionary +Algorithm looks like this, but otherwise you can try this very +brief introduction).
  • +
+ +


Colors and navigation: +

You will see this diagram in quite many places, as for instance at the +top of all examples - usually it will be clicable and will help you navigate +among the different parts of an EO program. See the brief +introduction to Evolutionary Computation for a detailed explanation. +

+

+ +

But in the text itself, colors are important, +as they will be used throughout this tutorial to clearly mark which part +of the algorithm we are discussing. So please keep in mind that, whereas +orange +is for emphasis, +

    +
  • +Yellowish is for representation, +i.e. the choice of the genotype
  • + +
  • +Magenta is for the stochastic +operators that are representation-dependent, +i.e. initialisation and variation operators +(crossover, mutation +and the like).
  • + +
  • +Green is for the implementation of Darwinism, +i.e. the way the individuals are selected +for reproduction and survive.
  • + +
  • +Red is for evaluation, i.e. the computation +of the fitness of all individuals
  • + +
  • +Blue is for interactions of the user and the +program, as for instance choice of stopping criterion, +on-line display of nice statistics or initial +choice +of all program parameters.
  • + +
  • +Brown is for everything that is NOT part of +any of the above, i.e. random number generator, or basic C++/STL syntax +.
  • + +
  • +Note that pink will be used to desctibe the +syntax of compile orders (i.e. at the oepratoring system level, see e.g. +below).
  • + +
  • +Last, but not least, all links into EO documentation +will use the Helvetica typeface, like this line you are now reading.
  • +
+ +
    +
  • +an interface that would allow you to build your Evolutionary Programs by +a few clics; such a thing does exist, is called EASEA, +and is complementary to this tutorial as it helps the user to build some +simple EO programs from simple description. But there are things that EASEA +cannot do, and you will have to do it yourself and will need to imcrease +your knowledge about EO for that.
  • +
+ +

+Before you start

+You should of course have downloaded and installed the whole EO +library (how did you get this file if not???). +
So we'll assume that you are now in the Tutorial directory, and that +your prompt looks something like +

(myname@myhost) EOdir/Tutorial % +

so you should now type in +

make lesson1 +

and see something like +

(myname@myhost) +EOdir/Tutorial % make lesson1 +
c++ -DPACKAGE=\"eo\" -DVERSION=\"0.9.1\" +-I. -I../../src -Wall -g -c FirstBitGA.cpp +
c++ -Wall -g -o FirstBitGA FirstBitGA.o +../../src/libeo.a ../../src/utils/libeoutils.a +
c++ -DPACKAGE=\"eo\" -DVERSION=\"0.9.1\" +-I. -I../../src -Wall -g -c FirstRealGA.cpp +
c++ -Wall -g -o FirstRealGA FirstRealGA.o +../../src/libeo.a ../../src/utils/libeoutils.a +

and two now executable files should have appeared in the subdirectory +Lesson1, namely FirstBitGA +and FirstRealGA (see First +lesson to know more about these two ready-to-run programs). If this +doesn't work, please go back to the main EO directory and run the installation +program. +

You should also test that you can access the EO documentation in the +menu line below: you might not need to go there immediately, but just in +case you make rapid progress ... This menu bar should be on all pages of +this tutorial, allowing you to navigate easily. +

Last, but not least: EO is improving only  from the good will of +contributors. This is also true for this tutorial: If you find anything +that you think could be improved, you are welcome to e-mail +me. +

+

Enjoy! +


Top-Down page +- Bottom-up page - Programming +hints - EO +documentation
+ +
+
+Marc Schoenauer
+ +
Last +modified: Fri Nov 28 2000  + + diff --git a/eo/tutorial/html/index.html b/eo/tutorial/html/index.html new file mode 100644 index 000000000..093aba7db --- /dev/null +++ b/eo/tutorial/html/index.html @@ -0,0 +1,178 @@ + + + + + + Tutorial EO + + +Top-Down page - Bottom-up +page - Programming hints - EO +documentation +
+
+

+EO Tutorial

+Welcome to EO - the Evolving Objects library. What is this tutorial good +for? +
Well,  the short term idea here is to help you build +your own Evolutionary Algorithms using EO - while the long term +idea is that you will be able to contribute to EO, and ultimately write +our +EAs :-) +

+About this tutorial

+This tutorial can be used in 2 different ways: top-down and bottom-up. +
    +
  • +Top-down means you start from a very +simple, ready-to-run algorithm, and gradually modify it, making +it both more powerful and more complex.
  • + +
  • +Bottom-up means you start by examining the +components +of an EA one by one, down to the level of complexity you feel comfortable +with, and then build the whole algorithm using those components you need +(or the one you are mastering). Such approach might be viewed as going +through a simplified user guide, too.
  • +
+However, it is strongly recommended +that you take some time on the first lesson of the Top-down approach to +get familiar with the basic concepts that are used throughout EO. Anyway, +as of today, November 29, the Bottom-up page is not written yet :-) +

Related documents +

    +
  • +There are of course a few (very few) programming +hints that you should know.
  • + +
  • +THe EO documentation - automatically +generated from the comments in the code - is very helpful, to get an idea +of the inheritance diagrams of EO classes, and to quickly reach some specific +part of the code.
  • + +
    The top page of each class documentation is for instance the inheritance +diagram of the class, and you'll learn a lot by simply looking at it. +
  • +And, last but not least, we assume you know approximately that an Evolutionary +Algorithm looks like this, but otherwise you can try this very +brief introduction).
  • +
+ +


Colors and navigation: +

You will see this diagram in quite many places, as for instance at the +top of all examples - usually it will be clicable and will help you navigate +among the different parts of an EO program. See the brief +introduction to Evolutionary Computation for a detailed explanation. +

+

+ +

But in the text itself, colors are important, +as they will be used throughout this tutorial to clearly mark which part +of the algorithm we are discussing. So please keep in mind that, whereas +orange +is for emphasis, +

    +
  • +Yellowish is for representation, +i.e. the choice of the genotype
  • + +
  • +Magenta is for the stochastic +operators that are representation-dependent, +i.e. initialisation and variation operators +(crossover, mutation +and the like).
  • + +
  • +Green is for the implementation of Darwinism, +i.e. the way the individuals are selected +for reproduction and survive.
  • + +
  • +Red is for evaluation, i.e. the computation +of the fitness of all individuals
  • + +
  • +Blue is for interactions of the user and the +program, as for instance choice of stopping criterion, +on-line display of nice statistics or initial +choice +of all program parameters.
  • + +
  • +Brown is for everything that is NOT part of +any of the above, i.e. random number generator, or basic C++/STL syntax +.
  • + +
  • +Note that pink will be used to desctibe the +syntax of compile orders (i.e. at the oepratoring system level, see e.g. +below).
  • + +
  • +Last, but not least, all links into EO documentation +will use the Helvetica typeface, like this line you are now reading.
  • +
+ +
    +
  • +an interface that would allow you to build your Evolutionary Programs by +a few clics; such a thing does exist, is called EASEA, +and is complementary to this tutorial as it helps the user to build some +simple EO programs from simple description. But there are things that EASEA +cannot do, and you will have to do it yourself and will need to imcrease +your knowledge about EO for that.
  • +
+ +

+Before you start

+You should of course have downloaded and installed the whole EO +library (how did you get this file if not???). +
So we'll assume that you are now in the Tutorial directory, and that +your prompt looks something like +

(myname@myhost) EOdir/Tutorial % +

so you should now type in +

make lesson1 +

and see something like +

(myname@myhost) +EOdir/Tutorial % make lesson1 +
c++ -DPACKAGE=\"eo\" -DVERSION=\"0.9.1\" +-I. -I../../src -Wall -g -c FirstBitGA.cpp +
c++ -Wall -g -o FirstBitGA FirstBitGA.o +../../src/libeo.a ../../src/utils/libeoutils.a +
c++ -DPACKAGE=\"eo\" -DVERSION=\"0.9.1\" +-I. -I../../src -Wall -g -c FirstRealGA.cpp +
c++ -Wall -g -o FirstRealGA FirstRealGA.o +../../src/libeo.a ../../src/utils/libeoutils.a +

and two now executable files should have appeared in the subdirectory +Lesson1, namely FirstBitGA +and FirstRealGA (see First +lesson to know more about these two ready-to-run programs). If this +doesn't work, please go back to the main EO directory and run the installation +program. +

You should also test that you can access the EO documentation in the +menu line below: you might not need to go there immediately, but just in +case you make rapid progress ... This menu bar should be on all pages of +this tutorial, allowing you to navigate easily. +

Last, but not least: EO is improving only  from the good will of +contributors. This is also true for this tutorial: If you find anything +that you think could be improved, you are welcome to e-mail +me. +

+

Enjoy! +


Top-Down page +- Bottom-up page - Programming +hints - EO +documentation
+ +
+
+Marc Schoenauer
+ +
Last +modified: Fri Nov 28 2000  + + diff --git a/eo/tutorial/html/lesson1.ps b/eo/tutorial/html/lesson1.ps new file mode 100644 index 000000000..d71bcc539 --- /dev/null +++ b/eo/tutorial/html/lesson1.ps @@ -0,0 +1,1952 @@ +%!PS-Adobe-3.0 +%%BoundingBox: 54 72 535 761 +%%Creator: Mozilla (NetScape) HTML->PS +%%DocumentData: Clean7Bit +%%Orientation: Portrait +%%Pages: 5 +%%PageOrder: Ascend +%%Title: Tutorial: Lesson 1 +%%EndComments +%%BeginProlog +[ /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef + /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef + /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef + /.notdef /.notdef /space /exclam /quotedbl /numbersign /dollar /percent /ampersand /quoteright + /parenleft /parenright /asterisk /plus /comma /hyphen /period /slash /zero /one + /two /three /four /five /six /seven /eight /nine /colon /semicolon + /less /equal /greater /question /at /A /B /C /D /E + /F /G /H /I /J /K /L /M /N /O + /P /Q /R /S /T /U /V /W /X /Y + /Z /bracketleft /backslash /bracketright /asciicircum /underscore /quoteleft /a /b /c + /d /e /f /g /h /i /j /k /l /m + /n /o /p /q /r /s /t /u /v /w + /x /y /z /braceleft /bar /braceright /asciitilde /.notdef /.notdef /.notdef + /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef + /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef + /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef + /space /exclamdown /cent /sterling /currency /yen /brokenbar /section /dieresis /copyright + /ordfeminine /guillemotleft /logicalnot /hyphen /registered /macron /degree /plusminus /twosuperior /threesuperior + /acute /mu /paragraph /periodcentered /cedilla /onesuperior /ordmasculine /guillemotright /onequarter /onehalf + /threequarters /questiondown /Agrave /Aacute /Acircumflex /Atilde /Adieresis /Aring /AE /Ccedilla + /Egrave /Eacute /Ecircumflex /Edieresis /Igrave /Iacute /Icircumflex /Idieresis /Eth /Ntilde + /Ograve /Oacute /Ocircumflex /Otilde /Odieresis /multiply /Oslash /Ugrave /Uacute /Ucircumflex + /Udieresis /Yacute /Thorn /germandbls /agrave /aacute /acircumflex /atilde /adieresis /aring + /ae /ccedilla /egrave /eacute /ecircumflex /edieresis /igrave /iacute /icircumflex /idieresis + /eth /ntilde /ograve /oacute /ocircumflex /otilde /odieresis /divide /oslash /ugrave + /uacute /ucircumflex /udieresis /yacute /thorn /ydieresis] /isolatin1encoding exch def +/c { matrix currentmatrix currentpoint translate + 3 1 roll scale newpath 0 0 1 0 360 arc setmatrix } bind def +/F0 + /Times-Roman findfont + dup length dict begin + {1 index /FID ne {def} {pop pop} ifelse} forall + /Encoding isolatin1encoding def + currentdict end +definefont pop +/f0 { /F0 findfont exch scalefont setfont } bind def +/F1 + /Times-Bold findfont + dup length dict begin + {1 index /FID ne {def} {pop pop} ifelse} forall + /Encoding isolatin1encoding def + currentdict end +definefont pop +/f1 { /F1 findfont exch scalefont setfont } bind def +/F2 + /Times-Italic findfont + dup length dict begin + {1 index /FID ne {def} {pop pop} ifelse} forall + /Encoding isolatin1encoding def + currentdict end +definefont pop +/f2 { /F2 findfont exch scalefont setfont } bind def +/F3 + /Times-BoldItalic findfont + dup length dict begin + {1 index /FID ne {def} {pop pop} ifelse} forall + /Encoding isolatin1encoding def + currentdict end +definefont pop +/f3 { /F3 findfont exch scalefont setfont } bind def +/F4 + /Courier findfont + dup length dict begin + {1 index /FID ne {def} {pop pop} ifelse} forall + /Encoding isolatin1encoding def + currentdict end +definefont pop +/f4 { /F4 findfont exch scalefont setfont } bind def +/F5 + /Courier-Bold findfont + dup length dict begin + {1 index /FID ne {def} {pop pop} ifelse} forall + /Encoding isolatin1encoding def + currentdict end +definefont pop +/f5 { /F5 findfont exch scalefont setfont } bind def +/F6 + /Courier-Oblique findfont + dup length dict begin + {1 index /FID ne {def} {pop pop} ifelse} forall + /Encoding isolatin1encoding def + currentdict end +definefont pop +/f6 { /F6 findfont exch scalefont setfont } bind def +/F7 + /Courier-BoldOblique findfont + dup length dict begin + {1 index /FID ne {def} {pop pop} ifelse} forall + /Encoding isolatin1encoding def + currentdict end +definefont pop +/f7 { /F7 findfont exch scalefont setfont } bind def +/rhc { + { + currentfile read { + dup 97 ge + { 87 sub true exit } + { dup 48 ge { 48 sub true exit } { pop } ifelse } + ifelse + } { + false + exit + } ifelse + } loop +} bind def + +/cvgray { % xtra_char npix cvgray - (string npix long) + dup string + 0 + { + rhc { cvr 4.784 mul } { exit } ifelse + rhc { cvr 9.392 mul } { exit } ifelse + rhc { cvr 1.824 mul } { exit } ifelse + add add cvi 3 copy put pop + 1 add + dup 3 index ge { exit } if + } loop + pop + 3 -1 roll 0 ne { rhc { pop } if } if + exch pop +} bind def + +/smartimage12rgb { % w h b [matrix] smartimage12rgb - + /colorimage where { + pop + { currentfile rowdata readhexstring pop } + false 3 + colorimage + } { + exch pop 8 exch + 3 index 12 mul 8 mod 0 ne { 1 } { 0 } ifelse + 4 index + 6 2 roll + { 2 copy cvgray } + image + pop pop + } ifelse +} def +/cshow { dup stringwidth pop 2 div neg 0 rmoveto show } bind def +/rshow { dup stringwidth pop neg 0 rmoveto show } bind def +/BeginEPSF { + /b4_Inc_state save def + /dict_count countdictstack def + /op_count count 1 sub def + userdict begin + /showpage {} def + 0 setgray 0 setlinecap 1 setlinewidth 0 setlinejoin + 10 setmiterlimit [] 0 setdash newpath + /languagelevel where + { pop languagelevel 1 ne + { false setstrokeadjust false setoverprint } if + } if +} bind def +/EndEPSF { + count op_count sub {pop} repeat + countdictstack dict_count sub {end} repeat + b4_Inc_state restore +} bind def +%%EndProlog +%%Page: 1 1 +%%BeginPageSetup +/pagelevel save def +54 0 translate +%%EndPageSetup +newpath 0 72 moveto 481 0 rlineto 0 689 rlineto -481 0 rlineto closepath clip newpath +0 748.4 moveto +12 f0 +(Lesson 2) show +42.9 748.4 moveto +12 f0 +( - ) show +52.8 748.4 moveto +12 f0 +(Tutorial main page) show +144.1 748.4 moveto +12 f0 +( - ) show +154 748.4 moveto +12 f0 +(Top-Down page) show +232.3 748.4 moveto +12 f0 +( - ) show +242.2 748.4 moveto +12 f0 +(Bottom-up page) show +319.8 748.4 moveto +12 f0 +( - ) show +329.7 748.4 moveto +12 f0 +(Programming hints) show +422 748.4 moveto +12 f0 +( -) show +428.9 748.4 moveto +14 f0 +(EO) show +0 732.9 moveto +14 f0 +(documentation) show +83.2 732.9 moveto +12 f0 +( ) show +0 723.4 moveto +481 0 rlineto 0 -1.4 rlineto -481 0 rlineto closepath fill +146.5 680.9 moveto +24 f1 +(Tutorial: Lesson 1) show +0 651.7 moveto +12 f0 +(This lesson will let you ) show +18.1 629.2 moveto +3.3 3.3 c fill +28 625.1 moveto +12 f0 +(run) show +43.9 625.1 moveto +12 f0 +( your first Evolutionary Algorithm written within EO Library, choosing between evolving) show +28 611.8 moveto +12 f0 +(bitstrings) show +72.6 611.8 moveto +12 f0 +(, or evolving ) show +136.5 611.8 moveto +12 f0 +(vectors of real numbers) show +249.4 611.8 moveto +12 f0 +(,) show +252.3 611.8 moveto +12 f0 +( ) show +18.1 602.6 moveto +3.3 3.3 c fill +28 598.5 moveto +12 f0 +(browse) show +62.6 598.5 moveto +12 f0 +( through the code of these algorithms, or) show +257.2 598.5 moveto +12 f0 +( ) show +18.1 589.3 moveto +3.3 3.3 c fill +28 585.2 moveto +12 f0 +(follow the ) show +79.9 585.2 moveto +12 f0 +(guided tour) show +134.9 585.2 moveto +12 f0 +(.) show +137.8 585.2 moveto +12 f0 +( ) show +0 558.6 moveto +12 f0 +(Later you will be asked to ) show +18.1 536.1 moveto +3.3 3.3 c fill +28 532 moveto +12 f0 +(write your own ) show +104.3 532 moveto +12 f0 +(fitness function) show +178.6 532 moveto +12 f0 +(,) show +181.5 532 moveto +12 f0 +( ) show +18.1 522.8 moveto +3.3 3.3 c fill +28 518.7 moveto +12 f0 +(use different kinds of ) show +133.3 518.7 moveto +12 f0 +(selection procedures) show +231.6 518.7 moveto +12 f0 +( in the framework of a generational GA ) show +424.2 518.7 moveto +12 f0 +(evolution) show +28 505.4 moveto +12 f0 +(engine) show +59.9 505.4 moveto +12 f0 +(,) show +62.8 505.4 moveto +12 f0 +( ) show +18.1 496.2 moveto +3.3 3.3 c fill +28 492.1 moveto +12 f0 +(check that EO let you separate the ) show +194.9 492.1 moveto +12 f0 +(representation) show +262.8 492.1 moveto +12 f0 +( from the ) show +309.7 492.1 moveto +12 f0 +(evolution engine) show +390 492.1 moveto +12 f0 +(.) show +392.9 492.1 moveto +12 f0 +( ) show +0 463.2 moveto +14 f1 +(I want to run an Evolutionary Algorithm ) show +248.5 463.2 moveto +14 f1 +(now) show +0 436.2 moveto +12 f0 +(You can choose to run a standard ) show +162.9 436.2 moveto +12 f0 +(bitstring Genetic Algorithm) show +296.2 436.2 moveto +12 f0 +( \(as defined in Goldberg's book\) or a) show +0 422.9 moveto +12 f0 +(standard ) show +43.6 422.9 moveto +12 f0 +(real-valued genetic algorithm) show +184.8 422.9 moveto +12 f0 +(, as proposed in Micahlewicz's book. ) show +0 395.8 moveto +12 f0 +(If you have not already done what was recommended in the ) show +289.5 395.8 moveto +12 f0 +(Tutorial main page) show +380.8 395.8 moveto +12 f0 +( , do it ) show +414.4 395.8 moveto +12 f1 +(NOW) show +444.3 395.8 moveto +12 f0 +(. Then) show +0 382.5 moveto +12 f0 +(go to the Lesson1 sub-dir of the tutorial dir, and simply type at the system prompt ) show +0 355.9 moveto +10 f4 +(\(myname@myhost\) EOdir/Tutorial/Lesson1 % ) show +246 355.9 moveto +10 f4 +(FirstRealGA) show +312 355.9 moveto +12 f0 +( ) show +0 342.6 moveto +12 f0 +(or ) show +0 329.3 moveto +10 f4 +(\(myname@myhost\) EOdir/Tutorial/Lesson1 % ) show +246 329.3 moveto +10 f4 +(FirstBitGA) show +306 329.3 moveto +12 f0 +( ) show +0 302.7 moveto +12 f0 +(and something should happen. ) show +0 273.8 moveto +14 f1 +(What is happening?) show +0 246.8 moveto +12 f0 +(At the moment, the ) show +95.6 246.8 moveto +12 f0 +(FirstBitGA) show +149.6 246.8 moveto +12 f0 +( maximizes the number of ones in the bitstring \(also calls the) show +0 233.5 moveto +12 f0 +(OneMaxfunction) show +81.9 233.5 moveto +12 f0 +(, whose solution is, as you can guess, ) show +263.5 233.5 moveto +12 f0 +(11111111) show +311.4 233.5 moveto +12 f0 +(\), and the ) show +359.3 233.5 moveto +12 f0 +(FirstRealGA) show +420.6 233.5 moveto +12 f0 +( is) show +0 220.2 moveto +12 f0 +(maximizing \(the default action for EO is to maximize\) the inverse of the sum \(i.e. minimizing the) show +0 206.9 moveto +12 f0 +(sum\) of the square of its variables \(also called the ) show +241.2 206.9 moveto +12 f0 +(sphere function) show +315.5 206.9 moveto +12 f0 +(, whose solution is ... ) show +419.8 206.9 moveto +12 f0 +(all zeroes) show +465.4 206.9 moveto +12 f0 +(\). ) show +0 180.3 moveto +12 f0 +(And what you see on the screen when running one of these two programs is, in each case, the initial) show +0 167 moveto +12 f0 +(and final population of an Evolutionary run, one individual per line, its fitness first, then the number) show +0 153.7 moveto +12 f0 +(of items \(bits or real numbers\) of the genotype, and the genotype itself. The final population) show +0 140.4 moveto +12 f0 +(hopefully contains the solution in the discrete case, and is close to it in the continuous case. ) show +0 113.8 moveto +12 f0 +(You need now to take a look at either programs by browsing alone through the sources for) show +0 100.5 moveto +12 f0 +(FirstBitGA) show +54 100.5 moveto +12 f0 +( and ) show +77.3 100.5 moveto +12 f0 +(FirstRealGA) show +138.6 100.5 moveto +12 f0 +(, or follow the guided tour below, or go directly to the ) show +400.5 100.5 moveto +12 f0 +(exercises) show +444.4 100.5 moveto +12 f0 +(. ) show +pagelevel restore +showpage +%%Page: 2 2 +%%BeginPageSetup +/pagelevel save def +54 0 translate +%%EndPageSetup +newpath 0 72 moveto 481 0 rlineto 0 689 rlineto -481 0 rlineto closepath clip newpath +0 747.9 moveto +14 f1 +(Browsing the code:) show +18.1 724.5 moveto +3.3 3.3 c fill +28 720.4 moveto +12 f1 +(General includes:) show +118.3 720.4 moveto +12 f0 +(Like all C-like code, the file starts with include directives \() show +401.2 720.4 moveto +12 f0 +(Bit) show +415.8 720.4 moveto +12 f0 +( - ) show +425.7 720.4 moveto +12 f0 +(Real) show +447.6 720.4 moveto +12 f0 +(\).) show +28 706.6 moveto +12 f0 +(Apart from standard includes, the spedific file to include is ) show +313.6 706.6 moveto +12 f1 +(eo) show +324.9 706.6 moveto +12 f0 +(: this is a file that contains the) show +28 693.3 moveto +12 f0 +(list of the most important EO files.) show +195 693.3 moveto +12 f0 +( ) show +28 680 moveto +12 f0 +( ) show +18.1 670.3 moveto +3.3 3.3 c fill +28 666.2 moveto +12 f1 +(Representation) show +105.9 666.2 moveto +12 f0 +(: you then have to delclare the type of individuals you will be handling. All) show +28 652.9 moveto +12 f0 +(evolution-related objects you will need are templatized w.r.t. the type of individuals.) show +433.6 652.9 moveto +12 f0 +( ) show +46.1 643.2 moveto +3.3 3.3 c stroke +56 639.1 moveto +12 f0 +(Bit) show +70.6 639.1 moveto +12 f0 +( You say here that you will be handling ) show +262.9 639.1 moveto +12 f1 +(Bitstring genotypes) show +361.8 639.1 moveto +12 f0 +(, whose fitness is a) show +56 625.8 moveto +12 f0 +(double. This makes Indi derive from the ) show +251.9 625.8 moveto +12 f0 +(STL class) show +299.5 625.8 moveto +12 f0 +( ) show +302.4 625.8 moveto +12 f0 +(vector) show +367.2 625.8 moveto +12 f0 +( ) show +46.1 616.1 moveto +3.3 3.3 c stroke +56 612 moveto +12 f0 +(Real) show +77.9 612 moveto +12 f0 +( You say here that you will be handling ) show +270.2 612 moveto +12 f1 +(Real-valued genotypes) show +385.1 612 moveto +12 f0 +(, whose fitness is a) show +56 598.7 moveto +12 f0 +(double. This makes Indi derive from the ) show +251.9 598.7 moveto +12 f0 +(STL class) show +299.5 598.7 moveto +12 f0 +( ) show +302.4 598.7 moveto +12 f0 +(vector) show +378.5 598.7 moveto +12 f0 +( ) show +56 585.4 moveto +12 f0 +( ) show +18.1 575.7 moveto +3.3 3.3 c fill +28 571.6 moveto +12 f1 +(Fitness function:) show +113.6 571.6 moveto +12 f0 +( the code for the fitness function is included in the file. It must take as) show +28 558.3 moveto +12 f0 +(argument a reference to an individual \(at the moment\).) show +290.2 558.3 moveto +12 f0 +( ) show +46.1 549.1 moveto +3.3 3.3 c stroke +56 545 moveto +12 f0 +(Bit) show +70.6 545 moveto +12 f0 +( This function simply computes the number of ones of the bitstring \(it's called the) show +56 531.7 moveto +12 f0 +(OneMax function\). The optimum is of course the all-ones bitstring.) show +378.9 531.7 moveto +12 f0 +( ) show +46.1 522.5 moveto +3.3 3.3 c stroke +56 518.4 moveto +12 f0 +(Real) show +77.9 518.4 moveto +12 f0 +( This function simply computes the inverse of the sum of the squares of all) show +56 505.1 moveto +12 f0 +(variables \(also called the sphere function\). The optimum is of course the all-zeroes) show +56 491.8 moveto +12 f0 +(vector.) show +88.9 491.8 moveto +12 f0 +( ) show +56 478.5 moveto +12 f0 +( ) show +18.1 468.8 moveto +3.3 3.3 c fill +28 464.7 moveto +12 f1 +(Parameters) show +87.3 464.7 moveto +12 f0 +(: all parameters of the algorithm are declared here \() show +333.5 464.7 moveto +12 f0 +(Bit) show +348.1 464.7 moveto +12 f0 +( - ) show +358 464.7 moveto +12 f0 +(Real) show +379.9 464.7 moveto +12 f0 +(\), and their values) show +28 451.4 moveto +12 f0 +(and assigned. Of course, this means that you will need to recompile to change these values -) show +28 438.1 moveto +12 f0 +(see Lesson 3 to get rid of that heavy requirement.) show +265.2 438.1 moveto +12 f0 +( ) show +28 424.8 moveto +12 f0 +( ) show +18.1 415.1 moveto +3.3 3.3 c fill +28 411 moveto +12 f1 +(Random seeding:) show +117 411 moveto +12 f0 +( Random numbers play an important role in Evolutionary Algorithms. See) show +28 397.7 moveto +12 f0 +(in ) show +40.3 397.7 moveto +12 f0 +(EO programming hints) show +150.9 397.7 moveto +12 f0 +( more details about how this is simulated in EO - but as far as you) show +28 384.4 moveto +12 f0 +(are concerned now, remember that the ) show +214.9 384.4 moveto +12 f0 +(global Random Number Generator) show +381.8 384.4 moveto +12 f0 +( is called ) show +427.4 384.4 moveto +12 f5 +(rng) show +448.9 384.4 moveto +12 f0 +( and) show +28 370.8 moveto +12 f0 +(should be used everywhere you need a realization of a random variable of known law.) show +28 357.5 moveto +12 f0 +(Moreover, this RNG requires a ) show +179.9 357.5 moveto +12 f5 +(seed) show +208.6 357.5 moveto +12 f0 +(, which is set here \() show +301.9 357.5 moveto +12 f0 +(Bit) show +316.5 357.5 moveto +12 f0 +( - ) show +326.4 357.5 moveto +12 f0 +(Real) show +348.3 357.5 moveto +12 f0 +(\): everytime you run the) show +28 343.9 moveto +12 f0 +(algorithm with the ) show +119.6 343.9 moveto +12 f0 +(same seed) show +168.5 343.9 moveto +12 f0 +(, you will get the ) show +252.4 343.9 moveto +12 f0 +(same result) show +306.7 343.9 moveto +12 f0 +(. Hence, to test the robustness of) show +28 330.6 moveto +12 f0 +(your algorithm, you should run it with different seeds. This is rather time consuming in the) show +28 317.3 moveto +12 f0 +(present programs, so we suggest that you wait until Lesson 3 to do so.) show +364.3 317.3 moveto +12 f0 +( ) show +28 304 moveto +12 f0 +( ) show +18.1 294.3 moveto +3.3 3.3 c fill +28 290.2 moveto +12 f1 +(Fitness function encapsulation: ) show +190.3 290.2 moveto +12 f0 +(EO is based on the notion of ) show +329.9 290.2 moveto +12 f0 +(functors) show +369.2 290.2 moveto +12 f0 +( - hence you now need) show +28 276.9 moveto +12 f0 +(to encapsulate your fitness function into a functor object. This is what is done here \() show +431.2 276.9 moveto +12 f0 +(Bit) show +445.8 276.9 moveto +12 f0 +( -) show +28 263.6 moveto +12 f0 +(Real) show +49.9 263.6 moveto +12 f0 +(\).) show +56.8 263.6 moveto +12 f0 +( ) show +28 250.3 moveto +12 f0 +( ) show +18.1 240.6 moveto +3.3 3.3 c fill +28 236.5 moveto +12 f1 +(Initialization) show +94 236.5 moveto +12 f0 +(: to initialize the population, first declare an empty object of class ) show +411.6 236.5 moveto +10 f5 +(eoPop) show +477.6 236.5 moveto +12 f0 +(,) show +28 223.2 moveto +12 f0 +(which is basically an ) show +131.3 223.2 moveto +12 f0 +(STL) show +152.6 223.2 moveto +12 f0 +( ) show +155.5 223.2 moveto +10 f5 +(vector) show +227.5 223.2 moveto +12 f0 +(, then fill it with Indi's.) show +339.1 223.2 moveto +12 f0 +( And remember that) show +28 209.9 moveto +10 f5 +(v.push_back) show +94 209.9 moveto +12 f0 +( simply appends its argument at the end of ) show +300.3 209.9 moveto +12 f0 +(STL) show +321.6 209.9 moveto +12 f0 +( vector ) show +357.5 209.9 moveto +10 f5 +(v.) show +369.5 209.9 moveto +12 f0 +( ) show +46.1 198.9 moveto +3.3 3.3 c stroke +56 194.8 moveto +12 f0 +(Bit) show +70.6 194.8 moveto +12 f0 +( ) show +73.5 194.8 moveto +10 f5 +(rng.flip\(\)) show +133.5 194.8 moveto +12 f0 +( return a ) show +176.4 194.8 moveto +14 f0 +(random boolean) show +266.9 194.8 moveto +12 f0 +( ) show +46.1 183.4 moveto +3.3 3.3 c stroke +56 179.3 moveto +12 f0 +(Real) show +77.9 179.3 moveto +12 f0 +( ) show +80.8 179.3 moveto +10 f5 +(rng.uniform\(\)) show +158.8 179.3 moveto +12 f0 +( returns a ) show +206.4 179.3 moveto +14 f0 +(real value uniformly drawn in [0,1].) show +407.4 179.3 moveto +12 f0 +( ) show +56 165.6 moveto +12 f0 +( ) show +18.1 155.9 moveto +3.3 3.3 c fill +28 151.8 moveto +12 f1 +(Output) show +65.3 151.8 moveto +12 f0 +(: take a snapshot at the initial population \() show +266.6 151.8 moveto +12 f0 +(Bit) show +281.2 151.8 moveto +12 f0 +( - ) show +291.1 151.8 moveto +12 f0 +(Real) show +313 151.8 moveto +12 f0 +(\). Sort it first, so the best) show +28 138.5 moveto +12 f0 +(individuals are first, and display it. Note that an eoPop has a ) show +319.9 138.5 moveto +10 f5 +(<<) show +331.9 138.5 moveto +12 f0 +( method, which means that a) show +28 125.2 moveto +12 f0 +(simple ) show +63 125.2 moveto +10 f5 +(os << pop ) show +123 125.2 moveto +12 f0 +(streams the ) show +180.3 125.2 moveto +10 f5 +(pop) show +198.3 125.2 moveto +12 f0 +( onto the ostream ) show +284.2 125.2 moveto +10 f5 +(os) show +296.2 125.2 moveto +12 f0 +(. This is true for ) show +376.1 125.2 moveto +12 f0 +(all objects of of class) show +28 109.6 moveto +14 f1 +(eoPrintable) show +97.2 109.6 moveto +12 f0 +( \(most EO objects\) through the method ) show +287.5 109.6 moveto +10 f5 +(printOn) show +329.5 109.6 moveto +12 f0 +( \(which is then called by the ) show +467.8 109.6 moveto +10 f5 +(<<) show +28 95.9 moveto +12 f0 +(operator\).) show +74.9 95.9 moveto +12 f0 +( ) show +28 82.6 moveto +12 f0 +( ) show +pagelevel restore +showpage +%%Page: 3 3 +%%BeginPageSetup +/pagelevel save def +54 0 translate +%%EndPageSetup +newpath 0 72 moveto 481 0 rlineto 0 689 rlineto -481 0 rlineto closepath clip newpath +18.1 753.8 moveto +3.3 3.3 c fill +28 749.7 moveto +12 f1 +(Evolution engine:) show +118.3 749.7 moveto +12 f0 +( The selection/replacement mechanism \() show +312.2 749.7 moveto +12 f0 +(Bit) show +326.8 749.7 moveto +12 f0 +( - ) show +336.7 749.7 moveto +12 f0 +(Real) show +358.6 749.7 moveto +12 f0 +(\) is a simple generational) show +28 734.1 moveto +12 f0 +(GA here: a simple selector, and a generational replacement. The ) show +339.2 734.1 moveto +14 f1 +(eoDetTournament) show +448.8 734.1 moveto +12 f0 +( has) show +28 720.4 moveto +12 f0 +(been chosen as a robust selection, and the generational replacement \(all parents are replaced) show +28 707.1 moveto +12 f0 +(by the offspring\) is hard-coded in the eoSGA ) show +247.9 707.1 moveto +12 f0 +(algorithm) show +294.5 707.1 moveto +12 f0 +(.) show +297.4 707.1 moveto +12 f0 +( ) show +28 693.8 moveto +12 f0 +( ) show +18.1 684.1 moveto +3.3 3.3 c fill +28 680 moveto +12 f1 +(Variation operators) show +129.6 680 moveto +12 f0 +(:) show +132.9 680 moveto +12 f0 +( in the simple algorithm considered here, individuals undergo ) show +430.8 680 moveto +12 f0 +(crossover) show +28 664.4 moveto +12 f0 +(and ) show +48.3 664.4 moveto +12 f0 +(mutation) show +90.9 664.4 moveto +12 f0 +(. In EO, these operators are \() show +228.8 664.4 moveto +12 f0 +(functor) show +263.4 664.4 moveto +12 f0 +(\) objects of class) show +343.7 664.4 moveto +12 f0 +( ) show +346.6 664.4 moveto +14 f1 +(eoQuadOp) show +411.9 664.4 moveto +12 f0 +( \(binary) show +28 648.4 moveto +12 f0 +(operator that modifies both its arguments\) and ) show +252.9 648.4 moveto +14 f1 +(eoMonOp) show +312.7 648.4 moveto +12 f0 +( \(unary operator\). These operators) show +28 634.7 moveto +12 f0 +(are applied in turn to all selected parents, according to user-defined probabilities. These) show +28 621.4 moveto +12 f0 +(probabilities are defined with all other ) show +214.6 621.4 moveto +12 f0 +(parameters) show +267.2 621.4 moveto +12 f0 +(, and will be passed to the ) show +394.5 621.4 moveto +12 f5 +(eoSGA) show +430.6 621.4 moveto +12 f0 +(algorithm) show +477.2 621.4 moveto +12 f0 +(.) show +46.1 609.6 moveto +3.3 3.3 c stroke +56 605.5 moveto +12 f0 +(Bit) show +70.6 605.5 moveto +12 f0 +( The crossover ) show +144.2 605.5 moveto +14 f1 +(eoBinCrossover) show +239 605.5 moveto +12 f0 +( is the standard ) show +314.3 605.5 moveto +12 f0 +(1-point crossover) show +397.9 605.5 moveto +12 f0 +(, and) show +56 589.5 moveto +14 f1 +(eoBinMutation) show +146.2 589.5 moveto +12 f0 +( is the standard ) show +221.5 589.5 moveto +12 f0 +(bit-flip mutation) show +300.5 589.5 moveto +12 f0 +( that randomly flips all bits with a) show +56 575.8 moveto +12 f0 +(given probability ) show +141.3 575.8 moveto +10 f5 +(P_MUT_PER_BIT.) show +225.3 575.8 moveto +12 f0 +( ) show +56 562 moveto +12 f1 +(Warning) show +102 562 moveto +12 f0 +(: the ) show +125.9 562 moveto +10 f5 +(P_MUT_PER_BIT) show +203.9 562 moveto +12 f0 +( probability is an ) show +287.8 562 moveto +12 f0 +(internal parameter) show +375.4 562 moveto +12 f0 +( of the) show +56 548.2 moveto +12 f5 +(eoBinMutation) show +149.5 548.2 moveto +12 f0 +(, it is ) show +176.1 548.2 moveto +12 f1 +(NOT) show +202.1 548.2 moveto +12 f0 +( the probability of mutation at the individual level. EO) show +56 534.6 moveto +12 f0 +(corrects what can be viewed as an inconsistency in Holland's original work, further) show +56 521.3 moveto +12 f0 +(used in Goldberg's book by separating the probability of mutation for each individual) show +56 508 moveto +12 f0 +(\(independent of the type of mutation that will be applied\) from the probability of) show +56 494.7 moveto +12 f0 +(flipping each bit, which is specific of the bit-flip mutation. Hence, to run the same) show +56 481.4 moveto +12 f0 +(algorithm as Goldberg's SGA, the mutation probability \(at individual level\) is 1, and the) show +56 468.1 moveto +12 f0 +(probability of flipping each bit is ) show +217.3 468.1 moveto +10 f5 +(P_MUT_PER_BIT.) show +301.3 468.1 moveto +12 f0 +( ) show +46.1 456.6 moveto +3.3 3.3 c stroke +56 452.5 moveto +12 f0 +(Real) show +77.9 452.5 moveto +12 f0 +( The crossover ) show +151.5 452.5 moveto +14 f1 +(eoArithmeticCrossover) show +290.6 452.5 moveto +12 f0 +( is the standard ) show +365.9 452.5 moveto +12 f0 +(arithmetic crossover) show +463.5 452.5 moveto +12 f0 +( for) show +56 438.8 moveto +12 f0 +(real-valued vectors, that chooses a point randomly on the segment between both parents) show +56 423.2 moveto +12 f0 +(\(also termed ) show +118.6 423.2 moveto +12 f0 +(BLX-0) show +152.5 423.2 moveto +12 f0 +(\). ) show +162.4 423.2 moveto +14 f1 +(eoUniformMutation) show +282.9 423.2 moveto +12 f0 +( is the ) show +314.5 423.2 moveto +12 f0 +(uniform mutation) show +398.8 423.2 moveto +12 f0 +( for real-valued) show +56 409.5 moveto +12 f0 +(vectors that choses a new value for each variable uniformly on an interval centered on) show +56 396.2 moveto +12 f0 +(the parent value. The width of the interval is an ) show +286.2 396.2 moveto +12 f0 +(internal parameter) show +373.8 396.2 moveto +12 f0 +( of the object, here) show +56 382.9 moveto +12 f0 +(called ) show +87.6 382.9 moveto +10 f5 +(EPSILON) show +129.7 382.9 moveto +12 f0 +(.) show +132.6 382.9 moveto +12 f0 +( ) show +56 369.6 moveto +12 f0 +( ) show +18.1 359.9 moveto +3.3 3.3 c fill +28 355.8 moveto +12 f1 +(Stopping criterion:) show +125.6 355.8 moveto +12 f0 +( Specify a ) show +176.5 355.8 moveto +12 f0 +(maximum number of generations) show +336.1 355.8 moveto +12 f0 +( to run \() show +374.4 355.8 moveto +12 f0 +(Bit) show +389 355.8 moveto +12 f0 +( - ) show +398.9 355.8 moveto +12 f0 +(Real) show +420.8 355.8 moveto +12 f0 +(\): the) show +28 342.5 moveto +12 f0 +(simplest of all stopping criteria at the moment, using an object of a sub-class of class) show +28 326.9 moveto +14 f1 +(eoContinue) show +96.4 326.9 moveto +12 f0 +(.) show +99.3 326.9 moveto +12 f0 +( ) show +28 313.2 moveto +12 f0 +( ) show +18.1 303.5 moveto +3.3 3.3 c fill +28 299.4 moveto +12 f1 +(The algorithm: ) show +108.6 299.4 moveto +12 f0 +(the simple algorithm that is used here, called ) show +329.2 299.4 moveto +12 f5 +(eoSGA ) show +372.3 299.4 moveto +12 f0 +(requires as parameters) show +28 285.8 moveto +12 f0 +(a ) show +36.3 285.8 moveto +12 f0 +(selector) show +73.6 285.8 moveto +12 f0 +(, a ) show +87.9 285.8 moveto +12 f0 +(crossover) show +133.9 285.8 moveto +12 f0 +( and the associated ) show +227.2 285.8 moveto +12 f0 +(crossover rate) show +294.1 285.8 moveto +12 f0 +(, a ) show +308.4 285.8 moveto +12 f0 +(mutation) show +351 285.8 moveto +12 f0 +( and the associated) show +28 272.5 moveto +12 f0 +(mutation rate,) show +94.6 272.5 moveto +12 f0 +( and a ) show +126.2 272.5 moveto +12 f0 +(stopping criterion) show +211.1 272.5 moveto +12 f0 +(. Take a look at the corresponding ) show +377.7 272.5 moveto +12 f0 +(constructor) show +431.7 272.5 moveto +12 f0 +( of the) show +28 259.2 moveto +12 f0 +(class ) show +54.3 259.2 moveto +12 f5 +(eoSGA) show +90.4 259.2 moveto +12 f0 +(: it only initializes its ) show +194.7 259.2 moveto +12 f0 +(private data) show +251 259.2 moveto +12 f0 +( with the parameters. Now look at the) show +28 245.6 moveto +12 f0 +(operator\(\)) show +75.9 245.6 moveto +12 f0 +( method - the one that is called in the code for ) show +299.1 245.6 moveto +12 f0 +(FirstBitGA) show +353.1 245.6 moveto +12 f0 +( or ) show +369 245.6 moveto +12 f0 +(FirstRealGA) show +430.3 245.6 moveto +12 f0 +( - and) show +28 232.3 moveto +12 f0 +(you'll find out that is is as simple as it sounds.) show +250.3 232.3 moveto +12 f0 +( ) show +28 219 moveto +12 f0 +( ) show +18.1 209.3 moveto +3.3 3.3 c fill +28 205.2 moveto +12 f1 +(Output) show +65.3 205.2 moveto +12 f0 +(: After running the algorithm, output the sorted final population \() show +377.6 205.2 moveto +12 f0 +(Bit) show +392.2 205.2 moveto +12 f0 +( - ) show +402.1 205.2 moveto +12 f0 +(Real) show +424 205.2 moveto +12 f0 +(\) - and look) show +28 191.9 moveto +12 f0 +(at the best individual: this is the result of the algorithm.) show +293.6 191.9 moveto +12 f0 +( ) show +28 178.6 moveto +12 f0 +( ) show +18.1 168.9 moveto +3.3 3.3 c fill +28 164.8 moveto +12 f1 +(Main body:) show +87.6 164.8 moveto +12 f0 +( for technical reasons \(intercepting the exceptions\), we need a main like this one) show +28 151.5 moveto +12 f0 +(\() show +31.9 151.5 moveto +12 f0 +(Bit) show +46.5 151.5 moveto +12 f0 +( - ) show +56.4 151.5 moveto +12 f0 +(Real) show +78.3 151.5 moveto +12 f0 +(\)., and you should not touch it unless you know what you are doing. Simply note) show +28 138.2 moveto +12 f0 +(that this main calls the function main_function, which we have been discussing up to now!) show +463.6 138.2 moveto +12 f0 +( ) show +0 109.3 moveto +14 f1 +(Exercise 1: maximize your own function) show +0 82.3 moveto +12 f0 +(This is very easy - if your search space is that of bitstring or of unbounded real numbers. ) show +pagelevel restore +showpage +%%Page: 4 4 +%%BeginPageSetup +/pagelevel save def +54 0 translate +%%EndPageSetup +newpath 0 72 moveto 481 0 rlineto 0 689 rlineto -481 0 rlineto closepath clip newpath +18.1 748.8 moveto +3.3 3.3 c fill +28 744.7 moveto +12 f0 +(Go to the tutorial directory, and ) show +182.9 744.7 moveto +12 f0 +(copy) show +206.2 744.7 moveto +12 f0 +( the program you want to modify onto ) show +392.3 744.7 moveto +10 f5 +(mytest.cpp.) show +458.3 744.7 moveto +12 f0 +( ) show +18.1 735.5 moveto +3.3 3.3 c fill +28 731.4 moveto +12 f0 +(Edit) show +48 731.4 moveto +12 f0 +( ) show +51.1 731.4 moveto +10 f5 +(mytest.cpp) show +111.1 731.4 moveto +12 f0 +( with any text editor:) show +211 731.4 moveto +12 f0 +( ) show +18.1 722.2 moveto +3.3 3.3 c fill +28 718.1 moveto +12 f0 +(Modify) show +63.9 718.1 moveto +12 f0 +( the fitness function itself \() show +192.8 718.1 moveto +12 f0 +(binary_value) show +255.4 718.1 moveto +12 f0 +( in ) show +270.7 718.1 moveto +10 f5 +(FirstBitGA) show +330.7 718.1 moveto +12 f0 +(,) show +333.6 718.1 moveto +12 f0 +(real_value) show +383.5 718.1 moveto +12 f0 +( in ) show +401.8 718.1 moveto +10 f5 +(FirstRealGA) show +467.8 718.1 moveto +12 f0 +(\)) show +471.7 718.1 moveto +12 f0 +( ) show +18.1 708.9 moveto +3.3 3.3 c fill +28 704.8 moveto +12 f0 +(Compile) show +69.3 704.8 moveto +12 f0 +( the program by typing ) show +182.4 704.8 moveto +10 f5 +(make mytest) show +248.4 704.8 moveto +12 f0 +( at system prompt) show +334 704.8 moveto +12 f0 +( ) show +18.1 695.6 moveto +3.3 3.3 c fill +28 691.5 moveto +12 f0 +(Run) show +48 691.5 moveto +12 f0 +( the new program by entering the command ) show +260.8 691.5 moveto +10 f5 +(mytest) show +296.8 691.5 moveto +12 f0 +( at system prompt.) show +385.4 691.5 moveto +12 f0 +( ) show +0 662.6 moveto +14 f1 +(Exercise 2: check the differences between both programs) show +0 635.6 moveto +12 f0 +(Go and take a look at the code for these programs ) show +241.6 635.6 moveto +12 f0 +(\() show +245.5 635.6 moveto +12 f0 +(Bit) show +260.1 635.6 moveto +12 f0 +( - ) show +270 635.6 moveto +12 f0 +(Real) show +291.9 635.6 moveto +12 f0 +(\)) show +295.8 635.6 moveto +12 f0 +(. Use the symbolic representation of) show +0 622.3 moveto +12 f0 +(an Evolutionary Algorithm \(you should understand that figure now, otherwise go ) show +392.6 622.3 moveto +12 f0 +(there) show +416.5 622.3 moveto +12 f0 +( and come) show +0 609 moveto +12 f0 +(back\) to understand how each part of the EA is coded. Try to spot the differences between both) show +0 595.7 moveto +12 f0 +(codes: there are not so many! ) show +0 582.4 moveto +12 f0 +(After you've tried that alone, take a look at the ) show +227.6 582.4 moveto +12 f0 +(solution) show +266.2 582.4 moveto +12 f0 +( :-\) ) show +0 569.1 moveto +12 f0 +( ) show +0 540.2 moveto +14 f1 +(Exercise 3: change the selection procedure) show +0 513.2 moveto +12 f0 +(This is rather straightforward ... if you know what other types of selection are available! ) show +0 499.9 moveto +12 f0 +(At the moment, let's only consider only the following simple ones: ) show +18.1 477.4 moveto +3.3 3.3 c fill +28 473.3 moveto +12 f0 +(You already know the ) show +137.3 473.3 moveto +12 f0 +(tournament selection) show +237.6 473.3 moveto +12 f0 +( ) show +28 460 moveto +12 f0 +(Syntax: ) show +70.6 460 moveto +10 f5 +(eoDetTournament select\(T_SIZE\); ) show +310.6 460 moveto +10 f4 +(// T_SIZE in [2,POP_SIZE\)) show +460.6 460 moveto +12 f0 +( ) show +18.1 450.8 moveto +3.3 3.3 c fill +28 446.7 moveto +12 f0 +(Try the well-known ) show +126.3 446.7 moveto +12 f0 +(roulette wheel) show +194.6 446.7 moveto +12 f0 +( ) show +28 433.4 moveto +12 f0 +( ) show +30.9 433.4 moveto +12 f0 +(Syntax: ) show +70.5 433.4 moveto +12 f0 +( ) show +79.4 433.4 moveto +10 f5 +(eoProportional select;) show +247.4 433.4 moveto +12 f0 +( ) show +18.1 424.2 moveto +3.3 3.3 c fill +28 420.1 moveto +12 f0 +(Or the ) show +61.3 420.1 moveto +12 f0 +(stochastic binary tournament) show +199.9 420.1 moveto +12 f0 +( ) show +28 406.8 moveto +12 f0 +(Syntax: ) show +70.6 406.8 moveto +10 f5 +(eoStochTournament select\(RATE\); ) show +298.6 406.8 moveto +10 f4 +( // RATE in ]0.5,1]) show +430.6 406.8 moveto +12 f0 +( ) show +18.1 397.6 moveto +3.3 3.3 c fill +28 393.5 moveto +12 f0 +(and of course the ) show +113.3 393.5 moveto +12 f0 +(random) show +149.9 393.5 moveto +12 f0 +( selection should give bad results!) show +312.8 393.5 moveto +12 f0 +( ) show +28 380.2 moveto +12 f0 +(Syntax: ) show +70.6 380.2 moveto +10 f5 +(eoSelectRandom select;) show +0 354.1 moveto +12 f0 +(Note that all these classes of eoObjects are derived from the abstract class ) show +357.5 354.1 moveto +14 f1 +(eoSelectOne.) show +434 354.1 moveto +12 f0 +( ) show +0 321 moveto +18 f1 +(Lessons:) show +66 321 moveto +12 f0 +( ) show +18.1 297.2 moveto +3.3 3.3 c fill +28 293.1 moveto +12 f0 +(in EO, all actions are performed by ) show +199.9 293.1 moveto +12 f0 +(functor objects) show +271.5 293.1 moveto +12 f0 +( \(this section is the last time in this tutorial) show +28 279.8 moveto +12 f0 +(that there is a direct link to the ) show +177.3 279.8 moveto +12 f0 +(EO Programming hints) show +288.6 279.8 moveto +12 f0 +( page - though the link at top and) show +28 266.5 moveto +12 f0 +(bottom of all pages will remain there\).) show +212.3 266.5 moveto +12 f0 +( ) show +18.1 256.8 moveto +3.3 3.3 c fill +28 252.7 moveto +12 f0 +(in EO, all object you will usually need to manipulate are ) show +301.9 252.7 moveto +12 f0 +(templatized) show +357.8 252.7 moveto +12 f1 +( w.r.t. the type of the) show +28 238.9 moveto +12 f1 +(individual) show +80 238.9 moveto +12 f0 +( you are handling.) show +166.6 238.9 moveto +12 f0 +( ) show +18.1 229.2 moveto +3.3 3.3 c fill +28 225.1 moveto +12 f0 +(The type of the individual is itself ) show +193.6 225.1 moveto +12 f0 +(templatized) show +249.5 225.1 moveto +12 f1 +( w.r.t. the type of fitness) show +372.1 225.1 moveto +12 f0 +( \(double by default\).) show +470 225.1 moveto +12 f0 +( ) show +18.1 215.9 moveto +3.3 3.3 c fill +28 211.8 moveto +12 f0 +(In EO \(actually, in EC!\) ) show +146.6 211.8 moveto +12 f0 +(initialization and variation) show +273.2 211.8 moveto +12 f0 +( operators are ) show +341.5 211.8 moveto +12 f0 +(representation) show +409.4 211.8 moveto +12 f0 +(-dependent,) show +28 198.5 moveto +12 f0 +(while the ) show +75.3 198.5 moveto +12 f0 +(evolution engine) show +155.6 198.5 moveto +12 f0 +( is ) show +169.6 198.5 moveto +12 f0 +(representation) show +237.5 198.5 moveto +12 f0 +(-independent \(well, like any rule, this one does) show +28 185.2 moveto +12 f0 +(have some exceptions\).) show +140.3 185.2 moveto +12 f0 +( ) show +18.1 176 moveto +3.3 3.3 c fill +28 171.9 moveto +12 f0 +(Changing the ) show +95.3 171.9 moveto +12 f0 +(fitness function) show +169.6 171.9 moveto +12 f0 +(, or the ) show +206.2 171.9 moveto +12 f0 +(selection procedure) show +299.8 171.9 moveto +12 f0 +( inside the generational GA evolution) show +28 158.6 moveto +12 f0 +(engine is straightforward.) show +150.9 158.6 moveto +12 f0 +( ) show +18.1 149.4 moveto +3.3 3.3 c fill +28 145.3 moveto +12 f0 +(remember, all ) show +97.6 145.3 moveto +12 f0 +(solutions) show +140.9 145.3 moveto +12 f0 +( to exercises are in the same sub-dir of dir Tutorial than the lesson) show +28 132 moveto +12 f0 +(itself \(see ) show +77.3 132 moveto +12 f0 +(here) show +97.9 132 moveto +12 f0 +(\).) show +104.8 132 moveto +12 f0 +( ) show +0 109.6 moveto +481 0 rlineto 0 -1.4 rlineto -481 0 rlineto closepath fill +0 90.3 moveto +12 f0 +(Lesson 2) show +42.9 90.3 moveto +12 f0 +( - ) show +52.8 90.3 moveto +12 f0 +(Tutorial main page) show +144.1 90.3 moveto +12 f0 +( - ) show +154 90.3 moveto +12 f0 +(Top-Down page) show +232.3 90.3 moveto +12 f0 +( - ) show +242.2 90.3 moveto +12 f0 +(Bottom-up page) show +319.8 90.3 moveto +12 f0 +( - ) show +329.7 90.3 moveto +12 f0 +(Programming hints) show +422 90.3 moveto +12 f0 +( - ) show +431.9 90.3 moveto +14 f0 +(EO) show +pagelevel restore +showpage +%%Page: 5 5 +%%BeginPageSetup +/pagelevel save def +54 0 translate +%%EndPageSetup +newpath 0 72 moveto 481 0 rlineto 0 689 rlineto -481 0 rlineto closepath clip newpath +0 748.4 moveto +14 f0 +(documentation) show +83.2 748.4 moveto +12 f0 +( ) show +0 738.9 moveto +481 0 rlineto 0 -1.4 rlineto -481 0 rlineto closepath fill +0.2 721.6 moveto +12 f2 +(Marc Schoenauer) show +0 695 moveto +12 f0 +(Last modified: Fri Nov 3 18:49:12 CET 2000) show +218.3 695 moveto +12 f0 +( ) show +pagelevel restore +showpage +%%EOF diff --git a/eo/tutorial/html/real_value.html b/eo/tutorial/html/real_value.html new file mode 100644 index 000000000..c45ffd054 --- /dev/null +++ b/eo/tutorial/html/real_value.html @@ -0,0 +1,56 @@ + + + + + + real_value.h + + +Back to Lesson 2 - Tutorial +main page - Top-Down page - Bottom-up +page - Programming hints - +EO documentation +
+
+
+ + + + +
#include <vector> +
//----------------------------------------------------------------------------- +
/** Just a simple function that takes an +vector<double> and sets the fitnes  +
     to the sphere function. +Please use doubles not float!!! +
     @param _ind A floatingpoint +vector  +
*/
+ + + + + +
double real_value(const std::vector<double>& +_ind) +
{ +
 double sum = 0; +
 for (unsigned i = 0; i < _ind.size(); +i++) +
         +sum += _ind[i] * _ind[i]; +
 return -sum; +
}
+ +
Back to Lesson 2 - Tutorial +main page - Top-Down page - Bottom-up +page - Programming hints - EO +documentation +
+
+Marc Schoenauer
+ +
Last modified: Wed Nov +29 08:58:50 2000 + +