- What is EO?- |
-
-
- EO is a templates-based, ANSI-C++ compliant evolutionary computation - library. It contains classes for almost any kind of evolutionary - computation you might come up to - at least for the ones we could think - of. It is component-based, so that if you don't find the class you need - in it, it is very easy to subclass existing abstract or concrete - classes. - -EO was started by the Geneura - Team at the University of Granada, headed by Juan Julián Merelo. The original Web site is also the only place where you - will find old releases of EO (up to 0.8.7), but beware that it is not - compatible at all with the current version. - -The developement team has then been reinforced by Maarten Keijzer, the C++ - wizzard, and Marc Schoenauer. - Later came Jeroen - Eggermont, who, among other things, did a lot of work on GP, - INRIA Dolphin Team, Olivier König, who did a - lot of useful additions and cleaning of the code and Jochen Küpper, working on - infrastructure maintenance. - - |
-
- Platforms- |
-
-
- EO should work on Windows and any Un*x-like operating system with a - standard-conforming C++ development system. - -Recent versions of EO have been tested on the following platforms: - - -
If you have tested EO on a system not listed here, please let - us know. - -If you are working on a system with an older C++ compiler there - is a good chance that eo-0.9.3z.1 works. It is tested on Linux - with gcc-2.9x and several systems (IRIX, Solaris) with egcs. - - |
-
- Documentation- |
-
-
- The tutorial demonstrates that writing an evolutionary algorithm - evolving your own structures is now easy, using ready-to-use - template files. Although the tutorial has not been upgraded for some - time now and refers to version 0.9.2 of EO, it nevertheless remains the - best way to dive into EO. You can start by trying it on-line at LRI - or SourceForge, - before downloading it. The - tutorial is also included in the released - sources. - -The latest tutorial - release - - -The complete code is also well documented and you can look at the - generated interface - documentation. - -The easiest way to create a complete new EO-project, even for new - genomes, is to use the script provided in tutorial/Templates/; see - the README in that directory and lesson 5 of the tutorial for - detail. - - |
-
- Presentations- |
-
-
- A functional and "philosophical" overview of EO was presented at EA'01 conference. - You can download the paper - or the - slides. - -A PowerPoint presentation shows the EO philosophy, and - it includes a Visual Basic macro for evolving objects in Visual Basic - for Applications. - -You can also look a the list of - publications that used EO to solve real problems. - - |
-
- Download- |
-
-
- The current release is EO 1.0. - It supports any Standard-compliant C++ compiler. - -You can obtain the latest version directly via cvs or download a - daily snapshot from LRI. - -All releases can be obtained from the SourceForge download - area. - - |
-
- Mailing Lists- |
- - - We would like EO to be an open development effort; that is why we have - created mailing lists to discuss future developments, solve technical - problems, announce releases, publish patches, and discuss evolutionary - computation in general. Browse the archives or join the EO mailing lists. - - | -
- EO@sourceforge- |
-
-
- The following resources are available, thanks to sourceforge - - |
-
- License- |
- EO is distributed under the - GNU Lesser General - Public License - - | -
- Related Apps- |
-
-
- ParadisEO provides EO extensions for - the flexible design of single solution-based metaheuristics, - metaheuristics for multi objective optimization as well as hybrid, parallel and distributed - metaheuristics. - -DegaX is an ActiveX control which embeds EO 0.8.4. - - - |
-
- Links- |
-
-
-
|
-
Please send comments on this webpage to the EO mailing
-list.
- - | -
-
- J.J. Gilijamse, J. Küpper,
- S. Hoekstra, S.Y.T. van de Meerakker, G. Meijer:
- "Optimizing the Stark-decelerator beamline for the trapping of
- cold molecules using evolutionary strategies",
- Phys. Rev. A |
-
-
-
-
- Please send publications that belong on this page and general comments on
- this webpage to
- the EO
- mailing list.
-
-#include <iostream> -#include <ga/make_ga.h> -#include <apply.h> - - |
-
-
-#include "binary_value.h" - - |
-
-
-using namespace std; -int main(int argc, char* argv[]) -{ - try - { - - |
-
-
-//----------------------------------------------------------------------------- -// define your genotype and fitness types - typedef eoBit<double> EOT; - - |
-
-
- eoParser parser(argc, argv); // for user-parameter reading - - |
-
-
- eoState state; // keeps all things allocated - ///// FIRST, problem or representation dependent stuff - ////////////////////////////////////////////////////// - - |
-
-
- // The evaluation fn - encapsulated into an eval counter for output - eoEvalFuncPtr<EOT, float> mainEval( binary_value<EOT> ); - eoEvalFuncCounter<EOT> eval(mainEval); - - |
-
-
- // the genotype - through a genotype initializer - eoInit<EOT>& init = make_genotype(parser, state, EOT()); - - |
-
-
- // Build the variation operator (any seq/prop construct) - eoGenOp<EOT>& op = make_op(parser, state, init); - - |
-
-
- //// Now the representation-independent things - ////////////////////////////////////////////// - // initialize the population - and evaluate - // yes, this is representation indepedent once you have an eoInit - eoPop<EOT>& pop = make_pop(parser, state, init); - - |
-
-
- // stopping criteria - eoContinue<EOT> & term = make_continue(parser, state, eval); - // output - eoCheckPoint<EOT> & checkpoint = make_checkpoint(parser, state, eval, term); - - |
-
-
- // algorithm (need the operator!) - eoAlgo<EOT>& ga = make_algo_scalar(parser, state, eval, checkpoint, op); - ///// End of construction of the algorith - ///////////////////////////////////////// - - |
-
-
- // to be called AFTER all parameters have been read!!! - make_help(parser); - //// GO - /////// - - |
-
-
- // evaluate intial population AFTER help and status in case it takes time - apply(eval, pop); - - |
-
-
- // print it out (sort witout modifying) - cout << "Initial Population\n"; - pop.sortedPrintOn(cout); - cout << endl; - - |
-
-
- run_ea(ga, pop); // run the ga - - |
-
-
- // print it out (sort witout modifying) - cout << "Final Population\n"; - pop.sortedPrintOn(cout); - cout << endl; - - |
-
-
- } - catch(exception& e) - { - cout << e.what() << endl; - } -} - |
-
-//----------------------------------------------------------------------------- -// 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> - - |
-
-
-#include <ga.h> -//----------------------------------------------------------------------------- -// define your individuals -typedef eoBit<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 eoUniformGenerator class (see utils/eoRndGenerators.h) - eoUniformGenerator<bool> uGen; - eoInitFixedLength<Indi> random(VEC_SIZE, uGen); - // Initialization of the population - eoPop<Indi> pop(POP_SIZE, random); - // and evaluate it in one line - 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 - //////////////////////////////////// - - |
-
-
- // 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 - eo1PtBitXover<Indi> xover1; - // uniform crossover for bitstring - eoUBitXover<Indi> xoverU; - // 2-pots xover - eoNPtsBitXover<Indi> xover2(2); - // Combine them with relative rates - eoPropCombinedQuadOp<Indi> xover(xover1, onePointRate); - xover.add(xoverU, URate); - xover.add(xover2, twoPointsRate, true); - - |
-
- - - | -
-
- ////////////////////////////////////// - // 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; -} - |
-
//-----------------------------------------------------------------------------
- // 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> |
-
#include <ga.h> -//----------------------------------------------------------------------------- - // define your individuals - typedef eoBit<double> Indi; -// A bitstring with fitness double |
-
//-----------------------------------------------------------------------------
- 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 |
-
/////////////////////////////
- // 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
- eoDetTournamentSelect<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 crossover for bitstring
- eo1PtBitXover<Indi> xover; |
-
- // standard bit-flip mutation -for bitstring - eoBitMutation<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,
- |
-
// 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; - } |
-
//-----------------------------------------------------------------------------
- // 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> |
-
#include <es.h> -//----------------------------------------------------------------------------- - // 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 - double -SIGMA = 0.3; // std dev. -for normal mutation - // some parameters for chosing -among different operators - const double hypercubeRate = 0.5; -// relative weight for hypercube Xover - const double segmentRate = 0.5; -// relative weight for segment Xover - const double uniformMutRate = 0.5; -// relative weight for uniform mutation - const double detMutRate = 0.5; -// relative weight for det-uniform mutation - const double normalMutRate = 0.5; -// relative weight for normal 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
- |
-
// sort pop before printing
-it!
- pop.sort(); - // Print (sorted) intial population -(raw printout) - cout << "Initial Population" -<< endl; - cout << pop; |
-
/////////////////////////////////////
- // selection and replacement - //////////////////////////////////// |
-
// 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 - eoHypercubeCrossover<Indi> xoverA; - // Combine them with relative -weights - eoPropCombinedQuadOp<Indi> xover(xoverS, -segmentRate); - xover.add(xoverA, hypercubeRate, -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); - // all coordinates of parents are normally -modified (stDev SIGMA) - eoNormalMutation<Indi> -mutationN(SIGMA); - // Combine them with relative -weights - eoPropCombinedMonOp<Indi> mutation(mutationU, -uniformMutRate); - mutation.add(mutationD, detMutRate); - mutation.add(mutationN, normalMutRate, -true); - // The operators are encapsulated
-into an eoTRansform object
- |
-
- |
//////////////////////////////////////
- // 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; - } |
-
-//----------------------------------------------------------------------------- -// 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> - - |
-
-
-#include <es.h> -//----------------------------------------------------------------------------- -// define your individuals - typedef eoReal<double> Indi; - - |
-
-
-//----------------------------------------------------------------------------- -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 - - |
-
-
- ///////////////////////////// - // 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 - eoDetTournamentSelect<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) - eoSegmentCrossover<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; -} - |
-
#include
-<stdexcept >
- #include <iostream> - #include <strstream> - #include <eo> |
-
-#include
-<stdexcept >
- #include <iostream> - #include <strstream> - #include <eo> |
-
#include <es.h> -typedef eoReal<double> Indi; |
-
-#include <ga.h> -typedef eoBit<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);
- eoSegmentCrossover<Indi> -xover; |
-
-eoBitMutation<Indi>
-mutation(P_MUT_PER_BIT);
- eo1PtBitXover<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 ] - } |
-
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: -
All solutions to exercises are in the same
-sub-dir of the Tutorial directory than the example files (i.e.
-Lesson1 for Lesson1, yes!) and are named exerciseN.p.cpp
-where N is the lesson number and p the exercise number. Hence you may browse
-through the code, eventually modifying it, and then simply type, in the
-corresponding directory,
-
... % make exerciseN.p
-
which will compile file exerciseN.p.cpp
-into executable exerciseN.p
-(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.p.exe).
-
-
/** -*- mode: c++; c-indent-level:
-4; c++-member-init-indent: 8; comment-column: 35; -*-
- The above line is usefulin Emacs-like editors - */ - /* - Template for creating a new representation -in EO - ================================================ - This is the template main file. - It includes all other files that have been -generated by the script create.sh - so it is the only file to compile. - In case you want to build up a separate library -for your new Evolving Object, - you'll need some work - follow what's done -in the src/ga dir, used in the - main file BitEA in tutorial/Lesson4 dir. - Or you can wait until we do it :-) - */ - // Miscilaneous include and declaration - #include <iostream> - using namespace std; - // eo general include - #include "eo" - // the real bounds (not yet in general eo -include) - #include "utils/eoRealVectorBounds.h" - // include here whatever specific files for -your representation - // Basically, this should include at least -the following - /** definition of representation: - * class eoOneMax MUST derive from EO<FitT> -for some fitness - */ |
-
#include "eoOneMax.h"
- /** definition of initilizqtion: - * class eoOneMaxInit MUST derive from eoInit<eoOneMax> - */ |
-
#include "eoOneMaxInit.h"
- /** definition of evaluation: - * class eoOneMaxEvalFunc MUST derive from -eoEvalFunc<eoOneMax> - * and should test for validity before doing -any computation - * see tutorial/Templates/evalFunc.tmpl - */ |
-
#include "eoOneMaxEvalFunc.h"
- // GENOTYPE eoOneMax ***MUST*** -be templatized over the fitness |
-
// START fitness type: double or eoMaximizingFitness
-if you are maximizing
- // -eoMinimizingFitness if you are minimizing - typedef eoMinimizingFitness MyFitT ; // -type of fitness - // END fitness type |
-
- |
// Then define your EO objects using that
-fitness type
- typedef eoOneMax<MyFitT> Indi; -// ***MUST*** derive from EO |
-
// create an initializer
- #include "make_genotype_OneMax.h" - eoInit<Indi> & make_genotype(eoParser& -_parser, eoState&_state, Indi _eo) - { - return do_make_genotype(_parser, -_state, _eo); - } |
-
// and the variation operaotrs
- #include "make_op_OneMax.h" - eoGenOp<Indi>& make_op(eoParser& -_parser, eoState& _state, eoInit<Indi>& _init) - { - return do_make_op(_parser, _state, -_init); - } |
-
// Use existing modules to define representation
-independent routines
- // These are parser-based definitions of -objects - // how to initialize the population - // it IS representation independent if an -eoInit is given - #include <do/make_pop.h> - eoPop<Indi >& make_pop(eoParser& -_parser, eoState& _state, eoInit<Indi> & _init) - { - return do_make_pop(_parser, _state, -_init); - } |
-
// the stopping criterion
- #include <do/make_continue.h> - eoContinue<Indi>& make_continue(eoParser& -_parser, eoState& _state, eoEvalFuncCounter<Indi> & _eval) - { - return do_make_continue(_parser, -_state, _eval); - } |
-
// outputs (stats, population dumps, ...)
- #include <do/make_checkpoint.h> - eoCheckPoint<Indi>& make_checkpoint(eoParser& -_parser, eoState& _state, eoEvalFuncCounter<Indi>& _eval, eoContinue<Indi>& -_continue) - { - return do_make_checkpoint(_parser, -_state, _eval, _continue); - } |
-
// evolution engine (selection and replacement)
- #include <do/make_algo_scalar.h> - eoAlgo<Indi>& make_algo_scalar(eoParser& -_parser, eoState& _state, eoEvalFunc<Indi>& _eval, eoContinue<Indi>& -_continue, eoGenOp<Indi>& _op) - { - return do_make_algo_scalar(_parser, -_state, _eval, _continue, _op); - } |
-
// simple call to the algo. stays there for
-consistency reasons
- // no template for that one - #include <do/make_run.h> - // the instanciating fitnesses - #include <eoScalarFitness.h> - void run_ea(eoAlgo<Indi>& _ga, -eoPop<Indi>& _pop) - { - do_run(_ga, _pop); - } - // checks for help demand, and writes the -status file - // and make_help; in libutils - void make_help(eoParser & _parser); - // now use all of the above, + representation -dependent things - int main(int argc, char* argv[]) - { - try - { - eoParser parser(argc, argv); -// for user-parameter reading - eoState state; -// keeps all things allocated |
-
//
-The fitness
- ////////////// - eoOneMaxEvalFunc<Indi> -plainEval /* (varType _anyVariable) */;; - // turn that object -into an evaluation counter - eoEvalFuncCounter<Indi> -eval(plainEval); |
-
// the genotype - through a
-genotype initializer
- eoInit<Indi>& init = make_genotype(parser, -state, Indi()); |
-
// Build the variation operator
-(any seq/prop construct)
- eoGenOp<Indi>& op = make_op(parser, -state, init); - //// Now the representation-independent -things - // - // YOU SHOULD NOT NEED TO MODIFY -ANYTHING BEYOND THIS POINT - // unless you want to add specific -statistics to the checkpoint - ////////////////////////////////////////////// |
-
// initialize the population
- // yes, this is representation -indepedent once you have an eoInit - eoPop<Indi>& pop -= make_pop(parser, state, init); |
-
// stopping criteria
- eoContinue<Indi> & term = -make_continue(parser, state, eval); |
-
// output
- eoCheckPoint<Indi> & checkpoint -= make_checkpoint(parser, state, eval, term); |
-
// algorithm (need the operator!)
- eoAlgo<Indi>& ga = make_algo_scalar(parser, -state, eval, checkpoint, op); - ///// End of construction of -the algorithm - ///////////////////////////////////////// - // to be called AFTER all parameters -have been read!!! - make_help(parser); - //// GO - /////// |
-
// evaluate intial population
-AFTER help and status in case it takes time
- apply<Indi>(eval, pop); - // if you want to print it -out - // cout << "Initial -Population\n"; - // pop.sortedPrintOn(cout); - // cout << endl; |
-
run_ea(ga, pop); // run the
-ga
- cout << "Final Population\n"; - pop.sortedPrintOn(cout); - cout << endl; - } - catch(exception& e) - { - cout << -e.what() << endl; - } - return 0; - } |
-
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> |
-
// a simple fitness function that computes
-the number of ones of a bitstring
- #include "binary_value.h" |
-
//-----------------------------------------------------------------------------
- // define your genotype and fitness types - typedef eoBit<double> Indi; |
-
// the main_function: nothing changed(!),
-except variable initialization
- void main_function(int argc, char **argv) - { |
-
// 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
- eoDetTournamentSelect<Indi> selectOne(tSize); -// tSize in [2,POPSIZE] - // is now encapsulated in a -eoSelectPerc (entage) - eoSelectPerc<Indi> select(selectOne); - // or eoSelectPerc<Indi> select(selectOne, -rate); - // but by default rate==1 |
-
// And we now have the full
-slection/replacement - though with
- // the same generational replacement -at the moment :-) - eoGenerationalReplacement<Indi> -replace; |
-
//////////////////////////////////////
- // The variation operators - ////////////////////////////////////// |
-
// 1-point crossover for bitstring
- eo1PtBitXover<Indi> xover1; - // uniform crossover for bitstring - eoUBitXover<Indi> xoverU; - // 2-pots xover - eoNPtsBitXover<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
- eoBitMutation<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); |
-
/////////////////////////////////////////
- // the algorithm - //////////////////////////////////////// - // Easy EA requires - // stopping criterion, eval, selection, -transformation, replacement - 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; - } |
-
-//----------------------------------------------------------------------------- -// SecondRealEA.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 -// (also slightly different than in SecondBitEA.cpp) -// and to twidle the output to your preferences (as in SecondBitEA.cpp) -// -//----------------------------------------------------------------------------- -// standard includes -#include <stdexcept> // runtime_error -#include <iostream> // cout -#include <strstream> // ostrstream, istrstream -// the general include for eo -#include <eo> -#include <es.h> - - |
-
-
-//----------------------------------------------------------------------------- -// define your individuals -typedef eoReal<eoMinimizingFitness> 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) -{ - - |
-
-
- ///////////////////////////// - // 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>& > plainEval( real_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 (loadName != "") - { - inState.load(loadName); // 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) - eoUniformGenerator<double> uGen(-1.0, 1.0); - eoInitFixedLength<Indi> random(vecSize, uGen); - // 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 before printing it! - pop.sort(); - // Print (sorted) intial population (raw printout) - cout << "Initial Population" << endl; - cout << pop; - - |
-
-
- ///////////////////////////////////// - // selection and replacement - //////////////////////////////////// - - |
-
-
- // The robust tournament selection - eoDetTournamentSelect<Indi> selectOne(tSize); - // 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 :-) - eoGenerationalReplacement<Indi> replace; - - |
-
-
- ////////////////////////////////////// - // The variation operators - ////////////////////////////////////// - - |
-
-
- // uniform chooce on segment made by the parents - eoSegmentCrossover<Indi> xoverS; - // uniform choice in hypercube built by the parents - eoHypercubeCrossover<Indi> xoverA; - // Combine them with relative weights - eoPropCombinedQuadOp<Indi> xover(xoverS, segmentRate); - xover.add(xoverA, hypercubeRate, 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); - // all coordinates of parents are normally modified (stDev SIGMA) - eoNormalMutation<Indi> mutationN(SIGMA); - // Combine them with relative weights - eoPropCombinedMonOp<Indi> mutation(mutationU, uniformMutRate); - mutation.add(mutationD, detMutRate); - mutation.add(mutationN, normalMutRate, 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(0); - 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(parser); - outState.registerObject(pop); - outState.registerObject(rng); - // and feed the state to state savers - // save state every 100th generation - eoCountedStateSaver stateSaver1(20, 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 - // stopping criterion, eval, selection, transformation, replacement - eoEasyEA<Indi> gga(checkpoint, 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) -{ - try - { - main_function(argc, argv); - } - catch(exception& e) - { - cout << "Exception: " << e.what() << '\n'; - } - return 1; -} - |
-
#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; - } |
-
diff --git a/eo/tutorial/html/eoBottomUp.html b/eo/tutorial/html/eoBottomUp.html deleted file mode 100644 index b35d40262..000000000 --- a/eo/tutorial/html/eoBottomUp.html +++ /dev/null @@ -1,77 +0,0 @@ - - -
- - -
Congratulations - You have chosen the component-based 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.
-
-
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.
-
-
-
-
EO classes described in this page: -
-
Continuators are functors that compute stopping critera. They receive -a population and return a boolean value which is set to false only when -some stopping vriterion is met. All algorithms in EO have a loop that goes -do{...}while(continuator(pop)which -means that the algorithm stops only when the continuator returns false. -
Interface: The abstract class -for computing stopping conditions is eoContinue, -and the interface for its operator() is -
- -bool operator()(const eoPop<EOT>& -) -
which you could have guessed from the inheritance -diagram for class eoContinue, as -you see there that eoContinue derives -from class eoUF<const eoPop<EOT>&, -bool>. -
Using a continuator:
-
You can find an first example of using a continuator in the code for
-FirstBitEA
-ior more sophisticated continue conditions in Lesson2.
-
If you want to find out how it is used inside an algorithm, go and
-see for instance in eoSGA, the simplest EA within EO.
-
Writing a
-continuator:
-
There are only two things to modify in the template
-class definitions provided (apart from the name of the class you are
-creating!)
-
-
-
Interface: -
Using a checkpoint: An eoCheckPoint -being an eoContinue, its usage is exactly the same. However, an eoCheckPoint -will actually do many more things than an eoContinue before returning its -boolean result as an eoContinue. -
Writing a
-checkpoint:
-
This is something you should never have to do. However, should you
-feel you have to do it, please do - and send us both the reasons that lead
-you to that (what is it you couldn't do with existing eoCheckPoint), and
-the resulting code, of course.
-
-
Interface: -
Using statistics: -
Interface: -
Using monitors: -
-
Interface: -
Using updaters: -
-
The term evolution engine denotes -the different parts of an Evolutionary Algorithm that simulate the Darwinism: -
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.
-
Both selection and replacement will be discussed in turn, before some -helper classes that are used within selection and replacement procedures -are presented. -
-
The very beginning of the generation loop is the selection phase, where
-some individuals from the population are chosen to become the parents,
-to be later modified by the variation operators and become the offspring.
-This is the first step of the artificial Darwinism,
-where the fittest individuals are allowed to reproduce.
-
Conceptually, there are two distinct ways to choose the lucky ones:
-one by one from the very same population (i.e. with replacement), which
-means that at the extreme the same individual can be chosen every time;
-or as a whole, in some sort of batch procedure. Of course, repeated selection
-of one individual results in a batch selection!
-
There are hence two basic EO classes for selection: eoSelectOne
-and eoSelect, with different interfaces.
-
-
The abstract class for selection of a single individual from a population -is eoSelectOne, and the interface for its -operator() -is -
const EOT & operator()(const eoPop<EOT>& -_parents)
which you could have guessed from the inheritance tree for class eoSelectOne.,
-as you see there that eoSelectOne derives
-from class eoUF<const eoPop<EOT>&,
-const EOT&>.
-
This means that it takes 1 population
-(without the right to modify it - see the const
-keyword in argument) and returns a const reference to an individual (again,
-the const keyword ensures
-that nothing will happen to the individual in the population - remember
-it returns a reference).
-
-
The abstract class for batch selection of a whole set of individuals -from a population is eoSelect, and the interface -for its -operator() is -
void operator()(const eoPop<EOT>& -_source, eoPop<EOT>& _dest)
which you could have guessed from the inheritance tree for class eoSelect.,
-as you see there that eoSelect derives from
-class
-eoBF<const eoPop<EOT>&, eoPop<EOT>&, void>.
-
This means that it takes 2 populations,
-and fills the second one with individuals from the first one without modifying
-it (see the const keyword).
-This raises two questions:
-
There are two ways an can derive the number of individuals it -has to select: either it is a fixed number, or it is some percentage of -the source population size (any positive real number). In both case, this -must be passed to the constructor. In most instances, however, the constructor -will accept a real number (double) and a boolean indicating whether this -real number should be used as an absolute integer or as a rate, thanks -to the eoHowMany class. -
Note: an eoSelect -can select more individuals than there are in the original population. -It is the job of the replacement to ensure -that the population size does not grow along the generations. -
-
It is clear that repeated selection of a single individual is a way -to do batch selection. This is why it is possible to encapsulate an object -of class eoSelectOne into an object of class -eoSelect -using the class eoSelectMany. Class eoSelectMany -is derived from class eoSelect and takes in -its constructor an eoSelectOne (plus the number -of individuals it should select, according to the eoHowMany -paradigm). -
Note: some procedures for selecting
-a single individual require some pre-processing of the whole population
-that takes place before any selection, and will be repeated identically
-for every individual. The encapsulation of an into an allows
-to call such technical processing only once through the use of method setup
-of class . This method does nothing by default, but is mandatory
-
-
The replacement phase takes place after the birth
-of all offspring through variation operators. This is the second
-step of the artificial Darwinism, where the
-fittest
-individuals are allowed to survive.
-
It can also be viewed on the algorithmic side as closing the generation
-loop, i.e. building the population that will be the initial population
-of next generation. That population will be built
-upon the old parents and the new-born offspring. In all algorithms
-that come up with EO, the population size
-is supposed to be constant from one generation
-to the next one - though nothing stops you from writing an algorithm with
-varying population size.
-
-
The abstract class for replacement procedures is the functor class -eoReplacement, -and the interface for its operator() -is -
void operator()(eoPop<EOT>& _parents, -eoPop<EOT>& _offspring)
which you could have guessed from the inheritance tree for class eoReplacement.,
-as you see there that eoReplacement derives
-from class eoBF<eoPop<EOT>&, eoPop<EOT>&,
-void>.
-
This means that it takes 2 populations
-(called, for obvious anthropomorphic reasons, _parents and _offspring :-)
-and is free to modify both, but the resulting population should be placed
-in the first argument (usually called_parents) to close the loop and go
-to next generation.
-
-
-
-
-
Available instances of eoMergeReduce replacement -include -
-
-
-
Note: The basic use (and initial -motivation) for eoSurviveAndDie -takes 2 arguments, an eoMergeReduce and a number of surviving parents. -It starts by copying the best parents to the new populations, then merges -the remaining parents with the offspring before reducing to the number -of remaining seats in the new population.
You can add what is called weak elitism -to any replacement by encapsulating it into an eoWeakElitismReplacement -object. Weak elitism ensures that the overall best -fitness in the population will never decrease: -if the best fitness in the new population is less than the best fitness -of the parent population, then the best parent is added back to the new -population, replacing the worse. -
Within EO, this is very easy to add: -
First, declare your replacement functor (here, generational, but it
-can be any replacement object):
-
eoGenerationalReplacement<Indi> genReplace;
-
Then wrap the weak elitism around it:
-
eoWeakElitismReplacement<Indi> replace(genReplace);
-
and use now replace as your replacement procedure within your algorithm.
-
Note: of course, adding weak elitism to
-an elitist replacement makes no sense - but will not harm either :-)
-
-
The file t-eoReplacement -in the test directory implements all -above replacement procedures within a very simple and easy-to-monitor Dummy -EO class. -
-
In an attempt to unify all the well-known replacements, plus most of
-the less-known-though-often-used, the eoReduceMergeReduce
-replacement has been designed, and supersedes all of the above instances.
-
It allows to implement strong elistism
-(i.e. some parents survive, whatever their fitness and that of the offspring),
-as well as multiple weak elistism (the best parents are put back in the
-next population if they outperform the best offspring).
-
Basically, an eoReduceMergeReduce
-starts by eventually preserving the (strong) elite parents, proceeds by
-reducing both the parent and offspring populations, merges those populations,
-and eventually reduces the resulting populations (augmented with the elite
-parents) to the right size. Last, the weak elitism is taken care of if
-necessary.
-
The following image, taken from the graphical interface of EASEA, somehow
-demonstrates the different parameters of an eoReduceMergeReduce.
-
-
The constructor takes 6 arguments: -
The most popular evolution engines are listed below, together with the -way to use them in EO. If you don't find your particuler algorithm, please -send it to us, and we might include it here! In the following, P will denote -the number of individuals in the initial population. -
Tournaments are an easy and quick way to select
-individuals within a population based on simple comparisons. Though usually
-based on fitness comparisons, they can use any comparison operator.
-
In EO, there are two variants of tournaments used to select one single
-individual, namely Deterministic Tournament
-and Stochastic Tournament,
-that are used in selection and in replacement procedures, and a global
-tournament-based selection of a whole bunch of individuals, the EP
-Tournament. Though the single-selection tournaments can
-be repeated to select more than one individual, and the batch tournament
-selection can be used to select a single individual, both uses are probably
-a waste of CPU time.
-
-
In replacement procedures, one frequently needs to merge two populations
-(computed form old parents and new-born offspring). Classes derived from
-the abstract class eoMerge are written for that purpose.
-
-
void operator()(const eoPop<EOT>& -_parents, eoPop<EOT>& _offspring)
which you could have guessed from the inheritance tree for class eoMerge,
-as you see there that eoMerge derives from
-
class eoBF<const eoPop<EOT>&, eoPop<EOT>&,
-void>.
-
This means that it takes 2 populations
-and modifies the seond one by adding some individuals from the first one
-(which is supposed to remain constant).
-
-
-
The other useful component of replacement procedures, eoReduce,
-kills
-some individuals from a given population.
-
-
void operator()(eoPop<EOT>& _parents, -unsigned int new_size)
which you could have guessed from the inheritance tree for class eoReduce,
-as you see there that eoReduce derives from
-
class eoBF<eoPop<EOT>&, unsigned
-int, void>.
-
An eoReduce shoud take a
-population and shrink it to the required size.
-
-
Many classes in selection/replacement procedures will handle a number
-of individuals that may either be fixed or be related to some argument-population
-size.
-
Of course, it is possible to write different classes that will only
-differ by the way they compute the number of individuals they have to treat,
-as it is done for selectors with the two classes eoSelectPerc
-and eoSelectNumber (it could also have been
-possible to have some pure abstrat class and implement the computation
-of the number of individuals to treat in some derived classes).
-
However, the class eoHowMany
-allows one to handle in a single class three different behaviors when given
-a poopulatio size as argument:
-
unsigned int operator()(unsigned int _pop_size)
which you could have guessed from the inheritance tree for class eoHowMany,
-as you see there that eoHowMany
-derives from
-
class eoUF<unsigned int, unsigned int>.
-
It has 3 possible constructors, that determine its behavior: -
-
eoSurviveAndDie: interface
-
The class interface for its operator()
-is
-
void operator()(eoPop<EOT>& _source, -eoPop<EOT>& _dest)
which you could have guessed from the inheritance tree for class eoSurviveAndDie, -as you see there that eoSurviveAndDie -derives from class eoBF<eoPop<EOT>&, -eoPop<EOT>&, void>. -
Its constructor takes 3 argumenrts: -
eoHowMany(double _survive, double _die, -bool _interpret_as_rate = true)
to indicate how many (or what proportion, according to _interpret_as_rate) -of the source should be copied to the dest population, and how many (or -what proportion, according to _interpret_as_rate) -should be erased from the source. -
-
-
-
-
-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
deleted file mode 100644
index f88921015..000000000
--- a/eo/tutorial/html/eoLesson1.html
+++ /dev/null
@@ -1,440 +0,0 @@
-
-
-
-
-
-
-
-
-Tutorial: Lesson 1
-
-Later you will be asked to
-
-
-
-
-
-
-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.
-
I want to run
-an Evolutionary Algorithm
-now
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. -
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.
-
-
Now you need to take a look at the program codes, either by browsing -alone through the sources for FirstBitGA -and FirstRealGA, or by following the guided -tour below. You might prefer to go directly to the exercises. -
-
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). -
Browse through the code, and discover them one after the other: -
-
Note: Also,
-a non-templatized fitness can be compiled
-separately (not done here) into an object
-file once and for all (remember
-that templates forbid that).
-
-
-
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).
-
-
-
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!!!
-
-
Note: The
-operators have to be encapsulated into an eoTransform
-object (Bit - Real)
-to be passed to the eoEasyEA algorithm.
-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 probability, 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.
-
-
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.
Exercise
-3: full selection/replacement
-
You can now twiddle 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.
-
-
You can then either -
-
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 ....
-
Note that an eoState alos has another use in EO whan it comes to memory
-management: it can be a repository of pointers that are not allocated within
-obects - allowing to delete them by simply deleting the eoState (see Lesson
-4).
-
-
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.
-
-
Statistics: Available
-instances
-
Some widely used statistics are already available (and of course you
-can build you own!).
-
Note: actually, there are 2 distinct
-classes that compute and give access to statistics: eoStatand
-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 objects
-work on a temporary vector of fitnesses . But as
-far as their usage is concerned, its makes no difference.
-
-
Monitors: Available
-instances
-
A few monitors are available in the EO distribution:
-
Monitors: Adding
-to the checkpoint
-
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.
-
-
Updater: Available -instances: A few updaters are available in the EO distribution: -
-
As already said, the behavior of the algorithms
-will be exactly the same as the previous one as far as optimization is
-concerned. Only now you will be able to tune every component of the algorithms
-(except the type of genotype) using run-time parameters.
-
Also, as in previous lessons, most of the code
-is representation-independent, i.e. is the same for both the binary genotypes
-and the real-valued genotypes. This small user's guide reflects that, but
-you can go directly to the binary or the real
-parts if you wish.
-
Warning: this -is a user guide, not a programming guide. In particular, the keywords -of the parameters are not -the names of -the underlying classes (though they should be similar in most cases). -
User's guide:Parameter -input The way to input parameters -has already be described in Lesson -3. To get a list of parameters, type the command with option --help -(or -h): with both testBit and testReal this will result in -
User's guide:Representation-independent
-parameters
-
In what follows, the fixed font colored text
-is directly taken from the status file and is commented between the lines.
-The presentation follows the status file format - only two sections are
-representation-dependent (see the corresponding binary
-or real sections). All other sections are presented
-now:
-
-
# --seed=988700289 # -S :
-Random number seed
-
Unsigned long parameter:
-the seed for the Random Number Generator
-If the parameter is absent, then time(0) is used, which indicates the number
-of seconds since Jan. 1 1980, is used ... and stored in the status file,
-of course, so you can repeat the same run by simply assigning that value
-again. There is no default value ("true" random
-seed).
-
-
Section ######
-engine ######
-
In this section, one chooses all components of
-the Evolution Engine (selection, replacemenet
-and the like).
-
# --popSize=20 # -P : Population
-Size
-
Integer parameter:
-the size of the population (constant along evolution). And yes, this is
-a representation independent parameter, as the population is created either
-from a file or using an eoInit object - and only that object is representation-dependent.
-
# --selection=DetTour(2)
-# -S : Selection: Roulette, DetTour(T), StochTour(t) or Sequential(ordered/unordered)
-
String parameter:
-Name of selection procedure. Availabable
-are the roulette wheel
-(name Roulette,
-fitness scaling coming soon); deterministic
-tournament (name DetTour
-with size - integer > 2 - in parentheses right after the name, use double
-quotes on the command line); stochastic
-tournament (name StochTour
-with probability - float in [0.5, 1] - in parentheses); sequential
-(name
-Sequential,
-all individuals in turn), either from best to worst (option ordered
-in parentheses), or in random ordered (option unordered);
-and finally repeated independent uniform
-choices (name Random).
-Default is DetTour(2).
-
# --nbOffspring=100% # -O
-: Nb of offspring (percentage or absolute)
-
Integer or real-valued parameter:
-this parameter indicates the amount of
-offspring that will be generated from
-the genitors every generation. However, this amount can be specified either
-relative
-to the population size, and it should then end with percent character (%),
-or as an absolute
-integer number (without the percent char).
-
Indeed, you can either want, say 7 times more
-offspring than parents (a rather common situation in Evolution Strategies),
-in which case you give value 700% to nbOffspring
-parameter; or you might want a single offspring whatever the population
-size, like in Steady-State evolution engines, in which case you simply
-enter value 1. Default is 100%.
-
# --replacement=Comma # -R
-: Replacement: Comma, Plus, EPTour(T), SSGAWorst, SSGADet(T), SSGAStoch(t)
-
String parameter:
-Name of replacement procedure. Availabable are the ES
-plus and comma deterministic replacement
-strategies (named respectively Plus
-and Comma);
-EP
-stochastic tournament (name EPTour
-with tournament size in parentheses); and the steady-state
-replacement
-procedures, at the moment only based on fitnesses, replacement being either
-deterministic
-(new born replace worst parent, name SSGAWorst),
-or based on a tournament (name SSGADet
-for deterministic tournament, size in parentheses, and SSGAStoch
-for stochastic tournament, probability in parentheses). Default
-is Comma (which btw is also SGA generational
-replacement whenever there are as many offspring
-as parents).
-
# --weakElitism=0 # -w :
-Old best parent replaces new worst offspring *if necessary*
-
Boolean parameter:
-if true, weak elitism is added to the replacement procedure (i.e. if the
-best fitness among the offspring is less than the best fitness, the best
-parent replaces the worst offspring). Default
-is false.
-
-
Section ######
-Output ######
-
This first section on Output contains parameters
-related to screen text output.
-
# --useEval=1 # Use nb of
-eval. as counter (vs nb of gen.)
-
Boolean parameter:
-whether or not you want the nb of evluations to be displayed and used as
-counter in statistics outputs and plots. Default
-is true.
-
# --printBestStat=1 # Print
-Best/avg/stdev every gen.
-
Boolean parameter:
-toggles screen output of indicated statistics. Default
-is true.
-
# --printPop=0 # Print sorted
-pop. every gen.
-
Boolean parameter:
-adds a dump of the whole population to the screen every generation. Is
-likely to generate huge
-output! Default is false.
-
# --printFDC=1 # Print FDC
-coeff. every gen.
-
Boolean parameter:
-adds Fitness Distance Correlation to output every generation. Default
-is false.
-
-
Section ######
-Output - Disk ######
-
This second section on Output contains parameters
-related to DISK output.
-
# --resDir=Res # Directory
-to store DISK outputs
-
String parameter: All
-DISK
-output will be stored in a separate directory
--this is its name. If the directory does not exist, it is created. Note
-that all graphical displays
-will use that directory for their temporary files. Also all
-job dump (see section Persistence
-below) store their files there too.
-
# --eraseDir=0 # erase files
-in dirName if any
-
Boolean parameter:
-in order not to mix up files from different runs, it is mandatory to ensure
-that the directory where all files will be stored is empty. However, if
-this parameter is not set and the directory already exists, an exception
-is thrown and the program stops. It it is set, all
-files in the result directory are erased.
-
# --fileBestStat=0 # Output
-Best/avg/stdev to a file
-
Boolean parameter:
-if present, the best, average and standard deviation statistics are stored
-in file resDir/best.xg.
-Each line contains the generation number, eventualy the evaluation count
-(depending on parameter useEval
-then the statistics. Default is false.
-
-
-
Section ######
-Output - Graphical ######
-
This last section on Output contains parameters
-related to graphical output (only available in Unix through gnuplot at
-the moment).
-
# --plotBestStat=0 # Plot
-Best/avg Stat
-
Boolean parameter:
-toggles gnuplot output of best and average plots (Linux only at the moment).
-Default
-is false.
-
# --plotFDCStat=0 # Plot
-FDC scatter plot
-
Boolean parameter:
-toggles the Fitness Distance Correlation plot (Fitness vs distance to best).
-Default
-is false.
-
# --plotHisto=0 # Plot histogram
-of fitnesses
-
Boolean parameter:
-if on, gnuplot is used to plot the sorted population (fitness vs rank).
-Gives a graphical idea of the diversity. Default
-is false.
-
-
Section ######
-Persistence ######
-
This section contains parameters handling job
-dump and restart mechanism.
-
# --Load= # -L : A save file
-to restart from
-
String parameter:
-if present, the initial population (and the RNG) is read from indicated
-file. That file must
-come from a previous save (or must be in same format!), i.e. must contain
-a popualtion, the RNG and all parameters. If no other parameter is modified,
-using a previously saved population and RNG will give exactly the same
-results than having run that previous run longer. And a way to be sure
-to re-use the same parameters is to ... use that very save file as parameter
-file, as it contains all actual parameters in the right format.
-
Note that if not enough individuals are read,
-the remaining are randomly initialized. No
-default value.
-
# --recomputeFitness=0 #
--r : Recompute the fitness after re-loading the pop.?
-
Boolean parameter:
-in case some individuals are read from a file, their fitness is read too.
-If this one is true, it is nevertheless recomputed. Default
-is false i.e. use fitnes that's in the file.
-
# --saveFrequency=0 # Save
-every F generation (0 = only final state, absent = never)
-
Integer parameter:
-interval between two dump to disk of the whole population (+RNG + parameters),
-in a file named genNN.sav in the dirRes
-directory, where NN is the generation number. If this prameter is present
-(even with 0 or negative value), the final population will always be saved,
-whatever the reason for stopping. Hence the only way to avoid all saves
-is to omit the parameter (there is no default
-value).
-
# --saveTimeInterval=0 #
-Save every T seconds (0 or absent = never)
-
Integer parameter:
-time interval between two population (+RNG + parameters) dumps to disks.
-Files are names timeNN.sav. See pervious parameter description for ore
-details. No default value.
-
# --status=t-eoGA.status
-# Status file
-
String parameter:
-name of the status file (that contains all parameters in the input format).
-There is no way to avoid creating that file except recompiling ... or giving
-the name /dev/null (Unix). Default value is ProgramName.status
-
-
Section ######
-Stopping criterion ######
-
This section allows to decide when the algorithm
-will stop.
-
# --maxGen=100 # -G : Maximum
-number of generations (0 = none)
-
Integer parameter: maximum number of generations.
-A value of 0 disables that stopping criterion. Default
-is 100.
-
# --steadyGen=100 # -s :
-Number of generations with no improvement
-
Integer parameter:
-stops whenever that number of generations is passed without any improvement
-of the best fitness in the population, provided the following minimum number
-of generations has been done. No default value.
-
# --minGen=0 # -g : Minimum
-number of generations
-
Integer parameter: the above steadyGen parameter
-starts its job only after that minimum nuber of generations is passed.
-No
-default value.
-
# --maxEval=0 # -E : Maximum
-number of evaluations (0 = none)
-
Integer parameter:
-maximum number of generations.
-No default
-value.
-
# --targetFitness=0 # -T
-: Stop when fitness reaches
-
Real-valued parameter:
-the algorithm stops whenever the best fitness reaches that target. No
-default value.
-
# --CtrlC=0 # -C : Terminate
-current generation upon Ctrl C
-
Boolean parameter:
-if true, Ctrl C only stops after the current generation as completed (eventually
-dumping population to a file if some saver is active). This very useful
-feature is only available in Unix at the moment. Default
-is false.
-
-
User's guide:Bistring
-specific parameters
-
The following describes the specific parameters that are available
-in program BitEA to evolve genotypes that are bitstrings.
-
The two representation-dependent sections are concerned repectively
-with genotype initilization and variation operators.
-
-
Section ######
-Genotype Initialization ######
-
This section should allow input if all necessary
-parameters for genitype initialization
-
# --ChromSize=10 # -n : The
-length of the bitstrings
-
Integer parameter:
-The bitstring initilization only requires the length of the chromosome.
-
-
Section ######
-Variation Operators ######
-
This section allows to tune the way the variation
-operators will be applied to the individuals (in the strict limit of SGA
-model at the moment, see below).
-
# --operator=SGA # -o : Description
-of the operator (SGA only now)
-
String parameter:
-Describes the way the operators are applied. At the moment, only
-SGA is available. SGA sequentially
-applies a (quadratic) crossover operator with probability pCross
-and a mutation operator with probability pMut.
-Both these operators can in turn be proportional
-combinations of simple operators of the
-same arity.
-
# --pCross=0.6 # -C : Probability
-of Crossover
-
Floating-point parameter:
-The probability that a given couple of selected genitors is applied the
-crossover operator. In SGA operator model, each couple of selected genitors
-is applied the crossover operator with that probability (and remains unchanged
-with probability 1-pCross.
-Whenever a couple undergoes crossover, a choice is made upon available
-crossover operators proportionaly to their
-relative rates (see below). Default
-is 0.6.
-
# --pMut=0.1 # -M : Probability
-of Mutation
-
Floating-point parameter:
-The probability that a given individual (resulting from a crossover or
-a non-crossover operation, see above) is applied the mutation operator.
-Whenever an individual undergoes mutation, a choice is made upon available
-mutation operators proportionaly to their
-relative rates (see below). Default
-is 0.1.
-
# --onePointRate=1 # -1 :
-Relative rate for one point crossover
-
Floating-point parameter:
-Rate of aplication of the 1-point crossover relatively
-to 2-point and uniform below (see pCross
-parameter). Default is 1.
-
# --twoPointRate=1 # -2 :
-Relative rate for two point crossover
-
Floating-point parameter:
-Rate of aplication of the 2-point crossover relatively
-to 1-point above and uniform below (see pCross
-parameter). Default is 1.
-
# --uRate=2 # -U : Relative
-rate for uniform crossover
-
Floating-point parameter:
-Rate of aplication of the 1-point crossover relatively
-to 1- and 2-point above (see pCross
-parameter). Default is 2.
-
# --pMutPerBit=0.01 # -b
-: Probability of flipping 1 bit in bit-flip mutation
-
Floating-point parameter:
-When bit-flip mutation
-is applied, each bit is flipped independently with probability pMutPerBit.
-
# --bitFlipRate=0.01 # -s
-: Relative rate for bit-flip mutation
-
Floating-point parameter:
-Rate of aplication of the bit-flip mutation relatively
-to one-Bit mutation below (see pMut
-above). Default is 0.01
-(if all relative rates are equal, the choice is uniform among available
-operators).
-
# --oneBitRate=0.01 # -d
-: Relative rate for deterministic bit-flip mutation
-
Floating-point parameter:
-Rate of aplication of the one-bit mutation relatively
-to bit-flip mutation below (see pMut
-above). One-bit mutation flips one and only one bit, uniformly chosen in
-the individual. Default is 0.01
-(if all relative rates are equal, the choice is uniform among available
-operators).
-
-
-
User's guide:Real-valued
-specific parameters
-
-To run your own real-valued application, write your fitness function
-(see real_value.h),
-recompile, and run from the command line
-
-
Section ######
-Genotype Initialization ######
-
This section should allow input if all necessary
-parameters for genitype initialization
-
# --vecSize=10 # -n : The
-number of variables
-
Integer parameter:
-The initilization requires the length of the vector<double>.
-
# --initBounds=10[-1,1] #
--B : Bounds for uniform initialization
-
Bounds parameter:
-Bounds for uniform initialization of the real variables. The syntax for
-this parameter given in the objectBounds
-parameter description below. This argument is mandatory, furthermore the
-given bounds must be bounded.
-The
-default is [-1,1] for all variables.
-
Note that this parameter is independent of the objectBounds
-parameter below.
-
# --sigmaInit=0.3 # -s :
-Initial value for Sigma(s)
-
Floating-point parameter:
-The initial value for all standard-deviation mutation strategy parameters.
-Useless when no self-adaptive mutation mechanism is used.
-
-
Section ######
-Variation Operators ######
-
This section allows to tune the way the variation
-operators will be applied to the individuals (in the strict limit of SGA
-model at the moment, see below).
-
# --objectBounds=10[-inf,+inf]
-# -B : Bounds for variables
-
Bounds parameter:
-Bounds for object variables. The syntax for this parameter is a succession
-of (optionally semi-colon separated) items of the form N[min,Max]where
-the optional integer N
-indicates how many variables have the given bounds. min
-and Max
-are either floating point numbers, or -inf
-(resp. +inf)
-to indicate unbounded direction. If not enough bounds are provided, the
-remaining variables will have the same bounds as the last bounds given.
-
This argument is mandatory, and
-default
-is [-inf,+inf], i.e. unbounded variables.
-
Examples:
-10[-1,1]is
-equivalent to simply [-1,1]
-or to the extended [-1,1][-1,1][-1,1][-1,1][-1,1][-1,1][-1,1][-1,1][-1,1][-1,1].
-
And [-1,1];2[0,1];[-inf,10]results
-in the first variable staying in [-1,1], the second and the third in [0,1]
-and all remaining variables below 10.
-
# --operator=SGA # -o : Description
-of the operator (SGA only now)
-
String parameter:
-Describes the way the operators are applied. At the moment, only
-SGA is available. SGA sequentially
-applies a (quadratic) crossover operator with probability pCross
-and a mutation operator with probability pMut.
-Both these operators can in turn be proportional
-combinations of simple operators of the
-same arity.
-
# --pCross=0.6 # -C : Probability
-of Crossover
-
Floating-point parameter:
-The probability that a given couple of selected genitors is applied the
-crossover operator. In SGA operator model, each couple of selected genitors
-is applied the crossover operator with that probability (and remains unchanged
-with probability 1-pCross.
-Whenever a couple undergoes crossover, a choice is made upon available
-crossover operators proportionaly to their
-relative rates (see below). Default
-is 0.6.
-
# --pMut=0.1 # -M : Probability
-of Mutation
-
Floating-point parameter:
-The probability that a given individual (resulting from a crossover or
-a non-crossover operation, see above) is applied the mutation operator.
-Whenever an individual undergoes mutation, a choice is made upon available
-mutation operators proportionaly to their
-relative rates (see below). Default
-is 0.1.
-
# --alpha=0 # -a : bound
-for combination factor in real crossover
-
Floating-point parameter:
-Bound for the choices of linear combination factors in both crossover belows
-(similar to BLX-alpha notation). Default is
-0 (i.e. combination factor are chosen in [0,1]).
-
# --segmentRate=1 # -s :
-Relative rate for segment crossover
-
Floating-point parameter:
-Rate of application of the segment crossover relatively
-to hypercube and uniform crossovers (see pCross
-parameter). Segment crossover generates offspring uniformly on the segment
-joining both parents, i.e. constructs two linear combinations of the parents
-with a random number uniformly drawn in [alpha,1+alpha].
-Default
-is 1.
-
# --hypercubeRate=1 # -A
-: Relative rate for hypercube crossover
-
Floating-point parameter:
-Rate of application of the hypercube crossover relatively
-to segment and uniform crossovers (see pCross
-parameter). Hypercube crossover generates offspring uniformly on the hypercube
-whose diagonal is the segment joining both parents, i.e. by doing linear
-combinations of each variable independently (a random number in [alpha,1+alpha]
-is drawn anew for each variable). Default
-is 1.
-
# --uxoverRate=1 # -A : Relative
-rate for uniform crossover
-
Floating-point parameter:
-Rate of application of the segment crossover relatively
-to hypercube and segment crossovers (see pCross
-parameter). Uniform crossover simply exchanges values of variables, i.e.
-uniformly picks up two other summits of the hypercube defined by the parents.
-Default
-is 1.
-
# --epsilon=0.01 # -e : Half-size
-of interval for Uniform Mutation
-
Floating-point parameter:
-The uniform and deterministic-uniform mutations will choose values of variable
-X uniformly in [X-epsilon,
-X+epsilon].
-Default
-is 0.01.
-
# --uniformMutRate=1 # -u
-: Relative rate for uniform mutation
-
Floating-point parameter:
-Rate of aplication of the uniform mutation relatively
-to determinitic uniform and the normal mutations (see pMut
-above). Uniform mutation modifies all variables by choosing new values
-uniformly on an interval centered on the old value of width 2*epsilon
-(see above). Default is1.
-
# --detMutRate=1 # -d : Relative
-rate for deterministic uniform mutation
-
Floating-point parameter:
-Rate of aplication of the determinisitc-uniform mutation relatively
-to uniform and normal mutations (see pMut
-above). Deterministic-uniform mutation modifies one single variable uniformly
-based on epsilon epsilon.
-Default
-is1.
-
# --normalMutRate=1 # -d
-: Relative rate for Gaussian mutation
-
Floating-point parameter:
-Rate of aplication of the normal mutation relatively
-to two uniform mutations above (see pMut
-above). Default is1.
-
# --sigma=0.3 # -s : Sigma
-(fixed) for Gaussian mutation
-
Floating-point parameter:
-The value of standard deviation for Gaussian mutation - fixed along evolution
-(see the Evolution Strategy program below for self-adaptive mutations).
-
-
User's guide:ES
-with self-adative mutation parameters
-
-To run your own SA-ES application, write your fitness function
-(see real_value.h),
-recompile, and run from the command line
-
-
Section ######
-ES mutation ######
-
This section allows to decide which type of self-adaptive
-mutation will be used. There are three available types: isotropic mutation,
-using one standard deviation for each individual, that will be applied
-to all variables; anisotropic mutation, where each individual carries as
-many standard deviations as it has variables; and correlated mutation where
-each individuals has its own full correlation matrix.
-
# --Isotropic=1 # -i : Isotropic
-self-adaptive mutation
-
Boolean parameter:
-If true, at least one self-adaptive parameter will be used for each individual.
-Default
-is true.
-
# --Stdev=0 # -s : One self-adaptive
-stDev per variable
-
Boolean parameter:
-If true, at least one self-adaptive parameter per variable will be used
-for each individual. Default is false.
-
# --Correl=0 # -c : Use correlated
-mutations
-
Boolean parameter:
-If true, full correalted self-adaptive mutation will be used for each individual.
-Default
-is false.
-
Note: The -default values result in an isotropic self-adaptive mutation to be chosen. -
-
Section ######
-Variation Operators ######
-
Only the parameters that are specific to ESEA
-are presented here - the objectBounds,operator,pCross
-and pMut
-are exactly the same as for RealEA
-above.
-
# --crossType=global # -C
-: Type of ES recombination (global or standard)
-
String parameter:
-Es crossover can involve only two parents - and it is then identical to
-the standard
-hypercube crossover describe for the RealEA
-parameters above. But new parents can also be chosen anew for each variable
-before doing the crossover for that variable - and this is called global
-recombination.
-
# --crossObj=discrete # -O
-: Recombination of object variables (discrete or intermediate)
-
String parameter:
-There are two possible crossovers in plain ES. The discrete
-crossover simpy exchanges variables among the parents. It is similar to
-the plain uniform crossover for real variables. The crossover performs
-a linear combination of parents;variables - it si similar to the hypercube
-crossover described for with alpah parameter set to 0. This parameter
-allso to choose the type of crossover that will be applied to the object
-variables (i.e. the origianl variables
-of the problem). Default is discrete.
-
# --crossStdev=intermediate
-# -S : Recombination of mutation strategy parameters (intermediate or discrete)
-
String parameter:
-This parameter allows to choose the type of crossover (see above) that
-will be applied to the mutation strategy
-parameters that are part of the genotype.
-Default
-is intermediate.
-
# --TauLoc=1 # -l : Local
-Tau (before normalization)
-
Floating-point parameter:
-The local factor for the mutation of the mutation strategy parameters (the
-only one used when a single standard deviation is used). Default
-is 1.
-
# --TauGlob=1 # -g : Global
-Tau (before normalization)
-
Floating-point parameter:
-The global factor for the mutation of the mutation strategy parameters
-(only useful when more than one standard deviation are used). Default
-is 1.
-
# --Beta=0.0873 # -b : Beta
-
Floating-point parameter:
-The factor for the mutation of the rotation angles in the case of the full
-correlated mutation. Default is 0.0873
-(following Schwefel).
-
-
At the moment, you will have to browse in the source (colored!) code -(Bit - Real) almost by yourself, sorry. -
Note that the main file is now very slim, as it only contains calls -to some make_xxx -functions - these functions contain the actual code, very similar to the -code of Lesson3, except for the memory management, performed through an -eoState -object (notice that all make_xxx -calls have an eoState as second parameter). -
Programmer's guide: The -make_xxx files -
Interface: all make_xxx -files have as first two parameters an eoParser -and an eoState. -The eoParser -is be used within all functions to parse the command-line and/or a parameter -file in order to read any relevant user-parameter, while the eoState -is used here to store all pointers to be allocated inside the function -(see Programming hints for more -detailed explanations). -
There are 2 types of make_xxx
-files: the ones that do depend on representation, defining the genotype
-and
-initialization
-(make_genotype_xxx,
-with xxx being the type of genotype) and variation operators (make_op_xxx),
-and the one that are truly representation-independent (make_pop,
-make_continue, make _checkpoint, make_algo and
-make_run).
-
The former are located in the directory corresponding to the actual
-genotype (src/ga
-for eoBit, src/es
-for eoReal and all eoESxxx genotypes). The latter are in the directory
-src/do.
-
If you take a close look at the code of make_continue
-for instance, you will first notice that ... the function declared there
-is called do_make_continue
-and is not the one you are calling in
-the main file, though it has the same parameters as arguments.
-
The explanation lies within the file make_continue_xxx.cpp
-(with xxx = ga or real/es)which, as its color (and name) should have
-told you about, are representation-dependent: in fact the make_continue_xxx.cpp
-files only instanciates the general <EOT> template into one of the possible
-template for eoBit or eoReal/eoES - and this trick allows to compile
-them separately!
-
The other thing that you should notice is that the code there is very -similar to the code that was in Lesson 3, regarding parameter reading -and type of object that are allocated - except for memory management. This -goes for all make_xxx -files - so the only thing you need to understand how it goes is to look -at the memory management section. -
Pros: you don't have to handle a
-huge main function - and many of the make_xxx files can be directly used
-in different applications (this is called modularity
-:-)))
-
More interesting, you can even compile
-the make_xxx
-files separately for a given target
-template, and link them e.g. with your fitness function when it is ready
-(remember that up to now you needed to compile everything altogether by
-including the code into your mail fine). Indeed, if you do a global make,
-you will notice that there are additional libraries compiled in src/ga
-and src/es
-...
-
Cons: It makes the code a little
-more complex to understand, first because of the indirection needed for
-pre-compilation with a given template, and second because of the memory
-management that this imposes.
-
-
-
Programmer's
-guide: Memory management
-
As already said, all functions have an eoState
-as second argument - and that object is used to store the functor objects
-that were simply declared as variables of the main function up to now :
-see Programming hints for more
-detailed explanations and take a look at the code of make_continue
-for instance, you will see the implementation of the memory management
-in action.
-
Programmer's -guide: Memory management -of eoParam objects -
It has been seen in Lesson 3 that parameters could be read from command-line
-and/or a parameter file using an eoParser
-object. However, the memory mangement problem also concerns EO parameter
-objects (eoParam):
-the way there are read in Lesson3
-makes them local variables of the function they are defined in.
-
It is however possible to ask the eoParser
-to hold them, as done for instance in eoContinue for the maximum number
-of generations. Local declaration would amount to something like :
-
eoValueParam<unsigned
-int>& maxGenParam(100, "maxGen", "Maximum number of generations ()
-= none)",'G');
-
parser.processParam(
-maxGenParam, "Stopping criterion" );
-
unsigned maxGen =
-maxGenParam.value();
-
while if you want the parser to hold those eoParam objects, you will -write something like -
eoValueParam<unsigned>& -maxGenParam = _parser.createParam(unsigned(100), "maxGen", "Maximum number -of generations () = none)",'G',"Stopping criterion"); -
and then use maxGenParam.value()
-to get the value enterred by the user. In that case, you get a reference
-to an eoParam object that is hold by the eoParser - and deleted whith it.
-
Note that there are two important differences
-between the arguments of the constructor of an eoParam object and the method
-createParam of an eoParser object: first, you need to provide the additional
-section parameter (used only when outputting the eoParser); second you
-must
-make sure that the first argument is of the correct type otherwise the
-compiler will complain.
-
Note that if you don't later need the eoParam, but simply its value, -you can even diretly write -
unsigned maxGen = _parser.createParam(unsigned(100), -"maxGen", "Maximum number of generations () = none)",'G',"Stopping criterion").value(); -
Getting parameter values in different -functions: -
It is often useful (though probably very bad
-programming style :-))) to be able to get the value of a user-defined
-parameter in two different places of the code without passing it around
-through many levels of call. You can then use the alternate function getORcreateParam
-with exactly the same syntax than createParam.
-
Be careful that the link between both parameters is made through their
-longmanes (second argument), and that you must so hard-code
-that name in two different places with of course exactly the same spelling!!!
-
Examples can be found for instance
-in the make_genotype_xxx files, for the sizes of the genotypes: it is often
-the case that the definition of the optimization problem requires (or computes)
-such size. The idea is then that you either read or compute that size,
-then create a (dummy) parameter with the name that is used later in the
-make_genotype file. For instance, for bitstrings, the make_genotype_ga.h
-contains the following line defining the size of the bitstring
-
unsigned theSize = -_parser.getORcreateParam(unsigned(10), "chromSize", "The length of the -bitstrings", 'n',"Problem").value(); -
If you want to define that size earlier, you should write somewhere
-before
-
-
unsigned requiredSize
-= ... ;
-
_parser.createParam(requiredSize,
-"chromSize", "The length of the bitstrings", 'n',"Problem");
-
Of course, if that size is mandatory, you should NOT modify it at run-time -by entering anther value ! -
-
The minimum code you'll have to write is first, of course, the code -for the genotype structure. Then, the representation-dependent -code: intialization procedure(s), -variation -operators (quadratic crossover, mutation operator), ... and evaluation -function - and that's it : we have prepared some template files and -the script create.sh that will take care of generating a few other files -to make your application complete. -
In what follows, we will suppose that you want to evolve some data structure,
-and that you have enough programming skills to be able to write C code
-for its random initilialization, its crossover, its mutation and the computation
-of its fitness.
-
The examples will be described supposing you want to evolve ... bitstings
-to solve the OneMax problem (oh no!!!).
-
-
- May 2004 : A
-second script, createSimple,
- was added some time ago, that generates much simpler
-set of files, and the stat.tmpl
-file is now used to allow you to
-compute and
-print and
-save-to-disk and
-plot-on-line your
-own statistics.
-But you'll have to find out by yourself how those work, sorry, no
-time. It should be easy by just looking at the code (in main file, and
-in OneMaxEA.cpp
-and the newly created
-eoOneMaxStat.h.
-
- May 2004 : In
-the same simplified main file (e.g. OneMaxEA.cpp after running
-./createsimple OneMax in
-dir .../eo/tutorial/Templates), you
-will also be able to use fitness sharing (together with roulette) as a
-possible selector.
-
-
-
First thing is to write the code for the structure -of the genotype. This is done by filling in the template file -eoOneMax.h. -There are 4 places that you should consider filling in: -
Initializer: eoOneMaxInit.h
-
You must provide an eoInit
-object for your genotype, that is an object that will randomize
-a genotype built by the default constructor of the EO class
-(here, an eoOneMax object) . Here you must at least fill the
-code for such randomization.
-
But you might also need some parameters (e.g. the size of the bitstring
-in eoOneMax): you should then pass
-them through the constructor of the eoOneMaxInit class, and store
-it in its private data.
-
And of course you might need to add a destructor (no example here)
-if you use complex data type in the object.
-
Parameters: make_genotype_OneMax.h
-
There is another file you will probably want to modify as far as initialization
-is concerned, that is make_genotype_OneMax.h.
-Such helper files are used for all components of advanced EO programs (see
-Lesson 4). The main reason for that is to allow separate compilation of
-such sub-components for known EO types, as this is done in the directories
-src/ga and src/es. But a useful consequence is to make your code modular.
-For instance, the make_genotype_OneMax.h
-file takes care of all the preparation of all data regarding the eoInit
-object - and returns to the main fonction a reference to an eoInit that
-will later be used to initialize the whole
-population in a representation-independent way.
-
What you have to do in that file is to set values for all parameters
-needed by the eoOneMaxInit class, for instance by reading them from the
-parser: this allows later to modify them easily from the command-line.
-Note however that an alternative could be to pass the parser to the constructor
-of the eoOneMaxInit class, and to read all parameters there...
-
Note: Remember that the make_xxx
-files were first introduced to allow the user to compile sepearately most
-of the code of standard Evolutionary Algorithm written in EO for bitstring
-and real vector representations (
-
-
The eoOneMaxEvalFunc is
-the object that will compute the fitness of an
-eoOneMax object. You have to fill in the code
-for the computation of the fitness value (there is no way that this
-can be done automatically :-) Note that this code must be run only
-if the _eo.invalid() test
-returns true, to avoid computing the fitness of an object that has not
-been modified and thus still holds a valid fitness value. After computing
-the fitness, store it into the object by calling the fitness(FitnessType)
-method.
-
Should you need some specific data for that, the constructor
-of the object is the place to get such data, and you should, again,
-store it in some private data
-of the class.
-
-
Crossover: eoOneMaxQuadCrossover.h
-
As usual, you must go and write the code
-for the operator() that will perform the crossover, possibly modifying
-both arguments. Don't forget to update the boolean
-parameter that will report whether the genotypes have been modified
-- allowing to recompute the fitness only of the ones that have actually
-been modified. You can also have parameters
-to the crossover by passing
-them to the constructor, ans storing them in the private
-data of the crossover object.
-
Mutation: eoOneMaxMutation.h
-
Here again, you must go and write the code for the operator() that
-will perform the mutation, eventually modifying its arguments. Don't forget
-to update the boolean parameter that
-will report whether the genotype has been modified - allowing to recompute
-the fitness only of the ones that have actually been modified. You can
-also have parameters to the mutation
-by passing them to the constructor,
-ans storing them in the private data
-of the mutation object.
-
Parameters: make_op_OneMax.h
-
First of all, if you intend to use only one
-crossover operator and one mutation
-operator, you have nothing to modify
-in make_op_OneMax function, except maybe
-reading user-defined parameters (copy the code from make_genotype_OneMax)
-and passing them to the appropriate
-operator constructor.
-
As it is written now, it allows you enter a crossover probability Pcross
-and a mutation probability Pmut,
-and to build an eoGeneralOp that will call in sequence the eoOneMaxQuadCrossover
-that is defined above with probability Pcross
-and the eoOneMaxMutation also
-defined above with probability Pmut.
-Beware that all allocated objects must be stored in the eoState otherwise
-you will run into trouble (see EO Memory
-Management explanations).
-
However, everything is there (commented out) to allow you to use more -than one crossover and one mutation -- provided you write the code for them , of course. -
The code starts by defining an eoOneMaxQuadCrossoverobject, -then reads some application rate that is totally useless if you have only -one crossover, then creates an eoPropCombinedQuadOp -with this simple oeprator. The same story repeats for the mutation. Finally, -the eoGeneralOp -is created from those combined operators and the individulal level probabilities -Pcross -and Pmut. -
In order to add a second crossover operator for instance (called eoOneMaxSecondCrossover -in the commented code) all you need to is -
-
As a start, you should only (eventually) modify in OneMaxEA.cpp -the type of fitness you -will be handling, namely double -if you are maximizing, or eoMinimizingFitness -if you are minimizing. Then running -make will result in a perfectly -valid executable named OneMaxEA. -
The skeleton of the main file here mimics that of the main file in -Lesson4, -and uses the make_xxx separate -files construct: the part of an Evolutionary Algorithm related to the -evolution -engine is indepenent of the representation, -and can be directly used ... provided it is compiled with the right template -(remember everything in EO is templatized -over the EO objects it handles. Main file OneMaxEA.cpp -is written so that it includes eveything - and thus everytime you run make -(or make OneMaxEA), you compile -the code for make_pop, make_continue and make_checkpoint that is defined -in the .../src/do directory. -
The basic construct is (for instance to build the evolution engine)
-
-
#include <do/make_algo_scalar.h>
- eoAlgo<Indi>& make_algo_scalar(eoParser& -_parser, eoState& _state, eoEvalFunc<Indi>& _eval, eoContinue<Indi>& -_continue, eoGenOp<Indi>& _op) - { - return do_make_algo_scalar(_parser, -_state, _eval, _continue, _op); - } |
-
Go in your application directory, and look at the differences between -both files and you'll see how this is handled in both cases. -
Reducing compilation time:
-
However, we also provide another main file (OneMaxLibEA.cpp)that
-only includes the code that is specific to your application, and is supposed
-to be linked with another object file that will contain the code that is
-representation independent (make_OneMax.cpp).
-This is done by running make OneMaxLibEA
-on the command-line.
-
For example, on a PentiumIII 400MHz with g++ 2.96, compiling OneMaxEA
-takes about 33s, compiling both make_OneMax.o
-and OneMaxLibEA takes about
-54s but compiling only OneMaxLibEA
-takes only 14s make_OneMax.o
-is up-to-date ...
-
Hints:
-
While developping the genotype structure itself in file eoOneMax.h,
-you should use the OneMaxEA.cpp
-file. But after the eoOneMax.h
-file is frozen, you should use the eoOneMaxLibEA.cpp
-file. Of course, both resulting programs are strictly identical!
-
-
/** -*- mode: c++; c-indent-level:
-4; c++-member-init-indent: 8; comment-column: 35; -*-
- The above line is usefulin Emacs-like editors - */ - /* - Template for creating a new representation -in EO - ================================================ - */ - #ifndef _eoOneMax_h - #define _eoOneMax_h - /** - * Always write a comment in this format -before class definition - * if you want the class to be documented -by Doxygen - * Note that you MUST derive your structure -from EO<fitT> - * but you MAY use some other already prepared -class in the hierarchy - * like eoVector for instance, if you handle -a vector of something.... - * If you create a structure from scratch, - * the only thing you need to provide are - * -a default constructor - * -IO routines printOn and readFrom - * - * Note that operator<< and operator>> -are defined at EO level - * using these routines - */ |
-
template< class FitT>
- class eoOneMax: public EO<FitT> { - public: - /** Ctor: you MUST provide -a default ctor. - * though such individuals will -generally be processed - * by some eoInit object - */ - eoOneMax() - { |
-
-// START Code of default Ctor of an eoOneMax object
- // -END Code of default Ctor of an eoOneMax object |
-
}
- virtual ~eoOneMax()
- |
-
-// START Code of Destructor of an eoEASEAGenome object
- // -END Code of Destructor of an eoEASEAGenome object |
-
}
- virtual string className() const
-{ return "eoOneMax"; }
- |
-
/** printing... */
- void printOn(ostream& os) const - { - // -First write the fitness - EO<FitT>::printOn(os); - os << ' -'; |
-
}
- /** reading...
- |
-
-// START Code of input
- /** HINTS
- // END -Code of input |
-
}
- |
-
private: // -put all data here | -
//
-START Private data of an eoOneMax object
- // -END Private data of an eoOneMax object |
-
};
- #endif |
-
/** -*- mode: c++; c-indent-level:
-4; c++-member-init-indent: 8; comment-column: 35; -*-
- The above line is usefulin Emacs-like editors
- /*
- #ifndef _eoOneMaxEvalFunc_h
- // include whatever general include you need
- // include the base definition of eoEvalFunc
- /**
- |
-
template <class EOT>
- class eoOneMaxEvalFunc : public eoEvalFunc<EOT> - { - public: - /// Ctor - no requirement |
-
{ | -
//
-START Code of Ctor of an eoOneMaxEvalFunc object
- // -END Code of Ctor of an eoOneMaxEvalFunc object |
-
}
- /** Actually compute the fitness
- |
-
-// START Code of computation of fitness of the eoOneMax object
- // fit = blablabla - // -END Code of computation of fitness of the eoOneMax object |
-
_eo.fitness(fit);
- -} - } - private: |
-
// START Private data
-of an eoOneMaxEvalFunc object
- // varType anyVariable; -// for example ... - // END Private data of -an eoOneMaxEvalFunc object |
-
};
- #endif |
-
/** -*- mode: c++; c-indent-level:
-4; c++-member-init-indent: 8; comment-column: 35; -*-
- The above line is usefulin Emacs-like editors - */ - /*
- #ifndef _eoOneMaxInit_h
- // include the base definition of eoInit
- /**
- |
-
template <class GenotypeT>
- class eoOneMaxInit: public eoInit<GenotypeT> -{ - public: - /// Ctor - no requirement |
-
{ | -
//
-START Code of Ctor of an eoOneMaxInit object
- // -END Code of Ctor of an eoOneMaxInit object |
-
}
- /** initialize a genotype
- |
-
-// START Code of random initialization of an eoOneMax object
- // -END Code of random initialization of an eoOneMax object |
-
_genotype.invalidate();
-// IMPORTANT in case the _genotype is old
- } - private: |
-
// START Private data
-of an eoOneMaxInit object
- // varType anyVariable; -// for example ... - // END Private data of -an eoOneMaxInit object |
-
};
- #endif |
-
-/** -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*- -The above line is useful in Emacs-like editors - */ -/* -Template for simple mutation operators -====================================== -*/ -#ifndef eoOneMaxMutation_H -#define eoOneMaxMutation_H -#include <eoOp.h> -/** - * Always write a comment in this format before class definition - * if you want the class to be documented by Doxygen - * - * THere is NO ASSUMPTION on the class GenoypeT. - * In particular, it does not need to derive from EO - */ - - |
-
-
-template<class GenotypeT> -class eoOneMaxMutation: public eoMonOp<GenotypeT> -{ -public: - /** - * Ctor - no requirement - */ - - |
-
-
-// START eventually add or modify the anyVariable argument - eoOneMaxMutation() - // eoOneMaxMutation( varType _anyVariable) : anyVariable(_anyVariable) -// END eventually add or modify the anyVariable argument - - |
-
-
- { - - |
-
-
- // START Code of Ctor of an eoOneMaxEvalFunc object - // END Code of Ctor of an eoOneMaxEvalFunc object - - |
-
-
- } - /// The class name. Used to display statistics - string className() const { return "eoOneMaxMutation"; } - /** - * modifies the parent - * @param _genotype The parent genotype (will be modified) - */ - bool operator()(GenotypeT & _genotype) - { - bool isModified; - - |
-
-
- // START code for mutation of the _genotype object - /** Requirement -* if (_genotype has been modified) -* isModified = true; -* else -* isModified = false; -*/ - return isModified; - // END code for mutation of the _genotype object - - |
-
-
- } -private: - - |
-
-
-// START Private data of an eoOneMaxMutation object - // varType anyVariable; // for example ... -// END Private data of an eoOneMaxMutation object - - |
-
-
-}; -#endif - |
-
/** -*- mode: c++; c-indent-level:
-4; c++-member-init-indent: 8; comment-column: 35; -*-
- The above line is usefulin Emacs-like editors - */ - /* - Template for simple quadratic crossover operators - ================================================= - Quadratic crossover operators modify the -both genotypes - */ - #ifndef eoOneMaxQuadCrossover_H
- #include <eoOp.h> - /**
- |
-
template<class GenotypeT>
- class eoOneMaxQuadCrossover: public eoQuadOp<GenotypeT> - { - public: - /** - * Ctor - no requirement - */ |
-
{ | -
//
-START Code of Ctor of an eoOneMaxEvalFunc object
- // -END Code of Ctor of an eoOneMaxEvalFunc object |
-
}
- /// The class name. Used to
-display statistics
- /**
- |
-
}
- private: |
-
// START Private data
-of an eoOneMaxQuadCrossover object
- // varType anyVariable; -// for example ... - // END Private data of -an eoOneMaxQuadCrossover object |
-
};
- #endif |
-
/** -*- mode: c++; c-indent-level:
-4; c++-member-init-indent: 8; comment-column: 35; -*-
- The above line is usefulin Emacs-like editors - */ - /*
- #ifndef _eoOneMax_h
- |
-
/**
- * A simple example class for bitstring (is -NOT supposed to be used :-) - */ |
-
- |
template< class FitT>
- class eoOneMax: public EO<FitT> { - public: - /** Deafult Ctor: nothing to -be done */ - eoOneMax() {} - virtual string className() const
-{ return "eoOneMax"; }
- |
-
/** printing... */
- void printOn(ostream& -_os) const - { - -// First write the fitness - -EO<FitT>::printOn(_os); - -_os << ' '; |
-
-_os << b.size() << ' ' ;
- -for (unsigned i=0; i<b.size(); i++) - -_os << b[i] << ' ' ; |
-
}
- /** reading...
- |
-
unsigned s;
- _is >> s; - b.resize(s); - for (unsigned -i=0; i<s; i++) - -{ - -bool bTmp; - -_is >> bTmp; - -b[i] = bTmp; - -} |
-
} | -
- |
// brute setting (we could
-also have defined a Ctor from a vector<bool>)
- void setB(vector<bool> & -_b) - { - b=_b; - } - // brute accessing (we could
-also define operator[] ...)
- |
-
- private: // -put all data here |
-
std::vector<bool> b; | -
};
- #endif |
-
The basic idea of EO variation operators is that they operate on genotypes -only. Hence there should be generally no reference to anything related -to the fitness within a variation operator. However, whenever the genotype -of an individual has been modified, it will be necessary to recompute its -fitness before any selection process. This is why all -variation operator return a bool that indicates whether or not -the genotype argument has been modified or not. -
EO classes for variation operators: -
The characteristic of crossover operators is that they involve two parents. -However, there are crossover operators that generate two parents, and some -that generate one parent only, and both types are available in EO. The -former type (2 --> 2) is termed quadratic crossover operator, and is implemanted -in the eoQuadOp class; the latter type -(2 --> 1) is termed binary operator and is implemanted in class eoBinOp. -Both classes are, as usual, templatized by the type of individual they -can handle (see documentation for eoBinOp -and eoQuadOp). -
Note: Whereas it is straightforward -to create a binary crossover operator from a quadratic one (by discarding -the changes on the second parent), the reverse might prove impossible (imagine -a binary crossover that simply merges the parents material: there is no -way to generate two new parents from that!). -
Interfaces:
-
The general approach in EO about simple variation operators is to perform
-in-place
-modifications, i.e. modifying the arguments rather than generating
-new (modified) individuals. This results in the following interfaces for
-the functor objects eoBinOp and eoQuadOp:
-
bool operator()(EOT & , const EOT &)
-for eoBinOp (note the const)
-
bool operator()(EOT & , EOT &
-)
-for eoQuadOp
-
which you could have guessed from the inheritance diagrams up to the -eoBF abstract class. You can also guess that only the first argument will -be modified by an oeBin object, while both arguments will be modified by -an eoQuad object. -
Using crossover operators:
-
Directly applying crossover operators is straightforward from the interface
-above:
-
eoBinOpDerivedClass<Indi> myBinOp(parameters);
-//
-use constructor to pass
-
eoQuadOpDerivedClass<Indi> myQuadOp(parameters);
-//
-any useful argument
-
Indi eo1= ..., eo2= ...; //
-the candidates to crossover
-
if (myBinOp(eo1, eo2))
-
{ ...
-// eo1 has been modified, not eo2
-
}
-
else ...
-// none has been modified
-
if (myQuadOp(eo1, eo2))
-
{ ...
-// both eo1 and eo2 have been modified
-
}
-
else ...
-// none has been modified
-
However, you will hardly have to actually apply operators to individuals,
-as operators are used within other classes, and are applied systematically
-to whole sets of individuals (e.g. that have already been selected, in
-standard generation-based evolutionary algorithms).
-
Hence the way to use such operators will more likely ressemble this
-if you are using for instance an SGA. See also the different ways that
-are described below, encapsulating the operators into combined operators
-objects.
-
Writing a crossover
-operator:
-
There are three things to modify in the template class definitions
-provided in the Templates directory for both binary
-crossover and quadratic crossovers
-(apart from the name of the class you are creating!)
-
Interfaces:
-
The general approach in EO about simple variation operators is to perform
-in-place
-modifications, i.e. modifying the arguments rather than generating
-new (modified) individuals. This results in the following interface for
-the functor objects eoMonOp:
-
bool operator()(EOT & ) -
which you could have guessed from the inheritance diagrams up to the -eoUF abstract class. -
Using mutation operators:
-
Directly applying mutation operators is straightforward from the interface
-above:
-
eoMonOpDerivedClass<Indi> myMutation(parameters);
-//pass parameters in constructor
-
Indi eo = ...;
-// eo is candidate to mutation
-
if (myMutation(eo))
-
{ ... //
-eo has been modified
-
}
-
else //
-eo has not been modified
-
However, you will hardly have to actually apply operators to individuals,
-as operators are used within other classes, and are applied systematically
-to whole sets of individuals (e.g. that have already been selected, in
-standard generational evolutionary algorithms).
-
Hence the way to use such operators will more likely ressemble this
-if you are using for instance an SGA. See also the different ways that
-are described below, encapsulating the operators into combined operators
-objects.
-
Writing a mutation
-operator:
-
There are only two things to modify in the template
-class definitions provided in the Templates directory (apart from the
-name of the class you are creating!)
-
The best thing to do is to go to the Lesson2
-of the tutorial, where everything is explained. You will find out how you
-can use
-
several mutations (respectiveley quadratic crossovers) as a single
-operator: every time the operator is called, one of the available operators
-is chosen by some roulette wheel selection using realtive weights.
-
-
General operators in EO are variation operators that are neither simple -mutations nor simple crossovers. They can involve any number of parents, -and create any number of offspring. Moreover, they can make use of different -ways to get the parents they will involve, e.g. they can use a different -selector for each of the parents they need to select. -
The corresponding EO class is called eoGenOp. -and it is as usual templatized by the type of individual it can handle -(see documentation for eoGenOp -:-) -
Interface:
-
All the work a general operator is done within the apply()
-method. WHy not in the usual operator() method? Because some memory management
-are needed, that are performed in the base class itself - which then calls
-the virtual apply() method.
-The interface for a eoGenOp thus is
-not deducible from its inheritance diagram, and actually is
-
void apply(eoPopulator<EOT>& -_plop) -
As you can see,the interface for eoGenOp -is based on that of another class, called eoPopulator. -An -eoPopulator -is a population, but also behaves like -an iterator over a population (hence -the name, Population-Iterator). -However, please note that you should probably never use an eoGenOp alone, -but rather through objects of type eoOpContainer. -
This results in the following general interface for an eoGenOp: -It receives as argument an eoPopulator, -gets the individuals it needs using the operator*, -and must handle the positinning of the using the ++operator -method (Warning: the operator++ -method is not defined, as recommended by many good-programming-style books). -
bool apply()(eoPopulator&
-_pop)
-
{
-
EOT& parent1 = *_pop;
-//
-select the first parent
-
++_plop; //
-advance once for each selected parents
-
...
-
EOT& parentN = *_pop;
-//
-select the last parent
-
//
-don't advance after the last one: _plop always
-
-// points to the last that has already been treated
-
// do whatever the operator is supposed to
-do
-
}
-
Warning: as said above, an eoPopulator -should always point to the last individual that has already been treated. -This is because it is intended to be used within a loop that looks like -(see e.g. eoBreeder -class): -
eoSelectivePopulator<EOT>
-popit(_parents, _offspring, select); // eoSelect
-is an eoSelectOne
-
while (_offspring.size()
-< target)
-
-{
-
-op(popit);
-
-++it;
-
-}
-
What happens next? Well, it all -depends on how many parents and how many offspring your general op needs: -
-
void apply()(eoPopulator&
-_pop)
-
{
-
// get the necessary number
-of parents (see above)
-
...
-
// Now create any supplementary offspring
-
EOT ofs1 = create_individual(...);
-
...
-
EOT ofsK = create_individual(...);
-
// advance and inserts offspring in
-_pop after parentN
-
++_pop;
-
_pop.insert(ofs1);
-
...
-
// invalidate the parents that
-have been modified
-
parent1.invalidate();
-
...
-
parentN.invalidate();
-
} // over
-
Of course the size of the resulting population will grow - and you should
-have a replacement procedure that takes care of that.
-
-
-
void apply()(eoPopulator&
-_pop)
-
{
-
// get as many parents as you
-will have offspring (see above)
-
...
-
// get extra parents - use
-private selector
-
const EOT& parentN+1 = select(_pop.source());
-
...
-
const EOT& parentM = select(_pop.source());
-
// do whatever needs to be done
-
...
-
// and of course invalidate fitnesses
-of remaining modified parents
-
parent1.invalidate();
-
...
-
parentN.invalidate();
-
}
-
where select is any selector you like. Note the
-const: you are not allowed to modify an element of the original
-population (but you could of course have copied it!). As usual, the select
-selector was passed to the operator at construct time. This typically allows
-one to use a different selector for one parent and the others, as demonstrated
-here.
-
-
-
void apply()(eoPopulator&
-_pop)
-
{
-
// get as many parents as you
-will have offspring (see above)
-
...
-
// get extra parents - use
-populator selector
-
const EOT& parentN+1 = _pop.select();
-
...
-
const EOT& parentM = _pop.select();
-
// do whatever needs to be done
-
...
-
// and of course invalidate fitnesses
-of remaining modified parents
-
parent1.invalidate();
-
...
-
parentN.invalidate();
-
}
Using general operators:
-
Directly applying general operators to given individuals is impossible
-in EO, due to its interface. You need the help
-of an individual dispenser of class eoPopulator.
-But anyway general operators were thought to be used putely in eoOpContainer,
-as described below.
-
Writing a general
-operator:
-
There are many things to do to write a general operator - but the Templates
-directory contains some sample tempaltes files to help you. It all depends
-on whether you want more or less offspring than parents, and whetehr you
-want the same selector for every parent or more specialized selectors.
-
The basic -interface of an eoPopulator -(see also the documentation, -of course) is the following: -
Example: An eoSelectivePopulator
-is the main ingredient of the eoGeneralBreeder
-operator()
-method - a class that creates a population of offspring from the parents
-applying an eoGenOp (usually an eoOpContainer) to all selected parents
-in turn.
-
-
Proportional combinations
-
When called upon a population (through an eoPopulator
-object), an eoProportionalOpContainer
-enters the following loop:
-
while there are individuals left in the list -
mark the current position
-
for all operators it contains,
-
Adding operators to a container:
-
The way to add an operator to an eoOpContainer
-is the method
-add. It is similar
-to all other add methods in
-other Combined things in eo (as the simple eoProportionalCombinedXXXop
-described above, but also the eoCombinedContinue class or the eoCheckPoint
-class).
-
The syntax is straightforward, and it works with any of the operator
-classes eoXXXOp, where XXX stands for
-Mon,
-Bin, Quad or
-Gen:
-
someOperatorType<Indi> myOperator;
-
eoYYYOpContainer<Indi> myOpContainer;
-
myOpContainer.add(myOperator, rate); //
-rate: double whose meaning depends on YYY
-
where YYY can be one of Proportional and Sequential. Note that before -being added to the container, all simple operators are wrapped into the -corresponding eoGenOp (see e.g. how an eoMonOpis -wrapped into an eoMonGenOp- or -how any operator -is handled by calling the appropriate wrapper). In particular, the -wrapper ensures that individuals who have been -modified are invalidated. -
Containers,
-Selectors and Populators
-
The way the eoOpContainer are applied
-on a population using an eoPopulator
-object. But, whereas the behavior of eoProportionalOpContainer
-does not depend on the type of eoPopulator,(one
-operator is chosen by roulette_wheel, and applied once before control is
-given back to the caller), the main loop in method operator()
-of
-class eoSequentialOpContainer
-iterates while (!_pop.exhausted())
-which is interpreted differently depending on the type
-of eoPopulator:
-
It is sometimes useful to be able to use a selector from inside an operator
-(a typical example is when you want to implement sexual
-preferences, i.e. choose a mate for a first parent according
-to some characteritics of that first parent).
-
This is made possible in EO because the general operators have a handle
-on the initial population through the method source()
-of the argument eoPopulator they work on. Their apply()
-method shoudl look like
-
void apply()(eoPopulator&
-_pop)
-
{
-
EOT & eo1 = *_pop; // get
-(select if necessary) the first guy
-
EOT maBlonde = findBlonde(_pop.source());
-//
-select mate
-
// do whatever the operator is supposed
-to do, e.g
-
cross(eo1, maBonde);
-// cross is some embedded crossover
-
...
-
// if you don't want to put maBlonde
-into the offspring,
-
// stop here (and use a reference
-to maBlonde above). Otherwise
-
maBonde.invalidate();
-
++_pop; //
-advance
-
_pop.insert(maBlonde);
-// and insert it
-
}
-
Where does that findBlonde -selector comes from? As usual, you have to attach it to the operator, -in its constructor for instance, which should give something like: -
sexualSelectorType<Indi> findBlonde;
-
sexualOperatorType<Indi> yourBrainAndMyBeauty(cross,
-findBlonde);
-
-
Most EO code is 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 (see EO.h) -
template<class F> class EO -
The idea is that, later in your code, you can define a class as follows -(see for instance eoOneMax.h - or check Lesson 5 for more details). -
template<class F> class eoOneMax : public
-EO<F>
-
{ ... code for eoOneMax };
-
and then use it in your application as -
eoOneMax<double> myeoBit; -
declares an object of type eoOneMax which has as fitness 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. -
-
Though EO is a library, it contains almost no functions per se!
-
EO mainly contains functors, that are objects which have a method called
-operator().
-Such objects are used as if they were functions, but the big differences
-are that
-
Functors: Example: -
The following is a basic example of how to program and use a functor -object: First code the class: -
class MyFunctor
-
{ ...
-
void operator()(ArgType
-arg)
-
{
-
-// do what you have to do
-
}
-
}; // end of class declaration
-
Then use it later in the code : -
ArgType myArgument;
-
MyFunctor myFunctorInstance;
-// myFunctorInstance is an object of class MyFUnctor ...
-
myFunctorInstance(myArgument);
-// calls operator() of myFunctorInstance acting on myArgument ...
-
-
Functors: The -three basic classes: -
Direct sub-classes of the root class , three classes
-are defined to differentiate functors by the number of argument required
-by their operator().
-These classes are templatized by the types of its arguments, and by its
-return type. Hence,
-
from the inheritance diagram of any functor class
-in EO, you can immediately deduce the interface of their operator()
-method.
-
-
Note: for -obvious simplicity reasons, we very often omit the reference to the operator(), -e.g. when we say above: -
-
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.
-Moreover, while browsing through EO code, you will gradually learn how
-to use STL, especially if you check at the SGI
-STL Web site from time to time, where you can not only download STL,
-but also browse in the Programmer's guide for isntance from the Table
-of Content.
-
Anyway, you will only find here, in EO tutorial, 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 containers, -iterators -and algorithms. And you can access -(almost) all containers content using (almost) all iterators, or apply -(almost) all algorithms on (almost) all containers (of course the tricky -part is to instanciate the "almost" in the previous sentence :-) -
STL: 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.
-
STL: Iterators
-
Iterators are accessors to the containers contents that provide unified
-access to different containers. They are very similar to pointers, i.e.
-you can increment them, compare them with one another, etc
-
Some very useful iterators for vectors and lists are begin()
-and end(), that refer to the first
-and after-last items of a container. They allow loops to sweep all items
-contained in a container as follows:
-
STLcontainer myContain;
-
STLcontainer::iterator it;
-
for (it=myContain.begin(); it!=myContain.end();
-it++)
-
{
-
// do what you have to do to
-(*it)
-the current item in the container
-
}
-
STL: Algorithms
-
Algorithms are functions acting on containers - the most widely used
-example of a STL algorithm are the different sorting
-algorithms.
-
STL: Drawbacks
-
The main drawback I see in using STL is that it makes it
-difficult
-to use a debugger normally: whereas access to data is made simple
-to the programmer, data structures are actually so complex, and debuggers
-so willing to display everything that you get lines of template instantiation
-when asking your debugger what is inside some container!
-However, here is a trick (thanks to Arnaud Quirin!) to actually print what is inside an STL vector with gdb (but it doesn't really work with complex structures like EO genotypes :-( :
-(gdb) print (*(&v))[i]
-$1 = (const double &) @0x934cad0: 0.69543264131061733
-
-
-
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 different 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 eo::rng. -Using that single RNG in all calls to random numbers allows one to be able -to reproduce a given run: -
EO also provides random_generators -that can be used in STL call to generate series of random numbers, as in -eoPop -initializers. -
Note: the eo::
-prefix indicates that it is in a separate C++ namespace, to avoid collision
-with possible variables that would also be named rng in some other library.
-As early versions of EO (<= 9.1) did not use a separate namespace
-for rng, the compiler directive using eo::rng in eoRNG.h allows you to
-use the name rng without the eo::
-prefix. However, the notation eo::rng
-should be preferred and might become mandatory some day.
-
-
A few naming conventions should help you to navigate more easily through -EO: -
-
-
-
class eoMyClass
-
{
-
public:
-
eoMyClass(unsigned _popSize):popSize(_popSize){...}
-
...
-
private:
-
unsigned popSize;
-
};
-
Most of EO constructs are based on the encapsulation
-of objects into other objects, and the embedded objects are passed through
-the constructor of the embedding object.
-
For instance, the construction of an algorithm requires a breeder (plus
-many other things of course), the construction of a breeder usually requires
-a selector, and in turn the construction of a selector requires some parameters.
-This gives something resembling the following
-
eoTournamentSelection<EOT> select(tSize);
-
eoBreeder<EOT> breed(select);
-
eoEasyAlgo<EOT> algo( ..., breed, ...);
-
Such a practice is no problem when doing everything -in a (large!) main function: all objects are local to that function, -but when the end of the function is also the end of the program. For instance, -all programs in Lesson1, Lesson2 -and Lesson3 of this tutorial are built that -way. -
It is however a big problem when you want to outsource some code in -other functions: indeed, the above sequence create objects that dissapear -when exiting the function, and thus cannot be used outside their defining -function. -
The solution is of course to use pointers, -which gives something like -
eoTournamentSelection<EOT> *ptSelect
-= new eoTournamentSelection<EOT>(tSize);
-
eoBreeder<EOT> *ptBreed = new eoBreeder<EOT>(*ptSselect);
-
eoEasyAlgo<EOT> *ptAlgo = new eoEasyAlgo<EOT>(
-..., *ptBreed, ...);
-
and you can then use the dynamically allocated objects anywhere. But -the trouble with such a construct is that after exiting the function where -such objects are defined, you will never be able -to free this allocated memory, should you not need the objects -any nore. Whereas this is not in general a big problem (except of being -a very bad practice that will make you a very naughty programmer :-), it -will prevent any re-entrance of the resulting code, and for instance you -will not be able to use an evolutionary algorithm within another loop of -some outside code. -
The solution in EO us to use an eoFunctorStore -object to store such nowhere-belonging pointers: whenever you allocate -such a thing, store it into an eoState : deleting that state will delete -all the stored pointers - one eoState is thus the only object you have -to care of. -
The above pointer allocation sequence thus become -
eoTournamentSelection<EOT> *ptSelect
-= new eoTournamentSelection<EOT>(tSize);
-
state.storeFunctor(ptSelect);
-
eoBreeder<EOT> *ptBreed = new eoBreeder<EOT>(*ptSelect);
-
state.storeFunctor(ptBreed);
-
eoEasyAlgo<EOT> *ptAlgo = new eoEasyAlgo<EOT>(
-..., *ptBreed, ...);
-
state.storeFunctor(ptAlgo);
-
or, even more quickly (though less readably) -
eoTournamentSelection<EOT> *ptSelect
-=
-
-state.storeFunctor(new eoTournamentSelection<EOT>(tSize));
-
eoBreeder<EOT> *ptBreed =
-
-state.storeFunctor(new eoBreeder<EOT>(*ptSelect));
-
eoEasyAlgo<EOT> *ptAlgo =
-
-state.storeFunctor(new eoEasyAlgo<EOT>( ..., *ptBreed, ...));
-
In both the above code, state is an eoFunctorStore -that is of course passed from outside the function -- and it's called state because in most cases it will actually be an eoState. -As its name says, an eoFunctorStore -can store any object that is an (derives from) eoFunctorBase -- hence all objects in EO that are used as functors should derive from -either eoF, eoUF or eBF. -
Examples of such constructs are shown in the make_xxx files described
-in Lesson4.
-
-
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 |
-
-
-
-
- From there on, you don't need to follow the lesson order any more: you
-can go directly to any lesson and experiment. Of course, you will need
-to bring together the different pieces to write exactly what you want -
-but only because we had no idea of what you exactly want :-)
-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
deleted file mode 100644
index f589f0aa0..000000000
--- a/eo/tutorial/html/eoTopDown.html
+++ /dev/null
@@ -1,111 +0,0 @@
-
-
-
-
-
-
-
-
-EO - The Algorithm-Based approach
Congratulations - You have chosen the algorithm-based 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.
-
-
-Marc Schoenauer
-
-
Current version (May. 5, 2002) stops here, but ...
-
-
-Of course, in each lesson, you have links to the corresponding Component-Based
-page. ( ... Well, to tell you the truth, as of today, this is not exactly
-true :-)
-
-
-
Tutorial main page - Algorithm-Based
-- Component-Based - Programming
-hints - EO
-documentation
-
-
-
Last modified: Tue Dec 19
-2000
-
-
diff --git a/eo/tutorial/html/eoTutorial.html b/eo/tutorial/html/eoTutorial.html
deleted file mode 100644
index 1dbef8bd2..000000000
--- a/eo/tutorial/html/eoTutorial.html
+++ /dev/null
@@ -1,286 +0,0 @@
-
-
-
-
-
-
-
-
You will see this diagram in quite many places, as for instance at the -top of all examples - usually it will be clickable 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, -
You should of course have downloaded and installed the whole EO
-library (how did you get this file if not???).
-If you are using a recent version of EO (0.9.3+), all tutorial Lessons
-should have been compiled when installing the library, and you can now
-proceed with Lesson1.
-
Otherwise, 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!
-
Algorithm-Based
-- Component-Based - Programming
-hints - EO
-documentation
-
-// -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*- - -//----------------------------------------------------------------------------- - -// make_genotype.h - -// (c) Maarten Keijzer, Marc Schoenauer and GeNeura Team, 2001 - -/* - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - Contact: todos@geneura.ugr.es, http://geneura.ugr.es - Marc.Schoenauer@inria.fr - mkeijzer@dhi.dk - */ - -//----------------------------------------------------------------------------- -#ifndef _make_genotype_h -#define _make_genotype_h -#include <eoOneMax.h> -#include <eoOneMaxInit.h> - -// also need the parser and param includes -#include <utils/eoParser.h> -#include <utils/eoState.h> - -/* - * This fuction does the create an eoInit<eoOneMax> - * - * It could be here tempatized only on the fitness, as it can be used - * to evolve structures with any fitness. - * However, for consistency reasons, it was finally chosen, as in - * the rest of EO, to templatize by the full EOT, as this eventually - * allows to choose the type of genotype at run time (see in es dir) - * - * It returns an eoInit<EOT> that can later be used to initialize - * the population (see make_pop.h). - * - * It uses a parser (to get user parameters) and a state (to store the memory) - * the last argument is to disambiguate the call upon different instanciations. - * - * WARNING: that last argument will generally be the result of calling - * the default ctor of EOT, resulting in most cases in an EOT - * that is ***not properly initialized*** -*/ - - |
-
-
-template <class EOT> -eoInit<EOT> & do_make_genotype(eoParser& _parser, eoState& _state, EOT) -{ - - |
-
-
-
-// read any useful parameter here from the parser - -// the param itself will belong to the parser (as far as memory is concerned) - -// paramType & param = _parser.createParam(deafultValue, "Keyword", "Comment to appear in help and status", 'c',"Section of status file").value(); - - |
-
-
-
-// Then built the initializer - a pointer, stored in the eoState - eoInit<EOT>* init = new eoOneMaxInit<EOT> -/* ( param ) */ ; ; - - |
-
-
-
-// Eventually by passing the parameters you need - // eoInit<EOT>* init = new eoOneMaxInit<EOT> -/* ( param ) */ ; ; - - |
-
-
-
-// store in state - _state.storeFunctor(init); - -// and return a reference - return *init; -} -#endif - |
-
// -*- mode: c++; c-indent-level:
-4; c++-member-init-indent: 8; comment-column: 35; -*-
- //-----------------------------------------------------------------------------
- #ifndef _make_op_OneMax_h
- // the operators
- /** definition of mutation:
- /** definition of crossover (either as eoBinOp
-(2->1) or eoQuadOp (2->2):
- // also need the parser and
-state includes
- /////////////////// variation operators ///////////////
- /*
- |
-
#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; - } |
-
But you are not in the right place!
-
You should better try to go to the html directory, for instance by
-clicking here.
-
-