Paradiseo-eo sources added

git-svn-id: svn://scm.gforge.inria.fr/svnroot/paradiseo@40 331e1502-861f-0410-8da2-ba01fb791d7f
This commit is contained in:
legrand 2006-12-12 14:49:08 +00:00
commit c3aec878e5
3609 changed files with 342772 additions and 0 deletions

View file

@ -0,0 +1 @@
Makefile.in

View file

@ -0,0 +1,6 @@
/.cvsignore/1.1/Fri Sep 17 16:53:15 2004//
/Makefile.am/1.3/Tue Feb 22 14:12:19 2005//
/Makefile.simple/1.1/Fri Sep 17 15:20:15 2004//
/README/1.4/Tue Dec 19 18:18:08 2000//
/index.html/1.3/Thu Jan 4 15:23:14 2001//
D

View file

@ -0,0 +1,10 @@
A D/Lesson1////
A D/Lesson2////
A D/Lesson3////
A D/Lesson4////
A D/Lesson5////
A D/ParadisEO////
A D/Templates////
A D/examples////
A D/html////
A D/pdf////

View file

@ -0,0 +1 @@
eo/tutorial

View file

@ -0,0 +1 @@
:ext:evomarc@eodev.cvs.sourceforge.net:/cvsroot/eodev

View file

@ -0,0 +1 @@
Makefile.in

View file

@ -0,0 +1,7 @@
/.cvsignore/1.1/Fri Sep 17 16:53:14 2004//
/FirstBitGA.cpp/1.10/Wed Sep 28 21:49:26 2005//
/FirstRealGA.cpp/1.9/Wed Sep 28 21:49:26 2005//
/Makefile.am/1.2/Wed Sep 22 18:18:30 2004//
/Makefile.simple/1.1/Fri Sep 17 15:20:17 2004//
/exercise1.3.cpp/1.7/Wed Sep 28 21:49:26 2005//
D

View file

@ -0,0 +1 @@
eo/tutorial/Lesson1

View file

@ -0,0 +1 @@
:ext:evomarc@eodev.cvs.sourceforge.net:/cvsroot/eodev

View file

@ -0,0 +1,167 @@
//-----------------------------------------------------------------------------
// FirstBitGA.cpp
//-----------------------------------------------------------------------------
//*
// An instance of a VERY simple Bitstring Genetic Algorithm
//
//-----------------------------------------------------------------------------
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <stdexcept>
#include <iostream>
#include <eo>
#include <ga.h>
// Use functions from namespace std
using namespace std;
// REPRESENTATION
//-----------------------------------------------------------------------------
// define your individuals
typedef eoBit<double> Indi; // A bitstring with fitness double
// EVAL
//-----------------------------------------------------------------------------
// a simple fitness function that computes the number of ones of a bitstring
// @param _indi A biststring individual
double binary_value(const Indi & _indi)
{
double sum = 0;
for (unsigned i = 0; i < _indi.size(); i++)
sum += _indi[i];
return sum;
}
// GENERAL
//-----------------------------------------------------------------------------
void main_function(int argc, char **argv)
{
// PARAMETRES
// all parameters are hard-coded!
const unsigned int SEED = 42; // seed for random number generator
const unsigned int T_SIZE = 3; // size for tournament selection
const unsigned int VEC_SIZE = 16; // Number of bits in genotypes
const unsigned int POP_SIZE = 100; // Size of population
const unsigned int MAX_GEN = 400; // Maximum number of generation before STOP
const float CROSS_RATE = 0.8; // Crossover rate
const double P_MUT_PER_BIT = 0.01; // probability of bit-flip mutation
const float MUT_RATE = 1.0; // mutation rate
// GENERAL
//////////////////////////
// Random seed
//////////////////////////
//reproducible random seed: if you don't change SEED above,
// you'll aways get the same result, NOT a random run
rng.reseed(SEED);
// EVAL
/////////////////////////////
// Fitness function
////////////////////////////
// Evaluation: from a plain C++ fn to an EvalFunc Object
eoEvalFuncPtr<Indi> eval( binary_value );
// INIT
////////////////////////////////
// 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
}
// OUTPUT
// sort pop before printing it!
pop.sort();
// Print (sorted) intial population (raw printout)
cout << "Initial Population" << endl;
cout << pop;
// shuffle - this is a test
pop.shuffle();
// Print (sorted) intial population (raw printout)
cout << "Shuffled Population" << endl;
cout << pop;
// ENGINE
/////////////////////////////////////
// selection and replacement
////////////////////////////////////
// SELECT
// The robust tournament selection
eoDetTournamentSelect<Indi> select(T_SIZE); // T_SIZE in [2,POP_SIZE]
// REPLACE
// The simple GA evolution engine uses generational replacement
// so no replacement procedure is needed
// OPERATORS
//////////////////////////////////////
// The variation operators
//////////////////////////////////////
// CROSSOVER
// 1-point crossover for bitstring
eo1PtBitXover<Indi> xover;
// MUTATION
// standard bit-flip mutation for bitstring
eoBitMutation<Indi> mutation(P_MUT_PER_BIT);
// STOP
// CHECKPOINT
//////////////////////////////////////
// termination condition
/////////////////////////////////////
// stop after MAX_GEN generations
eoGenContinue<Indi> continuator(MAX_GEN);
// GENERATION
/////////////////////////////////////////
// the algorithm
////////////////////////////////////////
// standard Generational GA requires as parameters
// selection, evaluation, crossover and mutation, stopping criterion
eoSGA<Indi> gga(select, xover, CROSS_RATE, mutation, MUT_RATE,
eval, continuator);
// Apply algo to pop - that's it!
gga(pop);
// OUTPUT
// Print (sorted) intial population
pop.sort();
cout << "FINAL Population\n" << pop << endl;
// GENERAL
}
// A main that catches the exceptions
int main(int argc, char **argv)
{
try
{
main_function(argc, argv);
}
catch(exception& e)
{
cout << "Exception: " << e.what() << '\n';
}
return 1;
}

View file

@ -0,0 +1,162 @@
//-----------------------------------------------------------------------------
// FirstRealGA.cpp
//-----------------------------------------------------------------------------
//*
// An instance of a VERY simple Real-coded Genetic Algorithm
//
//-----------------------------------------------------------------------------
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <stdexcept>
#include <iostream>
#include <sstream>
#include <eo>
#include <es.h>
// Use functions from namespace std
using namespace std;
// REPRESENTATION
//-----------------------------------------------------------------------------
// define your individuals
typedef eoReal<double> Indi;
// EVAL
//-----------------------------------------------------------------------------
// a simple fitness function that computes the euclidian norm of a real vector
// @param _indi A real-valued individual
double real_value(const Indi & _indi)
{
double sum = 0;
for (unsigned i = 0; i < _indi.size(); i++)
sum += _indi[i]*_indi[i];
return (-sum); // maximizing only
}
// GENERAL
//-----------------------------------------------------------------------------
void main_function(int argc, char **argv)
{
// PARAMETRES
// all parameters are hard-coded!
const unsigned int SEED = 42; // seed for random number generator
const unsigned int VEC_SIZE = 8; // Number of object variables in genotypes
const unsigned int POP_SIZE = 20; // Size of population
const unsigned int T_SIZE = 3; // size for tournament selection
const unsigned int MAX_GEN = 500; // Maximum number of generation before STOP
const float CROSS_RATE = 0.8; // Crossover rate
const double EPSILON = 0.01; // range for real uniform mutation
const float MUT_RATE = 0.5; // mutation rate
// GENERAL
//////////////////////////
// Random seed
//////////////////////////
//reproducible random seed: if you don't change SEED above,
// you'll aways get the same result, NOT a random run
rng.reseed(SEED);
// EVAL
/////////////////////////////
// Fitness function
////////////////////////////
// Evaluation: from a plain C++ fn to an EvalFunc Object
eoEvalFuncPtr<Indi> eval( real_value );
// INIT
////////////////////////////////
// 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
}
// OUTPUT
// sort pop before printing it!
pop.sort();
// Print (sorted) intial population (raw printout)
cout << "Initial Population" << endl;
cout << pop;
// ENGINE
/////////////////////////////////////
// selection and replacement
////////////////////////////////////
// SELECT
// The robust tournament selection
eoDetTournamentSelect<Indi> select(T_SIZE); // T_SIZE in [2,POP_SIZE]
// REPLACE
// eoSGA uses generational replacement by default
// so no replacement procedure has to be given
// OPERATORS
//////////////////////////////////////
// The variation operators
//////////////////////////////////////
// CROSSOVER
// offspring(i) is a linear combination of parent(i)
eoSegmentCrossover<Indi> xover;
// MUTATION
// offspring(i) uniformly chosen in [parent(i)-epsilon, parent(i)+epsilon]
eoUniformMutation<Indi> mutation(EPSILON);
// STOP
// CHECKPOINT
//////////////////////////////////////
// termination condition
/////////////////////////////////////
// stop after MAX_GEN generations
eoGenContinue<Indi> continuator(MAX_GEN);
// GENERATION
/////////////////////////////////////////
// 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);
// OUTPUT
// Print (sorted) intial population
pop.sort();
cout << "FINAL Population\n" << pop << endl;
// GENERAL
}
// A main that catches the exceptions
int main(int argc, char **argv)
{
try
{
main_function(argc, argv);
}
catch(exception& e)
{
cout << "Exception: " << e.what() << '\n';
}
return 1;
}

View file

@ -0,0 +1,16 @@
noinst_PROGRAMS = FirstBitGA FirstRealGA exercise1.3
FirstBitGA_SOURCES = FirstBitGA.cpp
FirstRealGA_SOURCES = FirstRealGA.cpp
exercise1_3_SOURCES = exercise1.3.cpp
LDADD = -L$(top_builddir)/src -L$(top_builddir)/src/ga -L$(top_builddir)/src/utils
LIBS = -lga -leoutils -leo
INCLUDES = -I$(top_srcdir)/src

View file

@ -0,0 +1,25 @@
# if you use this Makefile as a starting point for another application
# you might need to modify the following
DIR_EO = ../../src
.SUFFIXES: .cpp
# Warning: $(CXX) in Linux (RedHat and Mandrake at least) is g++
# However, if you are using this Makefile within xemacs,
# and have problems with the interpretation of the output (and its colors)
# then you should use c++ instead (make CXX=c++ will do)
.cpp: ; $(CXX) -DPACKAGE=\"eo\" -DVERSION=\"0.9.3\" -I. -I$(DIR_EO) -Wall -g -pg -o $@ $*.cpp $(DIR_EO)/utils/libeoutils.a $(DIR_EO)/libeo.a
.cpp.o: ; $(CXX) -DPACKAGE=\"eo\" -DVERSION=\"0.9.3\" -I. -I$(DIR_EO) -Wall -g -c -pg $*.cpp
firstGA = FirstRealGA FirstBitGA
ALL = $(firstGA) exercise1.3
lesson1 : $(firstGA)
all : $(ALL)
clean :
@/bin/rm $(ALL) *.o *~

View file

@ -0,0 +1,162 @@
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
//-----------------------------------------------------------------------------
// FirstBitGA.cpp
//-----------------------------------------------------------------------------
//*
// An instance of a VERY simple Bitstring Genetic Algorithm
//
//-----------------------------------------------------------------------------
// standard includes
#include <iostream>
#include <stdexcept>
// the general include for eo
#include <eo>
//-----------------------------------------------------------------------------
// Include the corresponding file
#include <ga.h> // bitstring representation & operators
// define your individuals
typedef eoBit<double> Indi; // A bitstring with fitness double
using namespace std;
//-----------------------------------------------------------------------------
/** a simple fitness function that computes the number of ones of a bitstring
@param _indi A biststring individual
*/
double binary_value(const Indi & _indi)
{
double sum = 0;
for (unsigned i = 0; i < _indi.size(); i++)
sum += _indi[i];
return sum;
}
//-----------------------------------------------------------------------------
void main_function(int argc, char **argv)
{
const unsigned int SEED = 42; // seed for random number generator
const unsigned int VEC_SIZE = 8; // Number of bits in genotypes
const unsigned int POP_SIZE = 20; // Size of population
const unsigned int MAX_GEN = 500; // Maximum number of generation before STOP
const float CROSS_RATE = 0.8; // Crossover rate
const double P_MUT_PER_BIT = 0.01; // probability of bit-flip mutation
const float MUT_RATE = 1.0; // mutation rate
//////////////////////////
// Random seed
//////////////////////////
//reproducible random seed: if you don't change SEED above,
// you'll aways get the same result, NOT a random run
rng.reseed(SEED);
/////////////////////////////
// Fitness function
////////////////////////////
// Evaluation: from a plain C++ fn to an EvalFunc Object
eoEvalFuncPtr<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
////////////////////////////////////
// solution solution solution: uncomment one of the following,
// comment out the eoDetTournament lines
// The well-known roulette
// eoProportionalSelect<Indi> select;
// could also use stochastic binary tournament selection
//
// const double RATE = 0.75;
// eoStochTournamentSelect<Indi> select(RATE); // RATE in ]0.5,1]
// The robust tournament selection
const unsigned int T_SIZE = 3; // size for tournament selection
eoDetTournamentSelect<Indi> select(T_SIZE); // T_SIZE in [2,POP_SIZE]
// and of course the random selection
// eoRandomSelect<Indi> select;
// The simple GA evolution engine uses generational replacement
// so no replacement procedure is needed
//////////////////////////////////////
// termination condition
/////////////////////////////////////
// stop after MAX_GEN generations
eoGenContinue<Indi> continuator(MAX_GEN);
//////////////////////////////////////
// The variation operators
//////////////////////////////////////
// standard bit-flip mutation for bitstring
eoBitMutation<Indi> mutation(P_MUT_PER_BIT);
// 1-point mutation for bitstring
eo1PtBitXover<Indi> xover;
/////////////////////////////////////////
// the algorithm
////////////////////////////////////////
// standard Generational GA requires as parameters
// selection, evaluation, crossover and mutation, stopping criterion
eoSGA<Indi> gga(select, xover, CROSS_RATE, mutation, MUT_RATE,
eval, continuator);
// Apply algo to pop - that's it!
gga(pop);
// Print (sorted) intial population
pop.sort();
cout << "FINAL Population\n" << pop << endl;
}
// A main that catches the exceptions
int main(int argc, char **argv)
{
try
{
main_function(argc, argv);
}
catch(exception& e)
{
cout << "Exception: " << e.what() << '\n';
}
return 1;
}

View file

@ -0,0 +1 @@
Makefile.in

View file

@ -0,0 +1,9 @@
/.cvsignore/1.1/Fri Sep 17 16:53:14 2004//
/FirstBitEA.cpp/1.11/Wed Sep 28 21:49:26 2005//
/FirstRealEA.cpp/1.14/Wed Sep 28 21:49:26 2005//
/Makefile.am/1.3/Sun Oct 2 21:42:08 2005//
/Makefile.simple/1.1/Fri Sep 17 15:20:18 2004//
/binary_value.h/1.2/Thu Feb 27 19:19:51 2003//
/exercise2.3.cpp/1.8/Wed Sep 28 21:49:26 2005//
/real_value.h/1.3/Tue Feb 27 05:09:09 2001//
D

View file

@ -0,0 +1 @@
eo/tutorial/Lesson2

View file

@ -0,0 +1 @@
:ext:evomarc@eodev.cvs.sourceforge.net:/cvsroot/eodev

View file

@ -0,0 +1,193 @@
//-----------------------------------------------------------------------------
// FirstBitEA.cpp
//-----------------------------------------------------------------------------
//*
// Still an instance of a VERY simple Bitstring Genetic Algorithm
// (see FirstBitGA.cpp) but now with Breeder - and Combined Ops
//
//-----------------------------------------------------------------------------
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
// standard includes
#include <stdexcept> // runtime_error
#include <iostream> // cout
// the general include for eo
#include <eo>
#include <ga.h>
// Use functions from namespace std
using namespace std;
// REPRESENTATION
//-----------------------------------------------------------------------------
// define your individuals
typedef eoBit<double> Indi; // A bitstring with fitness double
// EVALFUNC
//-----------------------------------------------------------------------------
// a simple fitness function that computes the number of ones of a bitstring
// Now in a separate file, and declared as binary_value(const vector<bool> &)
#include "binary_value.h"
// GENERAL
//-----------------------------------------------------------------------------
void main_function(int argc, char **argv)
{
// PARAMETRES
const unsigned int SEED = 42; // seed for random number generator
const unsigned int T_SIZE = 3; // size for tournament selection
const unsigned int VEC_SIZE = 8; // Number of bits in genotypes
const unsigned int POP_SIZE = 20; // Size of population
const unsigned int MAX_GEN = 500; // Maximum number of generation before STOP
const unsigned int MIN_GEN = 10; // Minimum number of generation before ...
const unsigned int STEADY_GEN = 50; // stop after STEADY_GEN gen. without improvelent
const double P_CROSS = 0.8; // Crossover probability
const double P_MUT = 1.0; // mutation probability
const double P_MUT_PER_BIT = 0.01; // internal probability for bit-flip mutation
// some parameters for chosing among different operators
const double onePointRate = 0.5; // rate for 1-pt Xover
const double twoPointsRate = 0.5; // rate for 2-pt Xover
const double URate = 0.5; // rate for Uniform Xover
const double bitFlipRate = 0.5; // rate for bit-flip mutation
const double oneBitRate = 0.5; // rate for one-bit mutation
// GENERAL
//////////////////////////
// Random seed
//////////////////////////
//reproducible random seed: if you don't change SEED above,
// you'll aways get the same result, NOT a random run
rng.reseed(SEED);
// EVAL
/////////////////////////////
// Fitness function
////////////////////////////
// Evaluation: from a plain C++ fn to an EvalFunc Object
// you need to give the full description of the function
eoEvalFuncPtr<Indi, double, const vector<bool>& > eval( binary_value );
// INIT
////////////////////////////////
// Initilisation of population
////////////////////////////////
// based on boolean_generator 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 loop
apply<Indi>(eval, pop); // STL syntax
// OUTPUT
// sort pop before printing it!
pop.sort();
// Print (sorted) intial population (raw printout)
cout << "Initial Population" << endl;
cout << pop;
// ENGINE
/////////////////////////////////////
// selection and replacement
////////////////////////////////////
// SELECT
// The robust tournament selection
eoDetTournamentSelect<Indi> selectOne(T_SIZE); // T_SIZE in [2,POP_SIZE]
// is now encapsulated in a eoSelectPerc (entage)
eoSelectPerc<Indi> select(selectOne);// by default rate==1
// REPLACE
// And we now have the full slection/replacement - though with
// no replacement (== generational replacement) at the moment :-)
eoGenerationalReplacement<Indi> replace;
// OPERATORS
//////////////////////////////////////
// The variation operators
//////////////////////////////////////
// CROSSOVER
// 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);
// MUTATION
// standard bit-flip mutation for bitstring
eoBitMutation<Indi> mutationBitFlip(P_MUT_PER_BIT);
// mutate exactly 1 bit per individual
eoDetBitFlip<Indi> mutationOneBit;
// Combine them with relative rates
eoPropCombinedMonOp<Indi> mutation(mutationBitFlip, bitFlipRate);
mutation.add(mutationOneBit, oneBitRate, true);
// The operators are encapsulated into an eoTRansform object
eoSGATransform<Indi> transform(xover, P_CROSS, mutation, P_MUT);
// STOP
// CHECKPOINT
//////////////////////////////////////
// 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(VEC_SIZE);
// do stop when one of the above says so
eoCombinedContinue<Indi> continuator(genCont);
continuator.add(steadyCont);
continuator.add(fitCont);
// GENERATION
/////////////////////////////////////////
// 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);
// OUTPUT
// Print (sorted) intial population
pop.sort();
cout << "FINAL Population\n" << pop << endl;
// GENERAL
}
// A main that catches the exceptions
int main(int argc, char **argv)
{
try
{
main_function(argc, argv);
}
catch(exception& e)
{
cout << "Exception: " << e.what() << '\n';
}
return 1;
}

View file

@ -0,0 +1,192 @@
//-----------------------------------------------------------------------------
// FirstRealEA.cpp
//-----------------------------------------------------------------------------
//*
// Still an instance of a VERY simple Real-coded Genetic Algorithm
// (see FirstBitGA.cpp) but now with Breeder - and Combined Ops
//
//-----------------------------------------------------------------------------
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
// standard includes
#include <stdexcept> // runtime_error
#include <iostream> // cout
// the general include for eo
#include <eo>
#include <es.h>
// REPRESENTATION
//-----------------------------------------------------------------------------
// define your individuals
typedef eoReal<double> Indi;
// Use functions from namespace std
using namespace std;
// EVALFUNC
//-----------------------------------------------------------------------------
// a simple fitness function that computes the euclidian norm of a real vector
// Now in a separate file, and declared as binary_value(const vector<bool> &)
#include "real_value.h"
// GENERAL
//-----------------------------------------------------------------------------
void main_function(int argc, char **argv)
{
// PARAMETRES
const unsigned int SEED = 42; // seed for random number generator
const unsigned int T_SIZE = 3; // size for tournament selection
const unsigned int VEC_SIZE = 8; // Number of object variables in genotypes
const unsigned int POP_SIZE = 20; // Size of population
const unsigned int MAX_GEN = 500; // Maximum number of generation before STOP
const unsigned int MIN_GEN = 10; // Minimum number of generation before ...
const unsigned int STEADY_GEN = 50; // stop after STEADY_GEN gen. without improvelent
const float P_CROSS = 0.8; // Crossover probability
const float P_MUT = 0.5; // mutation probability
const double EPSILON = 0.01; // range for real uniform mutation
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
// GENERAL
//////////////////////////
// Random seed
//////////////////////////
//reproducible random seed: if you don't change SEED above,
// you'll aways get the same result, NOT a random run
rng.reseed(SEED);
// EVAL
/////////////////////////////
// Fitness function
////////////////////////////
// Evaluation: from a plain C++ fn to an EvalFunc Object
// you need to give the full description of the function
eoEvalFuncPtr<Indi, double, const vector<double>& > eval( real_value );
// INIT
////////////////////////////////
// Initilisation of population
////////////////////////////////
// based on a uniform generator
eoUniformGenerator<double> uGen(-1.0, 1.0);
eoInitFixedLength<Indi> random(VEC_SIZE, uGen);
// Initialization of the population
eoPop<Indi> pop(POP_SIZE, random);
// and evaluate it in one loop
apply<Indi>(eval, pop); // STL syntax
// OUTPUT
// sort pop before printing it!
pop.sort();
// Print (sorted) intial population (raw printout)
cout << "Initial Population" << endl;
cout << pop;
// ENGINE
/////////////////////////////////////
// selection and replacement
////////////////////////////////////
// SELECT
// The robust tournament selection
eoDetTournamentSelect<Indi> selectOne(T_SIZE);
// is now encapsulated in a eoSelectPerc (entage)
eoSelectPerc<Indi> select(selectOne);// by default rate==1
// REPLACE
// And we now have the full slection/replacement - though with
// no replacement (== generational replacement) at the moment :-)
eoGenerationalReplacement<Indi> replace;
// OPERATORS
//////////////////////////////////////
// The variation operators
//////////////////////////////////////
// CROSSOVER
// 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);
// MUTATION
// 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);
// STOP
// CHECKPOINT
//////////////////////////////////////
// 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 operators are encapsulated into an eoTRansform object
eoSGATransform<Indi> transform(xover, P_CROSS, mutation, P_MUT);
// GENERATION
/////////////////////////////////////////
// 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);
// OUTPUT
// Print (sorted) intial population
pop.sort();
cout << "FINAL Population\n" << pop << endl;
// GENERAL
}
// A main that catches the exceptions
int main(int argc, char **argv)
{
try
{
main_function(argc, argv);
}
catch(exception& e)
{
cout << "Exception: " << e.what() << '\n';
}
return 1;
}

View file

@ -0,0 +1,23 @@
noinst_PROGRAMS = FirstBitEA FirstRealEA exercise2.3
FirstBitEA_SOURCES = FirstBitEA.cpp
FirstRealEA_SOURCES = FirstRealEA.cpp
exercise2_3_SOURCES = exercise2.3.cpp
noinst_HEADERS = binary_value.h \
real_value.h
extra_DIST = Makefile.simple
LDADD = -L$(top_builddir)/src -L$(top_builddir)/src/ga -L$(top_builddir)/src/utils
LIBS = -lga -leo -leoutils
INCLUDES = -I$(top_srcdir)/src

View file

@ -0,0 +1,34 @@
### This Makefile is part of the tutorial of the EO library
# Unlike other Makefiles in EO, it is not using the automake/autoconf
# so that it stays easy to understant (you are in the tutorial, remember!)
# MS, Oct. 2002
# if you use this Makefile as a starting point for another application
# you might need to modify the following
DIR_EO = ../../src
.SUFFIXES: .cpp
# Warning: $(CXX) in Linux (RedHat and Mandrake at least) is g++
# However, if you are using this Makefile within xemacs,
# and have problems with the interpretation of the output (and its colors)
# then you should use c++ instead (make CXX=c++ will do)
.cpp: ; $(CXX) -DPACKAGE=\"eo\" -DVERSION=\"0.9.3\" -I. -I$(DIR_EO) -Wall -g -pg -o $@ $*.cpp $(DIR_EO)/utils/libeoutils.a $(DIR_EO)/libeo.a
.cpp.o: ; $(CXX) -DPACKAGE=\"eo\" -DVERSION=\"0.9.3\" -I. -I$(DIR_EO) -Wall -g -c -pg $*.cpp
firstEA = FirstRealEA FirstBitEA
ALL = $(firstEA) exercise2.3
lesson2 : $(firstEA)
all : $(ALL)
clean :
@/bin/rm $(ALL) *.o *~
FirstRealEA : real_value.h
FirstBitEA : binary_value.h

View file

@ -0,0 +1,17 @@
#include <eo>
//-----------------------------------------------------------------------------
/** Just a simple function that takes binary value of a chromosome and sets
the fitnes.
@param _chrom A binary chromosome
*/
// INIT
double binary_value(const std::vector<bool>& _chrom)
{
double sum = 0;
for (unsigned i = 0; i < _chrom.size(); i++)
sum += _chrom[i];
return sum;
}

View file

@ -0,0 +1,197 @@
//-----------------------------------------------------------------------------
// FirstBitEA.cpp
//-----------------------------------------------------------------------------
//*
// Still an instance of a VERY simple Bitstring Genetic Algorithm
// (see FirstBitGA.cpp) but now with Breeder - and Combined Ops
//
//-----------------------------------------------------------------------------
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
// standard includes
#include <stdexcept> // runtime_error
#include <iostream> // cout
// the general include for eo
#include <eo>
// REPRESENTATION
//-----------------------------------------------------------------------------
// Include the corresponding file
#include <ga.h> // bitstring representation & operators
// define your individuals
typedef eoBit<double> Indi; // A bitstring with fitness double
// EVAL
//-----------------------------------------------------------------------------
// a simple fitness function that computes the number of ones of a bitstring
// Now in a separate file, and declared as binary_value(const vector<bool> &)
#include "binary_value.h"
// GENERAL
//-----------------------------------------------------------------------------
using namespace std;
void main_function(int argc, char **argv)
{
// PARAMETRES
const unsigned int SEED = 42; // seed for random number generator
const unsigned int T_SIZE = 3; // size for tournament selection
const unsigned int VEC_SIZE = 20; // Number of bits in genotypes
const unsigned int POP_SIZE = 20; // Size of population
const unsigned int MAX_GEN = 500; // Maximum number of generation before STOP
const unsigned int MIN_GEN = 10; // Minimum number of generation before ...
const unsigned int STEADY_GEN = 50; // stop after STEADY_GEN gen. without improvelent
const double P_CROSS = 0.8; // Crossover probability
const double P_MUT = 1.0; // mutation probability
const double P_MUT_PER_BIT = 0.01; // internal probability for bit-flip mutation
// some parameters for chosing among different operators
const double onePointRate = 0.5; // rate for 1-pt Xover
const double twoPointsRate = 0.5; // rate for 2-pt Xover
const double URate = 0.5; // rate for Uniform Xover
const double bitFlipRate = 0.5; // rate for bit-flip mutation
const double oneBitRate = 0.5; // rate for one-bit mutation
// GENERAL
//////////////////////////
// Random seed
//////////////////////////
//reproducible random seed: if you don't change SEED above,
// you'll aways get the same result, NOT a random run
rng.reseed(SEED);
// EVAL
/////////////////////////////
// Fitness function
////////////////////////////
// Evaluation: from a plain C++ fn to an EvalFunc Object
// you need to give the full description of the function
eoEvalFuncPtr<Indi, double, const vector<bool>& > eval( binary_value );
// INIT
////////////////////////////////
// Initilisation of population
////////////////////////////////
// based on boolean_generator class (see utils/rnd_generator.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 loop
apply<Indi>(eval, pop); // STL syntax
// OUTPUT
// sort pop before printing it!
pop.sort();
// Print (sorted) intial population (raw printout)
cout << "Initial Population" << endl;
cout << pop;
// ENGINE
/////////////////////////////////////
// selection and replacement
////////////////////////////////////
// SELECT
// The robust tournament selection
eoDetTournamentSelect<Indi> selectOne(T_SIZE); // T_SIZE in [2,POP_SIZE]
// solution solution solution solution solution solution solution
// modify the nb offspring / rate in the constructor. 2 ways:
// second arg treated as integer
eoSelectMany<Indi> select(selectOne,2, eo_is_an_integer);
// second arg treated as a rate (default behavior)
// eoSelectMany<Indi> select(selectOne,0.1);
// REPLACE
// solution solution solution solution solution solution solution
// eoCommaReplacement keeps the best among offspring
// eoPlusReplacement keeps the best among parents + offspring
// eoCommaReplacement<Indi> replace;
eoPlusReplacement<Indi> replace;
// OPERATORS
//////////////////////////////////////
// The variation operators
//////////////////////////////////////
// CROSSOVER
// 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);
// MUTATION
// standard bit-flip mutation for bitstring
eoBitMutation<Indi> mutationBitFlip(P_MUT_PER_BIT);
// mutate exactly 1 bit per individual
eoDetBitFlip<Indi> mutationOneBit;
// Combine them with relative rates
eoPropCombinedMonOp<Indi> mutation(mutationBitFlip, bitFlipRate);
mutation.add(mutationOneBit, oneBitRate, true);
// The operators are encapsulated into an eoTRansform object
eoSGATransform<Indi> transform(xover, P_CROSS, mutation, P_MUT);
// STOP
// CHECKPOINT
//////////////////////////////////////
// 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(VEC_SIZE);
// do stop when one of the above says so
eoCombinedContinue<Indi> continuator(genCont);
continuator.add(steadyCont);
continuator.add(fitCont);
// GENERATION
/////////////////////////////////////////
// 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);
// OUTPUT
// Print (sorted) intial population
pop.sort();
cout << "FINAL Population\n" << pop << endl;
// GENERAL
}
// A main that catches the exceptions
int main(int argc, char **argv)
{
try
{
main_function(argc, argv);
}
catch(exception& e)
{
cout << "Exception: " << e.what() << '\n';
}
return 1;
}

View file

@ -0,0 +1,20 @@
#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
*/
// INIT
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;
}

View file

@ -0,0 +1 @@
Makefile.in

View file

@ -0,0 +1,9 @@
/.cvsignore/1.1/Fri Sep 17 16:53:13 2004//
/Makefile.am/1.5/Wed Dec 7 15:51:32 2005//
/Makefile.simple/1.1/Fri Sep 17 15:20:18 2004//
/SecondBitEA.cpp/1.17/Wed Sep 28 21:49:26 2005//
/SecondRealEA.cpp/1.4/Wed Sep 28 21:49:26 2005//
/binary_value.h/1.2/Thu Feb 27 19:19:40 2003//
/exercise3.1.cpp/1.19/Wed Sep 28 21:49:26 2005//
/real_value.h/1.1/Wed May 22 02:13:06 2002//
D

View file

@ -0,0 +1 @@
eo/tutorial/Lesson3

View file

@ -0,0 +1 @@
:ext:evomarc@eodev.cvs.sourceforge.net:/cvsroot/eodev

View file

@ -0,0 +1,22 @@
noinst_PROGRAMS = SecondBitEA SecondRealEA exercise3.1
SecondBitEA_SOURCES = SecondBitEA.cpp
SecondRealEA_SOURCES = SecondRealEA.cpp
exercise3_1_SOURCES = exercise3.1.cpp
noinst_HEADERS = binary_value.h \
real_value.h
extra_DIST = Makefile.simple
LDADD = -L$(top_builddir)/src -L$(top_builddir)/src/ga -L$(top_builddir)/src/utils
LIBS = -lga -leoutils -leo
INCLUDES = -I$(top_srcdir)/src

View file

@ -0,0 +1,33 @@
### This Makefile is part of the tutorial of the EO library
# Unlike other Makefiles in EO, it is not using the automake/autoconf
# so that it stays easy to understant (you are in the tutorial, remember!)
# MS, Oct. 2002
# if you use this Makefile as a starting point for another application
# you might need to modify the following
DIR_EO = ../../src
.SUFFIXES: .cpp
# Warning: $(CXX) in Linux (RedHat and Mandrake at least) is g++
# However, if you are using this Makefile within xemacs,
# and have problems with the interpretation of the output (and its colors)
# then you should use c++ instead (make CXX=c++ will do)
.cpp: ; $(CXX) -DPACKAGE=\"eo\" -DVERSION=\"0.9.3\" -I. -I$(DIR_EO) -Wall -g -pg -o $@ $*.cpp $(DIR_EO)/utils/libeoutils.a $(DIR_EO)/libeo.a
.cpp.o: ; $(CXX) -DPACKAGE=\"eo\" -DVERSION=\"0.9.3\" -I. -I$(DIR_EO) -Wall -g -c -pg $*.cpp
secondEA = SecondBitEA SecondRealEA
ALL = $(secondEA) exercise3.1
lesson3 : $(secondEA)
all : $(ALL)
SecondBitEA : binary_value.h
SecondRealEA : real_value.h
clean :
@/bin/rm $(ALL) *.o *.sav *.xg *.status *~

View file

@ -0,0 +1,348 @@
//-----------------------------------------------------------------------------
// 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!
//-----------------------------------------------------------------------------
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
// standard includes
#include <fstream>
#include <iostream> // cout
#include <stdexcept> // runtime_error
// the general include for eo
#include <eo>
#include <ga.h>
// Use functions from namespace std
using namespace std;
// EVAL
#include "binary_value.h"
// REPRESENTATION
//-----------------------------------------------------------------------------
// 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)
{
// PARAMETRES
//-----------------------------------------------------------------------------
// instead of having all values of useful parameters as constants, read them:
// either on the command line (--option=value or -o=value)
// or in a parameter file (same syntax, order independent,
// # = usual comment character
// or in the environment (TODO)
// First define a parser from the command-line arguments
eoParser parser(argc, argv);
// For each parameter, define Parameter, read it through the parser,
// and assign the value to the variable
eoValueParam<uint32_t> seedParam(time(0), "seed", "Random number seed", 'S');
parser.processParam( seedParam );
unsigned seed = seedParam.value();
// description of genotype
eoValueParam<unsigned int> vecSizeParam(8, "vecSize", "Genotype size",'V');
parser.processParam( vecSizeParam, "Representation" );
unsigned vecSize = vecSizeParam.value();
// parameters for evolution engine
eoValueParam<unsigned int> popSizeParam(10, "popSize", "Population size",'P');
parser.processParam( popSizeParam, "Evolution engine" );
unsigned popSize = popSizeParam.value();
eoValueParam<unsigned int> tSizeParam(10, "tSize", "Tournament size",'T');
parser.processParam( tSizeParam, "Evolution Engine" );
unsigned tSize = tSizeParam.value();
// init and stop
eoValueParam<string> loadNameParam("", "Load","A save file to restart from",'L');
parser.processParam( loadNameParam, "Persistence" );
string loadName = loadNameParam.value();
eoValueParam<unsigned int> maxGenParam(100, "maxGen", "Maximum number of generations",'G');
parser.processParam( maxGenParam, "Stopping criterion" );
unsigned maxGen = maxGenParam.value();
eoValueParam<unsigned int> minGenParam(100, "minGen", "Minimum number of generations",'g');
parser.processParam( minGenParam, "Stopping criterion" );
unsigned minGen = minGenParam.value();
eoValueParam<unsigned int> steadyGenParam(100, "steadyGen", "Number of generations with no improvement",'s');
parser.processParam( steadyGenParam, "Stopping criterion" );
unsigned steadyGen = steadyGenParam.value();
// operators probabilities at the algorithm level
eoValueParam<double> pCrossParam(0.6, "pCross", "Probability of Crossover", 'C');
parser.processParam( pCrossParam, "Genetic Operators" );
double pCross = pCrossParam.value();
eoValueParam<double> pMutParam(0.1, "pMut", "Probability of Mutation", 'M');
parser.processParam( pMutParam, "Genetic Operators" );
double pMut = pMutParam.value();
// relative rates for crossovers
eoValueParam<double> onePointRateParam(1, "onePointRate", "Relative rate for one point crossover", '1');
parser.processParam( onePointRateParam, "Genetic Operators" );
double onePointRate = onePointRateParam.value();
eoValueParam<double> twoPointsRateParam(1, "twoPointRate", "Relative rate for two point crossover", '2');
parser.processParam( twoPointsRateParam, "Genetic Operators" );
double twoPointsRate = twoPointsRateParam.value();
eoValueParam<double> uRateParam(2, "uRate", "Relative rate for uniform crossover", 'U');
parser.processParam( uRateParam, "Genetic Operators" );
double URate = uRateParam.value();
// relative rates and private parameters for mutations;
eoValueParam<double> pMutPerBitParam(0.01, "pMutPerBit", "Probability of flipping 1 bit in bit-flip mutation", 'b');
parser.processParam( pMutPerBitParam, "Genetic Operators" );
double pMutPerBit = pMutPerBitParam.value();
eoValueParam<double> bitFlipRateParam(0.01, "bitFlipRate", "Relative rate for bit-flip mutation", 'B');
parser.processParam( bitFlipRateParam, "Genetic Operators" );
double bitFlipRate = bitFlipRateParam.value();
eoValueParam<double> oneBitRateParam(0.01, "oneBitRate", "Relative rate for deterministic bit-flip mutation", 'D');
parser.processParam( oneBitRateParam, "Genetic Operators" );
double oneBitRate = oneBitRateParam.value();
// the name of the "status" file where all actual parameter values will be saved
string str_status = parser.ProgramName() + ".status"; // default value
eoValueParam<string> statusParam(str_status.c_str(), "status","Status file",'S');
parser.processParam( statusParam, "Persistence" );
// do the following AFTER ALL PARAMETERS HAVE BEEN PROCESSED
// i.e. in case you need parameters somewhere else, postpone these
if (parser.userNeedsHelp())
{
parser.printHelp(cout);
exit(1);
}
if (statusParam.value() != "")
{
ofstream os(statusParam.value().c_str());
os << parser; // and you can use that file as parameter file
}
// EVAL
/////////////////////////////
// Fitness function
////////////////////////////
// Evaluation: from a plain C++ fn to an EvalFunc Object ...
eoEvalFuncPtr<Indi, double, const vector<bool>& > plainEval( binary_value );
// ... to an object that counts the nb of actual evaluations
eoEvalFuncCounter<Indi> eval(plainEval);
// INIT
////////////////////////////////
// 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<bool> uGen;
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
// OUTPUT
// sort pop for pretty printout
pop.sort();
// Print (sorted) intial population (raw printout)
cout << "Initial Population" << endl << pop << endl;
// ENGINE
/////////////////////////////////////
// selection and replacement
////////////////////////////////////
// SELECT
// The robust tournament selection
eoDetTournamentSelect<Indi> selectOne(tSize); // tSize in [2,POPSIZE]
// is now encapsulated in a eoSelectPerc (stands for Percentage)
eoSelectPerc<Indi> select(selectOne);
// REPLACE
// And we now have the full slection/replacement - though with
// the same generational replacement at the moment :-)
eoGenerationalReplacement<Indi> replace;
// OPERATORS
//////////////////////////////////////
// The variation operators
//////////////////////////////////////
// CROSSOVER
// 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);
// MUTATION
// 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);
// STOP
//////////////////////////////////////
// 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);
// CHECKPOINT
// but now you want to make many different things every generation
// (e.g. statistics, plots, ...).
// the class eoCheckPoint is dedicated to just that:
// Declare a checkpoint (from a continuator: an eoCheckPoint
// IS AN eoContinue and will be called in the loop of all algorithms)
eoCheckPoint<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
// GENERATION
/////////////////////////////////////////
// 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);
// OUTPUT
// Print (sorted) intial population
pop.sort();
cout << "FINAL Population\n" << pop << endl;
// GENERAL
}
// A main that catches the exceptions
int main(int argc, char **argv)
{
try
{
main_function(argc, argv);
}
catch(exception& e)
{
cout << "Exception: " << e.what() << '\n';
}
return 1;
}

View file

@ -0,0 +1,329 @@
//-----------------------------------------------------------------------------
// 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)
//
//-----------------------------------------------------------------------------
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
// standard includes
#include <fstream>
#include <iostream> // cout
#include <stdexcept> // runtime_error
// the general include for eo
#include <eo>
#include <es.h>
// REPRESENTATION
//-----------------------------------------------------------------------------
// define your individuals
typedef eoReal<eoMinimizingFitness> Indi;
// Use functions from namespace std
using namespace std;
// EVALFUNC
//-----------------------------------------------------------------------------
// a simple fitness function that computes the euclidian norm of a real vector
// Now in a separate file, and declared as binary_value(const vector<bool> &)
#include "real_value.h"
// GENERAL
//-----------------------------------------------------------------------------
void main_function(int argc, char **argv)
{
// PARAMETRES
//-----------------------------------------------------------------------------
// instead of having all values of useful parameters as constants, read them:
// either on the command line (--option=value or -o=value)
// or in a parameter file (same syntax, order independent,
// # = usual comment character
// or in the environment (TODO)
// First define a parser from the command-line arguments
eoParser parser(argc, argv);
// For each parameter, you can in on single line
// define the parameter, read it through the parser, and assign it
unsigned seed = parser.createParam(unsigned(time(0)), "seed", "Random number seed", 'S').value(); // will be in default section General
// description of genotype
unsigned vecSize = parser.createParam(unsigned(8), "vecSize", "Genotype size",'V', "Representation" ).value();
// parameters for evolution engine
unsigned popSize = parser.createParam(unsigned(10), "popSize", "Population size",'P', "Evolution engine" ).value();
unsigned tSize = parser.createParam(unsigned(2), "tSize", "Tournament size",'T', "Evolution Engine" ).value();
// init and stop
string loadName = parser.createParam(string(""), "Load","A save file to restart from",'L', "Persistence" ).value();
unsigned maxGen = parser.createParam(unsigned(100), "maxGen", "Maximum number of generations",'G', "Stopping criterion" ).value();
unsigned minGen = parser.createParam(unsigned(100), "minGen", "Minimum number of generations",'g', "Stopping criterion" ).value();
unsigned steadyGen = parser.createParam(unsigned(100), "steadyGen", "Number of generations with no improvement",'s', "Stopping criterion" ).value();
// operators probabilities at the algorithm level
double pCross = parser.createParam(double(0.6), "pCross", "Probability of Crossover", 'C', "Genetic Operators" ).value();
double pMut = parser.createParam(double(0.1), "pMut", "Probability of Mutation", 'M', "Genetic Operators" ).value();
// relative rates for crossovers
double hypercubeRate = parser.createParam(double(1), "hypercubeRate", "Relative rate for hypercube crossover", '\0', "Genetic Operators" ).value();
double segmentRate = parser.createParam(double(1), "segmentRate", "Relative rate for segment crossover", '\0', "Genetic Operators" ).value();
// internal parameters for the mutations
double EPSILON = parser.createParam(double(0.01), "EPSILON", "Width for uniform mutation", '\0', "Genetic Operators" ).value();
double SIGMA = parser.createParam(double(0.3), "SIGMA", "Sigma for normal mutation", '\0', "Genetic Operators" ).value();
// relative rates for mutations
double uniformMutRate = parser.createParam(double(1), "uniformMutRate", "Relative rate for uniform mutation", '\0', "Genetic Operators" ).value();
double detMutRate = parser.createParam(double(1), "detMutRate", "Relative rate for det-uniform mutation", '\0', "Genetic Operators" ).value();
double normalMutRate = parser.createParam(double(1), "normalMutRate", "Relative rate for normal mutation", '\0', "Genetic Operators" ).value();
// the name of the "status" file where all actual parameter values will be saved
string str_status = parser.ProgramName() + ".status"; // default value
string statusName = parser.createParam(str_status, "status","Status file",'S', "Persistence" ).value();
// do the following AFTER ALL PARAMETERS HAVE BEEN PROCESSED
// i.e. in case you need parameters somewhere else, postpone these
if (parser.userNeedsHelp())
{
parser.printHelp(cout);
exit(1);
}
if (statusName != "")
{
ofstream os(statusName.c_str());
os << parser; // and you can use that file as parameter file
}
// EVAL
/////////////////////////////
// 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);
// INIT
////////////////////////////////
// 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
// OUTPUT
// sort pop before printing it!
pop.sort();
// Print (sorted) intial population (raw printout)
cout << "Initial Population" << endl;
cout << pop;
// ENGINE
/////////////////////////////////////
// selection and replacement
////////////////////////////////////
// SELECT
// The robust tournament selection
eoDetTournamentSelect<Indi> selectOne(tSize);
// is now encapsulated in a eoSelectPerc (entage)
eoSelectPerc<Indi> select(selectOne);// by default rate==1
// REPLACE
// And we now have the full slection/replacement - though with
// no replacement (== generational replacement) at the moment :-)
eoGenerationalReplacement<Indi> replace;
// OPERATORS
//////////////////////////////////////
// The variation operators
//////////////////////////////////////
// CROSSOVER
// 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);
// MUTATION
// 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);
// STOP
//////////////////////////////////////
// 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);
// CHECKPOINT
// but now you want to make many different things every generation
// (e.g. statistics, plots, ...).
// the class eoCheckPoint is dedicated to just that:
// Declare a checkpoint (from a continuator: an eoCheckPoint
// IS AN eoContinue and will be called in the loop of all algorithms)
eoCheckPoint<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
// GENERATION
/////////////////////////////////////////
// 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);
// OUTPUT
// Print (sorted) intial population
pop.sort();
cout << "FINAL Population\n" << pop << endl;
// GENERAL
}
// A main that catches the exceptions
int main(int argc, char **argv)
{
try
{
main_function(argc, argv);
}
catch(exception& e)
{
cout << "Exception: " << e.what() << '\n';
}
return 1;
}

View file

@ -0,0 +1,17 @@
#include <eo>
//-----------------------------------------------------------------------------
/** Just a simple function that takes binary value of a chromosome and sets
the fitnes.
@param _chrom A binary chromosome
*/
// INIT
double binary_value(const std::vector<bool>& _chrom)
{
double sum = 0;
for (unsigned i = 0; i < _chrom.size(); i++)
sum += _chrom[i];
return sum;
}

View file

@ -0,0 +1,404 @@
//-----------------------------------------------------------------------------
// SecondBitGA.cpp
//-----------------------------------------------------------------------------
//*
// Same code than FirstBitEA as far as Evolutionary Computation is concerned
// but now you learn to enter the parameters in a more flexible way
// and to twidle the output to your preferences!
//-----------------------------------------------------------------------------
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
// standard includes
#include <fstream>
#include <iostream> // cout
#include <stdexcept> // runtime_error
// the general include for eo
#include <eo>
// EVAL
#include "binary_value.h"
// REPRESENTATION
//-----------------------------------------------------------------------------
// Include the corresponding file
#include <ga.h> // bitstring representation & operators
// define your genotype and fitness types
typedef eoBit<eoMinimizingFitness> Indi;
using namespace std;
// the main_function: nothing changed(!), except variable initialization
void main_function(int argc, char **argv)
{
// PARAMETRES
//-----------------------------------------------------------------------------
// instead of having all values of useful parameters as constants, read them:
// either on the command line (--option=value or -o=value)
// or in a parameter file (same syntax, order independent,
// # = usual comment character
// or in the environment (TODO)
// First define a parser from the command-line arguments
eoParser parser(argc, argv);
// For each parameter, define Parameter, read it through the parser,
// and assign the value to the variable
eoValueParam<uint32_t> seedParam(time(0), "seed", "Random number seed", 'S');
parser.processParam( seedParam );
unsigned seed = seedParam.value();
// description of genotype
eoValueParam<unsigned int> vecSizeParam(100, "vecSize", "Genotype size",'V');
parser.processParam( vecSizeParam, "Representation" );
unsigned vecSize = vecSizeParam.value();
// parameters for evolution engine
eoValueParam<unsigned int> popSizeParam(100, "popSize", "Population size",'P');
parser.processParam( popSizeParam, "Evolution engine" );
unsigned popSize = popSizeParam.value();
eoValueParam<unsigned int> tSizeParam(10, "tSize", "Tournament size",'T');
parser.processParam( tSizeParam, "Evolution Engine" );
unsigned tSize = tSizeParam.value();
// init and stop
eoValueParam<string> loadNameParam("", "Load","A save file to restart from",'L');
parser.processParam( loadNameParam, "Persistence" );
string loadName = loadNameParam.value();
eoValueParam<unsigned int> maxGenParam(500, "maxGen", "Maximum number of generations",'G');
parser.processParam( maxGenParam, "Stopping criterion" );
unsigned maxGen = maxGenParam.value();
eoValueParam<unsigned int> minGenParam(500, "minGen", "Minimum number of generations",'g');
parser.processParam( minGenParam, "Stopping criterion" );
unsigned minGen = minGenParam.value();
eoValueParam<unsigned int> steadyGenParam(100, "steadyGen", "Number of generations with no improvement",'s');
parser.processParam( steadyGenParam, "Stopping criterion" );
unsigned steadyGen = steadyGenParam.value();
// operators probabilities at the algorithm level
eoValueParam<double> pCrossParam(0.6, "pCross", "Probability of Crossover", 'C');
parser.processParam( pCrossParam, "Genetic Operators" );
double pCross = pCrossParam.value();
eoValueParam<double> pMutParam(0.1, "pMut", "Probability of Mutation", 'M');
parser.processParam( pMutParam, "Genetic Operators" );
double pMut = pMutParam.value();
// relative rates for crossovers
eoValueParam<double> onePointRateParam(1, "onePointRate", "Relative rate for one point crossover", '1');
parser.processParam( onePointRateParam, "Genetic Operators" );
double onePointRate = onePointRateParam.value();
eoValueParam<double> twoPointsRateParam(1, "twoPointRate", "Relative rate for two point crossover", '2');
parser.processParam( twoPointsRateParam, "Genetic Operators" );
double twoPointsRate = twoPointsRateParam.value();
eoValueParam<double> uRateParam(2, "uRate", "Relative rate for uniform crossover", 'U');
parser.processParam( uRateParam, "Genetic Operators" );
double URate = uRateParam.value();
// relative rates and private parameters for mutations;
eoValueParam<double> pMutPerBitParam(0.01, "pMutPerBit", "Probability of flipping 1 bit in bit-flip mutation", 'b');
parser.processParam( pMutPerBitParam, "Genetic Operators" );
double pMutPerBit = pMutPerBitParam.value();
eoValueParam<double> bitFlipRateParam(0.01, "bitFlipRate", "Relative rate for bit-flip mutation", 'B');
parser.processParam( bitFlipRateParam, "Genetic Operators" );
double bitFlipRate = bitFlipRateParam.value();
eoValueParam<double> oneBitRateParam(0.01, "oneBitRate", "Relative rate for deterministic bit-flip mutation", 'D');
parser.processParam( oneBitRateParam, "Genetic Operators" );
double oneBitRate = oneBitRateParam.value();
// the name of the "status" file where all actual parameter values will be saved
string str_status = parser.ProgramName() + ".status"; // default value
eoValueParam<string> statusParam(str_status.c_str(), "status","Status file",'S');
parser.processParam( statusParam, "Persistence" );
// do the following AFTER ALL PARAMETERS HAVE BEEN PROCESSED
// i.e. in case you need parameters somewhere else, postpone these
if (parser.userNeedsHelp())
{
parser.printHelp(cout);
exit(1);
}
if (statusParam.value() != "")
{
ofstream os(statusParam.value().c_str());
os << parser; // and you can use that file as parameter file
}
// EVAL
/////////////////////////////
// Fitness function
////////////////////////////
// Evaluation: from a plain C++ fn to an EvalFunc Object ...
eoEvalFuncPtr<Indi, double, const vector<bool>& > plainEval( binary_value );
// ... to an object that counts the nb of actual evaluations
eoEvalFuncCounter<Indi> eval(plainEval);
// INIT
////////////////////////////////
// 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<bool> uGen;
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
// OUTPUT
// sort pop for pretty printout
// pop.sort();
// Print (sorted) intial population (raw printout)
cout << "Initial Population" << endl << pop ;
cout << "and best is " << pop.best_element() << "\n\n";
cout << "and worse is " << pop.worse_element() << "\n\n";
// ENGINE
/////////////////////////////////////
// selection and replacement
////////////////////////////////////
// SELECT
// The robust tournament selection
eoDetTournamentSelect<Indi> selectOne(tSize); // tSize in [2,POPSIZE]
// is now encapsulated in a eoSelectPerc (entage)
eoSelectPerc<Indi> select(selectOne);// by default rate==1
// REPLACE
// And we now have the full slection/replacement - though with
// generational replacement at the moment :-)
eoGenerationalReplacement<Indi> replace;
// want to add (weak) elitism? easy!
// rename the eoGenerationalReplacement replace_main,
// then encapsulate it in the elitist replacement
// eoWeakElitistReplacement<Indi> replace(replace_main);
// OPERATORS
//////////////////////////////////////
// The variation operators
//////////////////////////////////////
// CROSSOVER
// 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);
// MUTATION
// 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);
// STOP
//////////////////////////////////////
// termination condition see FirstBitEA.cpp
/////////////////////////////////////
eoGenContinue<Indi> genCont(maxGen);
eoSteadyFitContinue<Indi> steadyCont(minGen, steadyGen);
// eoFitContinue<Indi> fitCont(vecSize); // remove if minimizing :-)
eoCombinedContinue<Indi> continuator(genCont);
continuator.add(steadyCont);
// continuator.add(fitCont);
// Ctrl C signal handling: don't know if that works in MSC ...
#ifndef _MSC_VER
eoCtrlCContinue<Indi> ctrlC;
continuator.add(ctrlC);
#endif
// CHECKPOINT
// but now you want to make many different things every generation
// (e.g. statistics, plots, ...).
// the class eoCheckPoint is dedicated to just that:
// Declare a checkpoint (from a continuator: an eoCheckPoint
// IS AN eoContinue and will be called in the loop of all algorithms)
eoCheckPoint<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;
eoAverageStat<Indi> averageStat;
// Second moment stats: average and stdev
eoSecondMomentStats<Indi> SecondStat;
// the Fitness Distance Correlation
// need first an object to compute the distances
eoQuadDistance<Indi> dist; // Hamming distance
eoFDCStat<Indi> fdcStat(dist);
// Add them to the checkpoint to get them called at the appropriate time
checkpoint.add(bestStat);
checkpoint.add(averageStat);
checkpoint.add(SecondStat);
checkpoint.add(fdcStat);
// 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);
monitor.add(fdcStat);
// test de eoPopStat and/or eoSortedPopStat.
// Dumps the whole pop every 10 gen.
// eoSortedPopStat<Indi> popStat(10, "Dump of whole population");
// eoPopStat<Indi> popStat(10, "Dump of whole population");
// checkpoint.add(popStat);
// monitor.add(popStat);
// A file monitor: will print parameters to ... a File, yes, you got it!
eoFileMonitor fileMonitor("stats.xg", " ");
// the checkpoint mechanism can handle monitors
checkpoint.add(fileMonitor);
// the fileMonitor can monitor parameters, too, but you must tell it!
fileMonitor.add(generationCounter);
fileMonitor.add(bestStat);
fileMonitor.add(SecondStat);
#ifndef _MSC_VER
// and an eoGnuplot1DMonitor will 1-print to a file, and 2- plot on screen
eoGnuplot1DMonitor gnuMonitor("best_average.xg",minimizing_fitness<Indi>());
// the checkpoint mechanism can handle multiple monitors
checkpoint.add(gnuMonitor);
// the gnuMonitor can monitor parameters, too, but you must tell it!
gnuMonitor.add(eval);
gnuMonitor.add(bestStat);
gnuMonitor.add(averageStat);
// send a scaling command to gnuplot
gnuMonitor.gnuplotCommand("set yrange [0:500]");
// a specific plot monitor for FDC
// first into a file (it adds everything ti itself
eoFDCFileSnapshot<Indi> fdcFileSnapshot(fdcStat);
// then to a Gnuplot monitor
eoGnuplot1DSnapshot fdcGnuplot(fdcFileSnapshot);
// and of coruse add them to the checkPoint
checkpoint.add(fdcFileSnapshot);
checkpoint.add(fdcGnuplot);
// want to see how the fitness is spread?
eoScalarFitnessStat<Indi> fitStat;
checkpoint.add(fitStat);
// a gnuplot-based monitor for snapshots: needs a dir name
// where to store the files
eoGnuplot1DSnapshot fitSnapshot("Fitnesses");
// add any stat that is a vector<double> to it
fitSnapshot.add(fitStat);
// and of course add it to the checkpoint
checkpoint.add(fitSnapshot);
#endif
// Last type of item the eoCheckpoint can handle: state savers:
eoState outState;
// Register the algorithm into the state (so it has something to save!!)
outState.registerObject(rng);
outState.registerObject(pop);
// and feed the state to state savers
// save state every 100th generation
eoCountedStateSaver stateSaver1(100, outState, "generation");
// save state every 1 seconds
eoTimedStateSaver stateSaver2(1, outState, "time");
// Don't forget to add the two savers to the checkpoint
checkpoint.add(stateSaver1);
checkpoint.add(stateSaver2);
// and that's it for the (control and) output
// GENERATION
/////////////////////////////////////////
// the algorithm
////////////////////////////////////////
// Easy EA requires
// selection, transformation, eval, replacement, and stopping criterion
eoEasyEA<Indi> gga(checkpoint, eval, select, transform, replace);
// Apply algo to pop - that's it!
gga(pop);
// OUTPUT
// Print (sorted) intial population
pop.sort();
cout << "FINAL Population\n" << pop << endl;
// GENERAL
}
// A main that catches the exceptions
int main(int argc, char **argv)
{
try
{
main_function(argc, argv);
}
catch(exception& e)
{
cout << "Exception: " << e.what() << '\n';
}
return 1;
}

View file

@ -0,0 +1,20 @@
#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
*/
// INIT
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;
}

View file

@ -0,0 +1 @@
Makefile.in

View file

@ -0,0 +1,95 @@
#include <iostream>
#include <ga/make_ga.h>
#include <apply.h>
// EVAL
#include "binary_value.h"
// GENERAL
using namespace std;
int main(int argc, char* argv[])
{
try
{
// REPRESENTATION
//-----------------------------------------------------------------------------
// define your genotype and fitness types
typedef eoBit<double> EOT;
// PARAMETRES
eoParser parser(argc, argv); // for user-parameter reading
// GENERAL
eoState state; // keeps all things allocated
///// FIRST, problem or representation dependent stuff
//////////////////////////////////////////////////////
// EVAL
// The evaluation fn - encapsulated into an eval counter for output
eoEvalFuncPtr<EOT, double> mainEval( binary_value<EOT> );
eoEvalFuncCounter<EOT> eval(mainEval);
// REPRESENTATION
// the genotype - through a genotype initializer
eoInit<EOT>& init = make_genotype(parser, state, EOT());
// if you want to do sharing, you'll need a distance.
// here Hamming distance
eoHammingDistance<EOT> dist;
// OPERATORS
// Build the variation operator (any seq/prop construct)
eoGenOp<EOT>& op = make_op(parser, state, init);
// GENERAL
//// 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);
// STOP
// stopping criteria
eoContinue<EOT> & term = make_continue(parser, state, eval);
// output
eoCheckPoint<EOT> & checkpoint = make_checkpoint(parser, state, eval, term);
// GENERATION
// algorithm (need the operator!)
eoAlgo<EOT>& ga = make_algo_scalar(parser, state, eval, checkpoint, op, &dist);
///// End of construction of the algorith
/////////////////////////////////////////
// PARAMETRES
// to be called AFTER all parameters have been read!!!
make_help(parser);
//// GO
///////
// EVAL
// evaluate intial population AFTER help and status in case it takes time
apply<EOT>(eval, pop);
// STOP
// print it out (sort witout modifying)
cout << "Initial Population\n";
pop.sortedPrintOn(cout);
cout << endl;
// GENERATION
run_ea(ga, pop); // run the ga
// STOP
// print it out (sort witout modifying)
cout << "Final Population\n";
pop.sortedPrintOn(cout);
cout << endl;
// GENERAL
}
catch(exception& e)
{
cout << e.what() << endl;
}
}

View file

@ -0,0 +1,11 @@
/.cvsignore/1.1/Fri Sep 17 16:53:13 2004//
/BitEA.cpp/1.4/Tue May 25 08:03:30 2004//
/ESEA.cpp/1.4/Thu Jan 17 17:51:58 2002//
/ESEA.param/1.1/Mon Dec 27 07:59:58 2004//
/Makefile.am/1.4/Wed Sep 28 21:49:25 2005//
/Makefile.simple/1.1/Fri Sep 17 15:20:18 2004//
/RealEA.cpp/1.2/Thu Jan 17 17:51:58 2002//
/RealEA.param/1.1/Mon Dec 27 07:59:58 2004//
/binary_value.h/1.3/Tue May 25 08:03:30 2004//
/real_value.h/1.1/Thu May 3 13:06:34 2001//
D

View file

@ -0,0 +1 @@
eo/tutorial/Lesson4

View file

@ -0,0 +1 @@
:ext:evomarc@eodev.cvs.sourceforge.net:/cvsroot/eodev

View file

@ -0,0 +1,137 @@
// Program to test several EO-ES features
#ifdef _MSC_VER
#pragma warning(disable:4786)
#endif
#include <algorithm>
#include <string>
#include <iostream>
#include <iterator>
#include <stdexcept>
#include <time.h>
using namespace std;
#include <eo>
// representation specific
#include <es/make_es.h>
#include "real_value.h" // the sphere fitness
// Now the main
///////////////
typedef eoMinimizingFitness FitT;
template <class EOT>
void runAlgorithm(EOT, eoParser& _parser, eoState& _state);
int main_function(int argc, char *argv[])
{
// Create the command-line parser
eoParser parser(argc, argv); // for user-parameter reading
eoState state; // keeps all things allocated
eoValueParam<bool>& simpleParam = parser.createParam(true, "Isotropic", "Isotropic self-adaptive mutation", 'i', "ES mutation");
eoValueParam<bool>& stdevsParam = parser.createParam(false, "Stdev", "One self-adaptive stDev per variable", 's', "ES mutation");
eoValueParam<bool>& corrParam = parser.createParam(false, "Correl", "Use correlated mutations", 'c', "ES mutation");
// Run the appropriate algorithm
if (simpleParam.value() == false)
{
cout << "Using eoReal" << endl;
runAlgorithm(eoReal<FitT>(), parser, state);
}
else if (stdevsParam.value() == false)
{
cout << "Using eoEsSimple" << endl;
runAlgorithm(eoEsSimple<FitT>(), parser, state);
}
else if (corrParam.value() == false)
{
cout << "Using eoEsStdev" << endl;
runAlgorithm(eoEsStdev<FitT>(), parser, state);
}
else
{
cout << "Using eoEsFull" << endl;
runAlgorithm(eoEsFull<FitT>(), parser, state);
}
return 0;
}
// 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;
}
/** The templatized main (sort of)
* quite similar to the main of other genotypes
* (e.g. t-eoReal and t-eoGA in test dir)
*/
template <class EOT>
void runAlgorithm(EOT, eoParser& _parser, eoState& _state)
{
typedef typename EOT::Fitness FitT;
///// FIRST, problem or representation dependent stuff
//////////////////////////////////////////////////////
// The evaluation fn - encapsulated into an eval counter for output
eoEvalFuncPtr<EOT, double, const std::vector<double>&>
mainEval( real_value );
eoEvalFuncCounter<EOT> eval(mainEval);
// the genotype - through a genotype initializer
eoRealInitBounded<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);
apply<EOT>(eval, pop);
// 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
///////
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;
}

View file

@ -0,0 +1,62 @@
###### General ######
# --help=0 # -h : Prints this message
# --stopOnUnknownParam=1 # Stop if unkown param entered
# --seed=1104133126 # -S : Random number seed
###### ES mutation ######
# --Isotropic=1 # -i : Isotropic self-adaptive mutation
# --Stdev=0 # -s : One self-adaptive stDev per variable
# --Correl=0 # -c : Use correlated mutations
###### Evolution Engine ######
--popSize=1 # -P : Population Size
--selection=Sequential # -S : Selection: DetTour(T), StochTour(t), Roulette, Ranking(p,e) or Sequential(ordered/unordered)
--nbOffspring=700% # -O : Nb of offspring (percentage or absolute)
--replacement=Comma # -R : Replacement: Comma, Plus or EPTour(T), SSGAWorst, SSGADet(T), SSGAStoch(t)
--weakElitism=0 # -w : Old best parent replaces new worst offspring *if necessary*
###### Genotype Initialization ######
# --vecSize=10 # -n : The number of variables
# --initBounds=10[-1,1] # -B : Bounds for initialization (MUST be bounded)
--sigmaInit=0.3% # -s : Initial value for Sigmas (with a '%' -> scaled by the range of each variable)
###### Output ######
# --useEval=1 # Use nb of eval. as counter (vs nb of gen.)
# --useTime=1 # Display time (s) every generation
# --printBestStat=1 # Print Best/avg/stdev every gen.
# --printPop=0 # Print sorted pop. every gen.
###### Output - Disk ######
# --resDir=Res # Directory to store DISK outputs
# --eraseDir=1 # erase files in dirName if any
# --fileBestStat=0 # Output bes/avg/std to file
###### Output - Graphical ######
# --plotBestStat=0 # Plot Best/avg Stat
# --plotHisto=0 # Plot histogram of fitnesses
###### Persistence ######
# --Load= # -L : A save file to restart from
# --recomputeFitness=0 # -r : Recompute the fitness after re-loading the pop.?
# --saveFrequency=0 # Save every F generation (0 = only final state, absent = never)
# --saveTimeInterval=0 # Save every T seconds (0 or absent = never)
# --status=t-eoESAll.status # Status file
###### Stopping criterion ######
# --maxGen=100 # -G : Maximum number of generations () = none)
# --steadyGen=100 # -s : Number of generations with no improvement
# --minGen=0 # -g : Minimum number of generations
# --maxEval=0 # -E : Maximum number of evaluations (0 = none)
# --targetFitness=0 # -T : Stop when fitness reaches
# --CtrlC=0 # -C : Terminate current generation upon Ctrl C
###### Variation Operators ######
# --objectBounds=10[-inf,+inf] # -B : Bounds for variables
# --operator=SGA # -o : Description of the operator (SGA only now)
# --pCross=1 # -C : Probability of Crossover
# --pMut=1 # -M : Probability of Mutation
# --crossType=global # -C : Type of ES recombination (global or standard)
# --crossObj=discrete # -O : Recombination of object variables (discrete, intermediate or none)
# --crossStdev=intermediate # -S : Recombination of mutation strategy parameters (intermediate, discrete or none)
# --TauLoc=1 # -l : Local Tau (before normalization)

View file

@ -0,0 +1,26 @@
noinst_PROGRAMS = BitEA RealEA ESEA
BitEA_SOURCES = BitEA.cpp
RealEA_SOURCES = RealEA.cpp
ESEA_SOURCES = ESEA.cpp
noinst_HEADERS = binary_value.h \
real_value.h
extra_DIST = Makefile.simple
AM_CXXFLAGS = -I$(top_srcdir)/src
LIBEO = $(top_builddir)/src/libeo.a
LIBES = $(top_builddir)/src/es/libes.a
LIBGA = $(top_builddir)/src/ga/libga.a
LIBUTILS = $(top_builddir)/src/utils/libeoutils.a
DEPS = $(LIBEO) $(LIBUTILS) $(LIBES) $(LIBGA)
LIBS = $(LIBES) $(LIBGA) $(LIBEO) $(LIBUTILS)

View file

@ -0,0 +1,33 @@
### This Makefile is part of the tutorial of the EO library
# Unlike other Makefiles in EO, it is not using the automake/autoconf
# so that it stays easy to understant (you are in the tutorial, remember!)
# MS, Oct. 2002
# if you use this Makefile as a starting point for another application
# you might need to modify the following
DIR_EO = ../../src
.SUFFIXES: .cpp
# Warning: $(CXX) in Linux (RedHat and Mandrake at least) is g++
# However, if you are using this Makefile within xemacs,
# and have problems with the interpretation of the output (and its colors)
# then you should use c++ instead (make CXX=c++ will do)
.cpp: ; $(CXX) -DPACKAGE=\"eo\" -DVERSION=\"0.9.3\" -I. -I$(DIR_EO) -Wall -g -o $@ $*.cpp $(DIR_EO)/utils/libeoutils.a $(DIR_EO)/libeo.a
.cpp.o: ; $(CXX) -DPACKAGE=\"eo\" -DVERSION=\"0.9.3\" -I. -I$(DIR_EO) -Wall -g -c $*.cpp
ALL = BitEA RealEA ESEA
all : $(ALL)
BitEA : BitEA.o ;
$(CXX) -DPACKAGE=\"eo\" -DVERSION=\"0.9.2\" -Wall -g -o $@ $< $(DIR_EO)/ga/libga.a $(DIR_EO)/utils/libeoutils.a $(DIR_EO)/libeo.a
RealEA : RealEA.o ; $(CXX) -DPACKAGE=\"eo\" -DVERSION=\"0.9.2\" -Wall -g -o $@ $< $(DIR_EO)/es/libes.a $(DIR_EO)/utils/libeoutils.a $(DIR_EO)/libeo.a
ESEA : ESEA.o ; $(CXX) -DPACKAGE=\"eo\" -DVERSION=\"0.9.2\" -Wall -g -o $@ $< $(DIR_EO)/es/libes.a $(DIR_EO)/utils/libeoutils.a $(DIR_EO)/libeo.a
clean :
@/bin/rm $(ALL) *.o *.sav *.xg *.status *~

View file

@ -0,0 +1,72 @@
#include <iostream>
#include <es/make_real.h>
#include "real_value.h"
#include <apply.h>
using namespace std;
int main(int argc, char* argv[])
{
try
{
typedef eoReal<eoMinimizingFitness> 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, double, const std::vector<double>&>
mainEval( real_value );
eoEvalFuncCounter<EOT> eval(mainEval);
// the genotype - through a genotype initializer
eoRealInitBounded<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>& ea = 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<EOT>(eval, pop);
// print it out
cout << "Initial Population\n";
pop.sortedPrintOn(cout);
cout << endl;
run_ea(ea, pop); // run the ea
cout << "Final Population\n";
pop.sortedPrintOn(cout);
cout << endl;
}
catch(exception& e)
{
cout << e.what() << endl;
}
}

View file

@ -0,0 +1,57 @@
###### General ######
# --help=0 # -h : Prints this message
# --stopOnUnknownParam=1 # Stop if unkown param entered
# --seed=1104133126 # -S : Random number seed
###### Evolution Engine ######
--popSize=10 # -P : Population Size
--selection=Sequential # -S : Selection: DetTour(T), StochTour(t), Roulette, Ranking(p,e) or Sequential(ordered/unordered)
--nbOffspring=700% # -O : Nb of offspring (percentage or absolute)
--replacement=Plus # -R : Replacement: Comma, Plus or EPTour(T), SSGAWorst, SSGADet(T), SSGAStoch(t)
--weakElitism=0 # -w : Old best parent replaces new worst offspring *if necessary*
###### Genotype Initialization ######
# --vecSize=10 # -n : The number of variables
# --initBounds=10[-1,1] # -B : Bounds for initialization (MUST be bounded)
--sigmaInit=0.3% # -s : Initial value for Sigmas (with a '%' -> scaled by the range of each variable)
###### Output ######
# --useEval=1 # Use nb of eval. as counter (vs nb of gen.)
# --useTime=1 # Display time (s) every generation
# --printBestStat=1 # Print Best/avg/stdev every gen.
# --printPop=0 # Print sorted pop. every gen.
###### Output - Disk ######
# --resDir=Res # Directory to store DISK outputs
# --eraseDir=1 # erase files in dirName if any
# --fileBestStat=0 # Output bes/avg/std to file
###### Output - Graphical ######
# --plotBestStat=0 # Plot Best/avg Stat
# --plotHisto=0 # Plot histogram of fitnesses
###### Persistence ######
# --Load= # -L : A save file to restart from
# --recomputeFitness=0 # -r : Recompute the fitness after re-loading the pop.?
# --saveFrequency=0 # Save every F generation (0 = only final state, absent = never)
# --saveTimeInterval=0 # Save every T seconds (0 or absent = never)
# --status=t-eoESAll.status # Status file
###### Stopping criterion ######
# --maxGen=100 # -G : Maximum number of generations () = none)
# --steadyGen=100 # -s : Number of generations with no improvement
# --minGen=0 # -g : Minimum number of generations
# --maxEval=0 # -E : Maximum number of evaluations (0 = none)
# --targetFitness=0 # -T : Stop when fitness reaches
# --CtrlC=0 # -C : Terminate current generation upon Ctrl C
###### Variation Operators ######
# --objectBounds=10[-inf,+inf] # -B : Bounds for variables
# --operator=SGA # -o : Description of the operator (SGA only now)
# --pCross=1 # -C : Probability of Crossover
# --pMut=1 # -M : Probability of Mutation
# --crossType=global # -C : Type of ES recombination (global or standard)
# --crossObj=discrete # -O : Recombination of object variables (discrete, intermediate or none)
# --crossStdev=intermediate # -S : Recombination of mutation strategy parameters (intermediate, discrete or none)
# --TauLoc=1 # -l : Local Tau (before normalization)

View file

@ -0,0 +1,25 @@
#include <eo>
//-----------------------------------------------------------------------------
/** Just a simple function that takes binary value of a chromosome and sets
the fitnes.
@param _chrom A binary chromosome
*/
template <class Chrom> double binary_value(const Chrom& _chrom)
{
double sum = 0;
for (unsigned i = 0; i < _chrom.size(); i++)
if (_chrom[i])
sum += _chrom[i];
return sum;
}
struct BinaryValue
{
template <class Chrom> void operator()(Chrom& _chrom)
{
_chrom.fitness(binary_value(_chrom));
}
};

View file

@ -0,0 +1,19 @@
#include <vector>
//-----------------------------------------------------------------------------
/** Just a simple function that takes an eoEsBase<double> and sets the fitnes
to sphere
@param _ind vector<double>
*/
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 sqrt(sum);
}

View file

@ -0,0 +1 @@
Makefile.in

View file

@ -0,0 +1,14 @@
/.cvsignore/1.1/Fri Sep 17 16:53:10 2004//
/Makefile.am/1.4/Wed Sep 28 21:49:25 2005//
/Makefile.simple/1.1/Fri Sep 17 15:20:18 2004//
/OneMaxEA.cpp/1.1/Wed May 8 06:44:04 2002//
/OneMaxLibEA.cpp/1.1/Wed May 8 06:44:04 2002//
/eoOneMax.h/1.1/Wed May 8 06:44:04 2002//
/eoOneMaxEvalFunc.h/1.1/Wed May 8 06:44:04 2002//
/eoOneMaxInit.h/1.1/Wed May 8 06:44:04 2002//
/eoOneMaxMutation.h/1.3/Mon Oct 3 09:47:06 2005//
/eoOneMaxQuadCrossover.h/1.2/Mon Oct 3 09:47:06 2005//
/make_OneMax.cpp/1.1/Wed May 8 06:44:04 2002//
/make_genotype_OneMax.h/1.1/Wed May 8 06:44:04 2002//
/make_op_OneMax.h/1.1/Wed May 8 06:44:04 2002//
D

View file

@ -0,0 +1 @@
eo/tutorial/Lesson5

View file

@ -0,0 +1 @@
:ext:evomarc@eodev.cvs.sourceforge.net:/cvsroot/eodev

View file

@ -0,0 +1,28 @@
noinst_PROGRAMS = OneMaxEA OneMaxLibEA
OneMaxEA_SOURCES = OneMaxEA.cpp
OneMaxLibEA_SOURCES = OneMaxLibEA.cpp make_OneMax.cpp
noinst_HEADERS = eoOneMax.h \
eoOneMaxEvalFunc.h \
eoOneMaxInit.h \
eoOneMaxMutation.h \
eoOneMaxQuadCrossover.h \
make_genotype_OneMax.h \
make_op_OneMax.h
extra_DIST = Makefile.simple
AM_CXXFLAGS = -I$(top_srcdir)/src
LIBEO = $(top_builddir)/src/libeo.a
LIBES = $(top_builddir)/src/es/libes.a
LIBGA = $(top_builddir)/src/ga/libga.a
LIBUTILS = $(top_builddir)/src/utils/libeoutils.a
DEPS = $(LIBEO) $(LIBUTILS) $(LIBES) $(LIBGA)
LIBS = $(LIBES) $(LIBGA) $(LIBEO) $(LIBUTILS)

View file

@ -0,0 +1,56 @@
### This Makefile is part of the tutorial of the EO library
# Unlike other Makefiles in EO, it is not using the automake/autoconf
# so that it stays easy to understant (you are in the tutorial, remember!)
# MS, Oct. 2002
# if you use this Makefile as a starting point for another application
# you might need to modify the following
DIR_EO = ../../src
.SUFFIXES: .cpp
# Warning: $(CXX) in Linux (RedHat and Mandrake at least) is g++
# However, if you are using this Makefile within xemacs,
# and have problems with the interpretation of the output (and its colors)
# then you should use c++ instead (make CXX=c++ will do)
.cpp: ; $(CXX) -DPACKAGE=\"eo\" -DVERSION=\"0.9.3\" -I. -I$(DIR_EO) -Wall -g -o $@ $*.cpp $(DIR_EO)/utils/libeoutils.a $(DIR_EO)/libeo.a
.cpp.o: ; $(CXX) -DPACKAGE=\"eo\" -DVERSION=\"0.9.3\" -I. -I$(DIR_EO) -Wall -g -c $*.cpp
# local sources
COMMON_SOURCES = eoOneMax.h \
eoOneMaxEvalFunc.h \
eoOneMaxInit.h \
eoOneMaxMutation.h \
eoOneMaxQuadCrossover.h \
make_genotype_OneMax.h \
make_op_OneMax.h
NO_LIB_SOURCES = OneMaxEA.cpp
LIB_SOURCES = OneMaxLibEA.cpp make_OneMax.cpp
SOURCES = $(COMMON_SOURCES) OneMaxEA.cpp OneMaxLibEA.cpp make_OneMax.cpp
LIB_EO = $(DIR_EO)/utils/libeoutils.a $(DIR_EO)/libeo.a
ALL = OneMaxEA OneMaxLibEA
OneMaxEA : OneMaxEA.o
$(CXX) -g -o $@ OneMaxEA.o $(DIR_EO)/utils/libeoutils.a $(DIR_EO)/libeo.a -lm
OneMaxLibEA : OneMaxLibEA.o make_OneMax.o
$(CXX) -g -o $@ OneMaxLibEA.o make_OneMax.o $(DIR_EO)/utils/libeoutils.a $(DIR_EO)/libeo.a -lm
tar : ; tar czvf OneMax.tgz *.h *.cpp Makefile
all : $(ALL)
clean : ; /bin/rm *.o $(ALL)
########## local dependencies
OneMaxEA.o : $(COMMON_SOURCES) OneMaxEA.cpp
OneMaxLibEA.o : $(COMMON_SOURCES) OneMaxLibEA.cpp
make_OneMax.o : make_OneMax.cpp eoOneMax.h

View file

@ -0,0 +1,188 @@
/** -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*-
The above line is usefulin Emacs-like editors
*/
/*
Template for creating a new representation in EO
================================================
This is the template main file.
It includes all other files that have been generated by the script create.sh
so it is the only file to compile.
In case you want to build up a separate library for your new Evolving Object,
you'll need some work - follow what's done in the src/ga dir, used in the
main file BitEA in tutorial/Lesson4 dir.
Or you can wait until we do it :-)
*/
// Miscilaneous include and declaration
#include <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 eoMaximizingFitness 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;
}

View file

@ -0,0 +1,162 @@
/** -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*-
The above line is usefulin Emacs-like editors
*/
/*
Template for creating a new representation in EO
================================================
This is the template main file for compiling after creating a
library.
See make_OneMax.cpp file.
*/
// Miscilaneous include and declaration
#include <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 - done here and NOT in make_OneMax.cpp
// because it is NOT representation independent
#include "make_genotype_OneMax.h"
eoInit<Indi> & make_genotype(eoParser& _parser, eoState&_state, Indi _eo)
{
return do_make_genotype(_parser, _state, _eo);
}
// same thing for the variation operaotrs
#include "make_op_OneMax.h"
eoGenOp<Indi>& make_op(eoParser& _parser, eoState& _state, eoInit<Indi>& _init)
{
return do_make_op(_parser, _state, _init);
}
// The representation independent routines are simply declared here
// how to initialize the population
// it IS representation independent if an eoInit is given
eoPop<Indi >& make_pop(eoParser& _parser, eoState& _state, eoInit<Indi> & _init);
// the stopping criterion
eoContinue<Indi>& make_continue(eoParser& _parser, eoState& _state, eoEvalFuncCounter<Indi> & _eval);
// outputs (stats, population dumps, ...)
eoCheckPoint<Indi>& make_checkpoint(eoParser& _parser, eoState& _state, eoEvalFuncCounter<Indi>& _eval, eoContinue<Indi>& _continue);
// evolution engine (selection and replacement)
eoAlgo<Indi>& make_algo_scalar(eoParser& _parser, eoState& _state, eoEvalFunc<Indi>& _eval, eoContinue<Indi>& _continue, eoGenOp<Indi>& _op);
// simple call to the algo. stays there for consistency reasons
// no template for that one
void run_ea(eoAlgo<Indi>& _ga, eoPop<Indi>& _pop);
// checks for help demand, and writes the status file
// and make_help; in libutils - just a declaration, code in libeoutils.a
void make_help(eoParser & _parser);
// now use all of the above, + representation dependent things
// from here on, no difference with eoOneMax.cpp
int main(int argc, char* argv[])
{
try
{
eoParser parser(argc, argv); // for user-parameter reading
eoState state; // keeps all things allocated
// The fitness
//////////////
eoOneMaxEvalFunc<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;
}

View file

@ -0,0 +1,111 @@
/** -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*-
The above line is usefulin Emacs-like editors
*/
/*
Template for creating a new representation in EO
================================================
*/
#ifndef _eoOneMax_h
#define _eoOneMax_h
/**
* Always write a comment in this format before class definition
* if you want the class to be documented by Doxygen
* Note that you MUST derive your structure from EO<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 << ' ';
// START Code of default output
/** HINTS
* in EO we systematically write the sizes of things before the things
* so readFrom is easier to code (see below)
*/
_os << b.size() << ' ' ;
for (unsigned i=0; i<b.size(); i++)
_os << b[i] << ' ' ;
// END Code of default output
}
/** reading...
* of course, your readFrom must be able to read what printOn writes!!!
*/
void readFrom(istream& _is)
{
// of course you should read the fitness first!
EO<FitT>::readFrom(_is);
// START Code of input
/** HINTS
* remember the eoOneMax object will come from the default ctor
* this is why having the sizes written out is useful
*/
unsigned s;
_is >> s;
b.resize(s);
for (unsigned i=0; i<s; i++)
{
bool bTmp;
_is >> bTmp;
b[i] = bTmp;
}
// END Code of input
}
// accessing and setting values
void setB(vector<bool> & _b)
{
b=_b;
}
const vector<bool> & B()
{
return b;
}
private: // put all data here
// START Private data of an eoOneMax object
std::vector<bool> b;
// END Private data of an eoOneMax object
};
#endif

View file

@ -0,0 +1,68 @@
/** -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*-
The above line is usefulin Emacs-like editors
*/
/*
Template for evaluator in EO, a functor that computes the fitness of an EO
==========================================================================
*/
#ifndef _eoOneMaxEvalFunc_h
#define _eoOneMaxEvalFunc_h
// include whatever general include you need
#include <stdexcept>
#include <fstream>
// include the base definition of eoEvalFunc
#include "eoEvalFunc.h"
/**
Always write a comment in this format before class definition
if you want the class to be documented by Doxygen
*/
template <class EOT>
class eoOneMaxEvalFunc : public eoEvalFunc<EOT>
{
public:
/// Ctor - no requirement
// START eventually add or modify the anyVariable argument
eoOneMaxEvalFunc()
// eoOneMaxEvalFunc( varType _anyVariable) : anyVariable(_anyVariable)
// END eventually add or modify the anyVariable argument
{
// START Code of Ctor of an eoOneMaxEvalFunc object
// END Code of Ctor of an eoOneMaxEvalFunc object
}
/** Actually compute the fitness
*
* @param EOT & _eo the EO object to evaluate
* it should stay templatized to be usable
* with any fitness type
*/
void operator()(EOT & _eo)
{
// test for invalid to avoid recomputing fitness of unmodified individuals
if (_eo.invalid())
{
double fit; // to hold fitness value
// START Code of computation of fitness of the eoOneMax object
const vector<bool> & b = _eo.B();
fit = 0;
for (unsigned i=0; i<b.size(); i++)
fit += (b[i]?0:1);
// 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

View file

@ -0,0 +1,63 @@
/** -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*-
The above line is usefulin Emacs-like editors
*/
/*
Template for EO objects initialization in EO
============================================
*/
#ifndef _eoOneMaxInit_h
#define _eoOneMaxInit_h
// include the base definition of eoInit
#include <eoInit.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 (e.g. to initialize
* atoms of an eoVector you will need an eoInit<AtomType>)
*/
template <class GenotypeT>
class eoOneMaxInit: public eoInit<GenotypeT> {
public:
/// Ctor - no requirement
// START eventually add or modify the anyVariable argument
// eoOneMaxInit()
eoOneMaxInit( unsigned _vecSize) : vecSize(_vecSize)
// END eventually add or modify the anyVariable argument
{
// START Code of Ctor of an eoOneMaxInit object
// END Code of Ctor of an eoOneMaxInit object
}
/** initialize a genotype
*
* @param _genotype generally a genotype that has been default-constructed
* whatever it contains will be lost
*/
void operator()(GenotypeT & _genotype)
{
// START Code of random initialization of an eoOneMax object
vector<bool> b(vecSize);
for (unsigned i=0; i<vecSize; i++)
b[i]=rng.flip();
_genotype.setB(b);
// 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
unsigned vecSize; // size of all bitstrings that this eoInit randomize
// varType anyVariable; // for example ...
// END Private data of an eoOneMaxInit object
};
#endif

View file

@ -0,0 +1,68 @@
/** -*- 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(true);
// 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

View file

@ -0,0 +1,70 @@
/** -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*-
The above line is usefulin Emacs-like editors
*/
/*
Template for simple quadratic crossover operators
=================================================
Quadratic crossover operators modify the both genotypes
*/
#ifndef eoOneMaxQuadCrossover_H
#define eoOneMaxQuadCrossover_H
#include <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 eoOneMaxQuadCrossover: public eoQuadOp<GenotypeT>
{
public:
/**
* Ctor - no requirement
*/
// START eventually add or modify the anyVariable argument
eoOneMaxQuadCrossover()
// eoOneMaxQuadCrossover( varType _anyVariable) : anyVariable(_anyVariable)
// END eventually add or modify the anyVariable argument
{
// START Code of Ctor of an eoOneMaxEvalFunc object
// END Code of Ctor of an eoOneMaxEvalFunc object
}
/// The class name. Used to display statistics
string className() const { return "eoOneMaxQuadCrossover"; }
/**
* eoQuad crossover - modifies both parents
* @param _genotype1 The first parent
* @param _genotype2 The second parent
*/
bool operator()(GenotypeT& _genotype1, GenotypeT & _genotype2)
{
bool oneAtLeastIsModified(true);
// START code for crossover of _genotype1 and _genotype2 objects
/** Requirement
* if (at least one genotype has been modified) // no way to distinguish
* oneAtLeastIsModified = true;
* else
* oneAtLeastIsModified = false;
*/
return oneAtLeastIsModified;
// END code for crossover of _genotype1 and _genotype2 objects
}
private:
// START Private data of an eoOneMaxQuadCrossover object
// varType anyVariable; // for example ...
// END Private data of an eoOneMaxQuadCrossover object
};
#endif

View file

@ -0,0 +1,129 @@
/** -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*-
The above line is usefulin Emacs-like editors
*/
/*
Template for creating a new representation in EO
================================================
This is the template file that llows separate compilation of
everything that is representation independant (evolution engine and
general output) for an Evolutionary Algorithm with scalar fitness.
It includes of course the definition of the genotype (eoOneMax.h) and
is written like the make_xxx.cpp files in dirs src/ga (for bitstrings)
and src/es (for real vectors).
*/
// Miscilaneous include and declaration
#include <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"
// create an initializer: this is NOT representation-independent
// and will be done in the main file
// However, should you decide to freeze that part, you could use the
// following (and remove it from the main file, of course!!!)
//------------------------------------------------------------------
// #include "make_genotype_OneMax.h"
// eoInit<eoOneMax<double>> & make_genotype(eoParser& _parser, eoState&_state, eoOneMax<double> _eo)
// {
// return do_make_genotype(_parser, _state, _eo);
// }
// eoInit<eoOneMax<eoMinimizingFitness>> & make_genotype(eoParser& _parser, eoState&_state, eoOneMax<eoMinimizingFitness> _eo)
// {
// return do_make_genotype(_parser, _state, _eo);
// }
// same thing for the variation operaotrs
//---------------------------------------
// #include "make_op_OneMax.h"
// eoGenOp<eoOneMax<double>>& make_op(eoParser& _parser, eoState& _state, eoInit<eoOneMax<double>>& _init)
// {
// return do_make_op(_parser, _state, _init);
// }
// eoGenOp<eoOneMax<eoMinimizingFitness>>& make_op(eoParser& _parser, eoState& _state, eoInit<eoOneMax<eoMinimizingFitness>>& _init)
// {
// return do_make_op(_parser, _state, _init);
// }
// The following modules use ***representation independent*** routines
// how to initialize the population
// it IS representation independent if an eoInit is given
#include <do/make_pop.h>
eoPop<eoOneMax<double> >& make_pop(eoParser& _parser, eoState& _state, eoInit<eoOneMax<double> > & _init)
{
return do_make_pop(_parser, _state, _init);
}
eoPop<eoOneMax<eoMinimizingFitness> >& make_pop(eoParser& _parser, eoState& _state, eoInit<eoOneMax<eoMinimizingFitness> > & _init)
{
return do_make_pop(_parser, _state, _init);
}
// the stopping criterion
#include <do/make_continue.h>
eoContinue<eoOneMax<double> >& make_continue(eoParser& _parser, eoState& _state, eoEvalFuncCounter<eoOneMax<double> > & _eval)
{
return do_make_continue(_parser, _state, _eval);
}
eoContinue<eoOneMax<eoMinimizingFitness> >& make_continue(eoParser& _parser, eoState& _state, eoEvalFuncCounter<eoOneMax<eoMinimizingFitness> > & _eval)
{
return do_make_continue(_parser, _state, _eval);
}
// outputs (stats, population dumps, ...)
#include <do/make_checkpoint.h>
eoCheckPoint<eoOneMax<double> >& make_checkpoint(eoParser& _parser, eoState& _state, eoEvalFuncCounter<eoOneMax<double> >& _eval, eoContinue<eoOneMax<double> >& _continue)
{
return do_make_checkpoint(_parser, _state, _eval, _continue);
}
eoCheckPoint<eoOneMax<eoMinimizingFitness> >& make_checkpoint(eoParser& _parser, eoState& _state, eoEvalFuncCounter<eoOneMax<eoMinimizingFitness> >& _eval, eoContinue<eoOneMax<eoMinimizingFitness> >& _continue)
{
return do_make_checkpoint(_parser, _state, _eval, _continue);
}
// evolution engine (selection and replacement)
#include <do/make_algo_scalar.h>
eoAlgo<eoOneMax<double> >& make_algo_scalar(eoParser& _parser, eoState& _state, eoEvalFunc<eoOneMax<double> >& _eval, eoContinue<eoOneMax<double> >& _continue, eoGenOp<eoOneMax<double> >& _op)
{
return do_make_algo_scalar(_parser, _state, _eval, _continue, _op);
}
eoAlgo<eoOneMax<eoMinimizingFitness> >& make_algo_scalar(eoParser& _parser, eoState& _state, eoEvalFunc<eoOneMax<eoMinimizingFitness> >& _eval, eoContinue<eoOneMax<eoMinimizingFitness> >& _continue, eoGenOp<eoOneMax<eoMinimizingFitness> >& _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>
void run_ea(eoAlgo<eoOneMax<double> >& _ga, eoPop<eoOneMax<double> >& _pop)
{
do_run(_ga, _pop);
}
void run_ea(eoAlgo<eoOneMax<eoMinimizingFitness> >& _ga, eoPop<eoOneMax<eoMinimizingFitness> >& _pop)
{
do_run(_ga, _pop);
}

View file

@ -0,0 +1,75 @@
// -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*-
//-----------------------------------------------------------------------------
// make_genotype.h
// (c) Maarten Keijzer, Marc Schoenauer and GeNeura Team, 2001
/*
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Contact: todos@geneura.ugr.es, http://geneura.ugr.es
Marc.Schoenauer@polytechnique.fr
mkeijzer@dhi.dk
*/
//-----------------------------------------------------------------------------
#ifndef _make_genotype_h
#define _make_genotype_h
#include <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(eoParameterLoader& _parser, eoState& _state, EOT)
{
// read any useful parameter here from the parser
// the param itself will belong to the parser (as far as memory is concerned)
// paramType & param = _parser.createParam(deafultValue, "Keyword", "Comment to appear in help and status", 'c',"Section of status file").value();
unsigned vecSize = _parser.createParam(unsigned(8), "VecSize", "Size of the bitstrings", 'v',"Representation").value();
// Then built the initializer - a pointer, stored in the eoState
eoInit<EOT>* init = new eoOneMaxInit<EOT>(vecSize);
// store in state
_state.storeFunctor(init);
// and return a reference
return *init;
}
#endif

View file

@ -0,0 +1,210 @@
// -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*-
//-----------------------------------------------------------------------------
// make_op_OneMax.h
// (c) Marc Schoenauer, Maarten Keijzer and GeNeura Team, 2001
/*
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Contact: todos@geneura.ugr.es, http://geneura.ugr.es
Marc.Schoenauer@polytechnique.fr
mkeijzer@dhi.dk
*/
//-----------------------------------------------------------------------------
#ifndef _make_op_OneMax_h
#define _make_op_OneMax_h
// the operators
#include <eoOp.h>
#include <eoGenOp.h>
#include <eoCloneOps.h>
#include <eoOpContainer.h>
// combinations of simple eoOps (eoMonOp and eoQuadOp)
#include <eoProportionalCombinedOp.h>
/** definition of mutation:
* class eoOneMaxMonop MUST derive from eoMonOp<eoOneMax>
*/
#include "eoOneMaxMutation.h"
/** definition of crossover (either as eoBinOp (2->1) or eoQuadOp (2->2):
* class eoOneMaxBinCrossover MUST derive from eoBinOp<eoOneMax>
* OR
* class eoOneMaxQuadCrossover MUST derive from eoQuadOp<eoOneMax>
*/
// #include "eoOneMaxBinOp.h"
// OR
#include "eoOneMaxQuadCrossover.h"
// also need the parser and state includes
#include <utils/eoParser.h>
#include <utils/eoState.h>
/////////////////// variation operators ///////////////
// canonical (crossover + mutation) only at the moment //
/*
* This function builds the operators that will be applied to the eoOneMax
*
* It uses a parser (to get user parameters), a state (to store the memory)
* the last parameter is an eoInit: if some operator needs some info
* about the genotypes, the init has it all (e.g. bounds, ...)
* Simply do
* EOT myEO;
* _init(myEO);
* and myEO is then an ACTUAL object
*
* As usual, the template is the complete EOT even though only the fitness
* is actually templatized here: the following only applies to eoOneMax
*/
template <class EOT>
eoGenOp<EOT> & do_make_op(eoParameterLoader& _parser, eoState& _state, eoInit<EOT>& _init)
{
// this is a temporary version, while Maarten codes the full tree-structured
// general operator input
// BTW we must leave that simple version available somehow, as it is the one
// that 90% people use!
/////////////////////////////
// Variation operators
////////////////////////////
// read crossover and mutations, combine each in a proportional Op
// and create the eoGenOp that calls crossover at rate pCross
// then mutation with rate pMut
// the crossovers
/////////////////
// here we can have eoQuadOp (2->2) only - no time for the eoBinOp case
// you can have more than one - combined in a proportional way
// first, define the crossover objects and read their rates from the parser
// A first crossover
eoQuadOp<Indi> *cross = new eoOneMaxQuadCrossover<Indi> /* (varType _anyVariable) */;
// store in the state
_state.storeFunctor(cross);
// read its relative rate in the combination
double cross1Rate = _parser.createParam(1.0, "cross1Rate", "Relative rate for crossover 1", '1', "Variation Operators").value();
// and create the combined operator with this one
eoPropCombinedQuadOp<Indi> *propXover =
new eoPropCombinedQuadOp<Indi>(*cross, cross1Rate);
// and of course stor it in the state
_state.storeFunctor(propXover);
// Optional: A second(and third, and ...) crossover
// of course you must create the corresponding classes
// and all ***MUST*** derive from eoQuadOp<Indi>
/* Uncomment if necessary - and replicate as many time as you need
cross = new eoOneMaxSecondCrossover<Indi>(varType _anyVariable);
_state.storeFunctor(cross);
double cross2Rate = _parser.createParam(1.0, "cross2Rate", "Relative rate for crossover 2", '2', "Variation Operators").value();
propXover.add(*cross, cross2Rate);
*/
// if you want some gentle output, the last one shoudl be like
// propXover.add(*cross, crossXXXRate, true);
// the mutation: same story
////////////////
// you can have more than one - combined in a proportional way
// for each mutation,
// - define the mutator object
// - read its rate from the parser
// - add it to the proportional combination
// a first mutation
eoMonOp<Indi> *mut = new eoOneMaxMutation<Indi>/* (varType _anyVariable) */;
_state.storeFunctor(mut);
// its relative rate in the combination
double mut1Rate = _parser.createParam(1.0, "mut1Rate", "Relative rate for mutation 1", '1', "Variation Operators").value();
// and the creation of the combined operator with this one
eoPropCombinedMonOp<Indi> *propMutation = new eoPropCombinedMonOp<Indi>(*mut, mut1Rate);
_state.storeFunctor(propMutation);
// Optional: A second(and third, and ...) mutation with their rates
// of course you must create the corresponding classes
// and all ***MUST*** derive from eoMonOp<Indi>
/* Uncomment if necessary - and replicate as many time as you need
mut = new eoOneMaxSecondMutation<Indi>(varType _anyVariable);
_state.storeFunctor(mut);
double mut2Rate = _parser.createParam(1.0, "mut2Rate", "Relative rate for mutation 2", '2', "Variation Operators").value();
propMutation.add(*mut, mut2Rate);
*/
// if you want some gentle output, the last one shoudl be like
// propMutation.add(*mut, mutXXXRate, true);
// end of crossover and mutation definitions
////////////////////////////////////////////
// END Modify definitions of objects by eventually add parameters
//*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
// from now on, you do not need to modify anything
// though you CAN add things to the checkpointing (see tutorial)
// now build the eoGenOp:
// to simulate SGA (crossover with proba pCross + mutation with proba pMut
// we must construct
// a sequential combination of
// with proba 1, a proportional combination of
// a QuadCopy and our crossover
// with proba pMut, our mutation
// but of course you're free to use any smart combination you could think of
// especially, if you have to use eoBinOp rather than eoQuad Op youùll have
// to modify that part
// First read the individual level parameters
eoValueParam<double>& pCrossParam = _parser.createParam(0.6, "pCross", "Probability of Crossover", 'C', "Variation Operators" );
// minimum check
if ( (pCrossParam.value() < 0) || (pCrossParam.value() > 1) )
throw runtime_error("Invalid pCross");
eoValueParam<double>& pMutParam = _parser.createParam(0.1, "pMut", "Probability of Mutation", 'M', "Variation Operators" );
// minimum check
if ( (pMutParam.value() < 0) || (pMutParam.value() > 1) )
throw runtime_error("Invalid pMut");
// the crossover - with probability pCross
eoProportionalOp<Indi> * propOp = new eoProportionalOp<Indi> ;
_state.storeFunctor(propOp);
eoQuadOp<Indi> *ptQuad = new eoQuadCloneOp<Indi>;
_state.storeFunctor(ptQuad);
propOp->add(*propXover, pCrossParam.value()); // crossover, with proba pcross
propOp->add(*ptQuad, 1-pCrossParam.value()); // nothing, with proba 1-pcross
// now the sequential
eoSequentialOp<Indi> *op = new eoSequentialOp<Indi>;
_state.storeFunctor(op);
op->add(*propOp, 1.0); // always do combined crossover
op->add(*propMutation, pMutParam.value()); // then mutation, with proba pmut
// that's it - return a reference
return *op;
}
#endif

View file

@ -0,0 +1,2 @@
SUBDIRS = Lesson1 Lesson2 Lesson3 Lesson4 Lesson5

View file

@ -0,0 +1,29 @@
SUBDIRS = Lesson1 Lesson2 Lesson3 Lesson4 Lesson5
all:
for i in $(SUBDIRS); do cd $$i && $(MAKE) all; cd ..; done
lesson1 :
cd Lesson1; make
lesson2 :
cd Lesson2; make
lesson3 :
cd Lesson3; make
lesson4 :
cd Lesson4; make
lesson5 :
cd Lesson5; make
#empty dist and distdir to let top-level 'make' do its job
dist :
distdir :
check :
clean:
for i in $(SUBDIRS); do cd $$i && $(MAKE) clean; cd ..; done

View file

@ -0,0 +1 @@
D

View file

@ -0,0 +1,3 @@
A D/Lesson1////
A D/Lesson2////
A D/Lesson3////

View file

@ -0,0 +1 @@
eo/tutorial/ParadisEO

View file

@ -0,0 +1 @@
:ext:evomarc@eodev.cvs.sourceforge.net:/cvsroot/eodev

View file

@ -0,0 +1 @@
D

View file

@ -0,0 +1 @@
eo/tutorial/ParadisEO/Lesson1

View file

@ -0,0 +1 @@
:ext:evomarc@eodev.cvs.sourceforge.net:/cvsroot/eodev

View file

@ -0,0 +1 @@
D

View file

@ -0,0 +1 @@
eo/tutorial/ParadisEO/Lesson2

View file

@ -0,0 +1 @@
:ext:evomarc@eodev.cvs.sourceforge.net:/cvsroot/eodev

View file

@ -0,0 +1 @@
D

View file

@ -0,0 +1 @@
eo/tutorial/ParadisEO/Lesson3

View file

@ -0,0 +1 @@
:ext:evomarc@eodev.cvs.sourceforge.net:/cvsroot/eodev

View file

@ -0,0 +1,13 @@
Eo Tutorial - corresponding to EO version 0.9.1+
To start the tutorial, read index.html in your favorite browser.
Many things are missing, including many solutions for the exercises,
the introduction to EC and most of the Component-based pages.
More important, all examples of this tutorial have only been tested
on a Linux computer, and the Makefile will not work with MS-Windows
systems. Any help is welcome!
Be patient ...
evoMarc

View file

@ -0,0 +1,24 @@
/EO.tpl/1.1/Fri Aug 23 16:02:02 2002//
/MakeSimple.tmpl/1.2/Tue May 25 07:57:52 2004//
/Makefile.tmpl/1.6/Wed Oct 23 04:42:07 2002//
/MyStructEA.cpp/1.5/Wed May 1 04:04:15 2002//
/MyStructLibEA.cpp/1.1/Wed May 8 06:47:50 2002//
/MyStructSEA.cpp/1.4/Wed Oct 5 21:34:19 2005//
/README/1.4/Tue May 25 07:57:52 2004//
/binCrossover.tmpl/1.3/Tue Sep 4 08:35:22 2001//
/continue.tmpl/1.2/Tue Sep 4 08:35:22 2001//
/create.sh/1.4/Wed May 8 06:47:50 2002//
/createSimple/1.2/Tue May 25 07:57:52 2004//
/eoMyStruct.tmpl/1.4/Sat Mar 22 06:39:21 2003//
/evalFunc.tmpl/1.2/Thu Oct 4 20:12:19 2001//
/init.tmpl/1.2/Sat Nov 10 06:32:05 2001//
/lessOffspringExternalSelectorGenOp.tmpl/1.3/Tue Sep 4 08:35:22 2001//
/lessOffspringSameSelectorGenOp.tmpl/1.3/Tue Sep 4 08:35:22 2001//
/make_MyStruct.cpp/1.1/Wed May 8 06:47:50 2002//
/make_genotype_MyStruct.h/1.2/Fri May 3 05:12:32 2002//
/make_op_MyStruct.h/1.1/Thu Oct 4 20:12:19 2001//
/moreOffspringGenOp.tmpl/1.3/Tue Sep 4 08:35:22 2001//
/mutation.tmpl/1.6/Mon Sep 24 05:59:13 2001//
/quadCrossover.tmpl/1.5/Sat Jun 21 06:34:00 2003//
/stat.tmpl/1.2/Thu Feb 10 09:57:28 2005//
D

View file

@ -0,0 +1 @@
eo/tutorial/Templates

View file

@ -0,0 +1 @@
:ext:evomarc@eodev.cvs.sourceforge.net:/cvsroot/eodev

View file

@ -0,0 +1,938 @@
\TEMPLATE_START// -*- mode: c++; c-indent-level: 2; c++-member-init-indent: 8; comment-column: 35; -*-
//
// (The above line is useful in Emacs-like editors)
//
//*************************************
//
// EASEA.cpp
//
// C++ file generated by AESAE-EO v0.7
//
//*************************************
//
//
// Main file for creating a new representation in EO
// =================================================
//
// This main file 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 :-)
// Miscellany includes and declarations
#include <iostream>
using namespace std;
// eo general include
#include "eo"
// real bounds (not yet in general eo include)
#include "utils/eoRealVectorBounds.h"
unsigned *pCurrentGeneration;
unsigned *pEZ_NB_GEN;
double EZ_MUT_PROB, EZ_XOVER_PROB, EZ_REPL_PERC=0.0;
int EZ_NB_GEN, EZ_POP_SIZE;
unsigned long EZ_NB_EVALUATIONS=0L;
inline int random(int b1=0, int b2=1){
return rng.random(b2-b1)+b1;
}
inline double random(double b1=0, double b2=1){
return rng.uniform(b2-b1)+b1;
}
inline float random(float b1=0, float b2=1){
return rng.uniform(b2-b1)+b1;
}
\ANALYSE_PARAMETERS
\INSERT_USER_DECLARATIONS
\INSERT_INITIALISATION_FUNCTION
// include here whatever specific files for your representation
// Basically, this should include at least the following
/** definition of representation:
* class EASEAGenome MUST derive from EO<FitT> for some fitness
*/
#include "EASEAGenome.h"
// GENOTYPE EASEAGenome ***MUST*** be templatized over the fitness
//*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
// START fitness type: double or eoMaximizingFitness if you are maximizing
// eoMinimizingFitness if you are minimizing
typedef \MINIMAXI MyFitT ; // type of fitness
// END fitness type
//*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
// Then define your EO objects using that fitness type
typedef EASEAGenome<MyFitT> Indi; // ***MUST*** derive from EO
\INSERT_USER_FUNCTIONS
/** definition of evaluation:
* class EASEAEvalFunc MUST derive from eoEvalFunc<EASEAGenome>
* and should test for validity before doing any computation
* see tutorial/Templates/evalFunc.tmpl
*/
#include "EASEAEvalFunc.h"
/** definition of initialization:
* class EASEAGenomeInit MUST derive from eoInit<EASEAGenome>
*/
#include "EASEAInit.h"
/** include all files defining variation operator classes
*/
#include "EASEAMutation.h"
#include "EASEAQuadCrossover.h"
// 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_easea.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 {
\INSERT_INIT_FCT_CALL
eoParser parser(argc, argv); // for user-parameter reading
eoState state; // keeps all things allocated
// The fitness
//////////////
EASEAEvalFunc<Indi> plainEval/* (varType _anyVariable) */;
// turn that object into an evaluation counter
eoEvalFuncCounter<Indi> eval(plainEval);
// a genotype initializer
EASEAInit<Indi> init;
// or, if you need some parameters, you might as well
// - write a constructor of the eoMyStructInit that uses a parser
// - call it from here:
// eoEASEAInit<Indi> init(parser);
// Build the variation operator (any seq/prop construct)
// here, a simple example with only 1 crossover (2->2, a QuadOp) and
// one mutation, is given.
// Hints to have choice among multiple crossovers and mutations are given
// A (first) crossover (possibly use the parser in its Ctor)
EASEAQuadCrossover<Indi> cross /* (eoParser parser) */;
// IF MORE THAN ONE:
// read its relative rate in the combination
// double cross1Rate = parser.createParam(1.0, "cross1Rate", "Relative rate for crossover 1", '1', "Variation Operators").value();
// create the combined operator with the first one (rename it cross1 !!!)
// eoPropCombinedQuadOp<Indi> cross(cross1, cross1Rate);
// and as many as you want the following way:
// 1- write the new class by mimicking eoEASEAQuadCrossover.h
// 2- include that file here together with eoEASEAQuadCrossover above
// 3- uncomment and duplicate the following lines:
//
// eoEASEASecondCrossover<Indi> cross2(eoParser parser);
// double cross2Rate = parser.createParam(1.0, "cross2Rate", "Relative rate for crossover 2", '2', "Variation Operators").value();
// cross.add(cross2, cross2Rate);
// NOTE: if you want some gentle output, the last one shoudl be like
// cross.add(cross, crossXXXRate, true);
/////////////// Same thing for MUTATION
// a (first) mutation (possibly use the parser in its Ctor)
EASEAMutation<Indi> mut /* (eoParser parser) */;
// IF MORE THAN ONE:
// read its relative rate in the combination
// double mut1Rate = parser.createParam(1.0, "mut1Rate", "Relative rate for mutation 1", '1', "Variation Operators").value();
// create the combined operator with the first one (rename it cross1 !!!)
// eoPropCombinedMonOp<Indi> mut(mut1, mut1Rate);
// and as many as you want the following way:
// 1- write the new class by mimicking eoEASEAMutation.h
// 2- include that file here together with eoEASEAMutation above
// 3- uncomment and duplicate the following lines:
//
// eoEASEASecondMutation<Indi> mut2(eoParser parser);
// double mut2Rate = parser.createParam(1.0, "mut2Rate", "Relative rate for mutation 2", '2', "Variation Operators").value();
// mut.add(mut2, mut2Rate);
// NOTE: if you want some gentle output, the last one shoudl be like
// mut.add(mut, mutXXXRate, true);
// now encapsulate your crossover(s) and mutation(s) into an eoGeneralOp
// so you can fully benefit of the existing evolution engines
// First read the individual level parameters
double pCross = parser.createParam(0.6, "pCross", "Probability of Crossover", 'C', "Variation Operators" ).value();
// minimum check
if ( (pCross < 0) || (pCross > 1) )
throw runtime_error("Invalid pCross");
double pMut = parser.createParam(0.1, "pMut", "Probability of Mutation", 'M', "Variation Operators" ).value();
// minimum check
if ( (pMut < 0) || (pMut > 1) )
throw runtime_error("Invalid pMut");
// now create the generalOp
eoSGAGenOp<Indi> op(cross, pCross, mut, pMut);
//// Now the representation-independent things
//
// YOU SHOULD NOT NEED TO MODIFY ANYTHING BEYOND THIS POINT
// unless you want to add specific statistics to the checkpoint
//////////////////////////////////////////////
// initialize the population
// yes, this is representation indepedent once you have an eoInit
eoPop<Indi>& pop = make_pop(parser, state, init);
// give popSize to AESAE control
EZ_POP_SIZE = pop.size();
// 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 << "Best individual in final population\n";
cout << pop.best_element() << endl;
}
catch(exception& e)
{
cout << e.what() << endl;
}
return 0;
}
\START_EO_GENOME_H_TPL// -*- mode: c++; c-indent-level: 2; c++-member-init-indent: 8; comment-column: 35; -*-
//
// (The above line is useful in Emacs-like editors)
//
//*************************************
//
// EASEAGenome.h
//
// C++ file generated by AESAE-EO v0.7
//
//*************************************
//
#ifndef _EASEAGenome_h
#define _EASEAGenome_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
*/
\ANALYSE_USER_CLASSES
\INSERT_USER_CLASSES
template< class FitT>
class EASEAGenome: public EO<FitT> {
public:
/** Ctor: you MUST provide a default ctor.
* though such individuals will generally be processed
* by some eoInit object
*/
EASEAGenome() : EO<FitT>()
{
// START Code of default Ctor of an EASEAGenome object
\GENOME_CTOR
// END Code of default Ctor of an EASEAGenome object
}
EASEAGenome(const EASEAGenome & arg) : EO<FitT>()
{
\GENOME_CTOR
copy(arg);
}
virtual ~EASEAGenome()
{
// START Code of Destructor of an EASEAGenome object
\GENOME_DTOR
// END Code of Destructor of an EASEAGenome object
}
virtual string className() const { return "EASEAGenome"; }
EASEAGenome& operator=(const EASEAGenome & arg) {
copy(arg);
return *this;
}
void copy(const EASEAGenome& genome)
{
if(&genome != this){
\GENOME_DTOR
\COPY_CTOR
if (genome.invalid()) { // copying an invalid genome
fitness(FitT()); // put a valid value (i.e. non NAN)
invalidate(); // but INVALIDATE the genome
}
else
fitness(genome.fitness());
}
}
bool operator==(const EASEAGenome & genome) const {
\EQUAL
return true;
}
bool operator!=(const EASEAGenome & genome) const {
return !(*this==genome);
}
/** printing... */
void printOn(ostream& os) const
{
// First write the fitness
EO<FitT>::printOn(os);
os << ' ';
// START Code of default output
/** HINTS
* in EO we systematically write the sizes of things before the things
* so readFrom is easier to code (see below)
*/
\INSERT_DISPLAY
\WRITE
// END Code of default output
}
/** reading...
* of course, your readFrom must be able to read what printOn writes!!!
*/
void readFrom(istream& is)
{
// of course you should read the fitness first!
EO<FitT>::readFrom(is);
// START Code of input
/** HINTS
* remember the EASEAGenome object will come from the default ctor
* this is why having the sizes written out is useful
*/
\READ
// END Code of input
}
//private: // put all data here - no privacy in EASEA
// START Private data of an EASEAGenome object
\INSERT_GENOME
// END Private data of an EASEAGenome object
};
#endif
\START_EO_EVAL_TPL// -*- mode: c++; c-indent-level: 2; c++-member-init-indent: 8; comment-column: 35; -*-
//
// (The above line is useful in Emacs-like editors)
//
//*************************************
//
// EASEAEvalFunc.h
//
// C++ file generated by AESAE-EO v0.7
//
//*************************************
//
/*
Evaluator in EO: a functor that computes the fitness of an EO
=============================================================
*/
#ifndef _EASEAEvalFunc_h
#define _EASEAEvalFunc_h
// include whatever general include you need
#include <stdexcept>
#include <fstream>
// include the base definition of eoEvalFunc
#include "eoEvalFunc.h"
/**
Always write a comment in this format before class definition
if you want the class to be documented by Doxygen
*/
template <class EOT>
class EASEAEvalFunc : public eoEvalFunc<EOT>
{
public:
/// Ctor - no requirement
// START eventually add or modify the anyVariable argument
EASEAEvalFunc()
// EASEAEvalFunc( varType _anyVariable) : anyVariable(_anyVariable)
// END eventually add or modify the anyVariable argument
{
// START Code of Ctor of an EASEAEvalFunc object
// END Code of Ctor of an EASEAEvalFunc object
}
/** Actually compute the fitness
*
* @param EOT & _eo the EO object to evaluate
* it should stay templatized to be usable
* with any fitness type
*/
void operator()(EOT & genome)
{
// test for invalid to avoid recomputing fitness of unmodified individuals
if (genome.invalid())
{
// START Code of computation of fitness of the EASEA object
\INSERT_EVALUATOR
// END Code of computation of fitness of the EASEA object
}
}
private:
// START Private data of an EASEAEvalFunc object
// varType anyVariable; // for example ...
// END Private data of an EASEAEvalFunc object
};
#endif
\START_EO_INITER_TPL// -*- mode: c++; c-indent-level: 2; c++-member-init-indent: 8; comment-column: 35; -*-
//
// (The above line is useful in Emacs-like editors)
//
//*************************************
//
// EASEAInit.h
//
// C++ file generated by AESAE-EO v0.7
//
//*************************************
//
/*
objects initialization in EO
============================
*/
#ifndef _EASEAInit_h
#define _EASEAInit_h
// include the base definition of eoInit
#include <eoInit.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 (e.g. to initialize
* atoms of an eoVector you will need an eoInit<AtomType>)
*/
template <class GenotypeT>
class EASEAInit: public eoInit<GenotypeT> {
public:
/// Ctor - no requirement
// START eventually add or modify the anyVariable argument
EASEAInit()
// EASEAInit( varType & _anyVariable) : anyVariable(_anyVariable)
// END eventually add or modify the anyVariable argument
{
// START Code of Ctor of an EASEAInit object
// END Code of Ctor of an EASEAInit object
}
/** initialize a genotype
*
* @param _genotype generally a genotype that has been default-constructed
* whatever it contains will be lost
*/
void operator()(GenotypeT & _genotype)
{
// START Code of random initialization of an EASEAGenome object
\INSERT_EO_INITIALISER
// END Code of random initialization of an EASEAGenome object
_genotype.invalidate(); // IMPORTANT in case the _genotype is old
}
private:
// START Private data of an EASEAInit object
// varType & anyVariable; // for example ...
// END Private data of an EASEAInit object
};
#endif
\START_EO_MUT_TPL// -*- mode: c++; c-indent-level: 2; c++-member-init-indent: 8; comment-column: 35; -*-
//
// (The above line is useful in Emacs-like editors)
//
//*************************************
//
// EASEAMutation.h
//
// C++ file generated by AESAE-EO v0.7
//
//*************************************
//
/*
simple mutation operators
=========================
*/
#ifndef EASEAMutation_H
#define EASEAMutation_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 EASEAMutation: public eoMonOp<GenotypeT>
{
public:
/**
* Ctor - no requirement
*/
// START eventually add or modify the anyVariable argument
EASEAMutation()
// EASEAMutation( varType _anyVariable) : anyVariable(_anyVariable)
// END eventually add or modify the anyVariable argument
{
// START Code of Ctor of an EASEAMutation object
// END Code of Ctor of an EASEAMutation object
}
/// The class name. Used to display statistics
string className() const { return "EASEAMutation"; }
/**
* modifies the parent
* @param _genotype The parent genotype (will be modified)
*/
bool operator()(GenotypeT & _genotype)
{
// START code for mutation of the _genotype object
\INSERT_MUTATOR
// END code for mutation of the _genotype object
private:
// START Private data of an EASEAMutation object
// varType anyVariable; // for example ...
// END Private data of an EASEAMutation object
};
#endif
\START_EO_QUAD_XOVER_TPL// -*- mode: c++; c-indent-level: 2; c++-member-init-indent: 8; comment-column: 35; -*-
//
// (The above line is useful in Emacs-like editors)
//
//*************************************
//
// EASEAQuadCrossover.h
//
// C++ file generated by AESAE-EO v0.7
//
//*************************************
//
/*
Template for simple quadratic crossover operators
=================================================
Quadratic crossover operators modify both genotypes
*/
#ifndef EASEAQuadCrossover_H
#define EASEAQuadCrossover_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 EASEAQuadCrossover: public eoQuadOp<GenotypeT>
{
public:
/**
* Ctor - no requirement
*/
// START eventually add or modify the anyVariable argument
EASEAQuadCrossover()
// EASEAQuadCrossover( varType _anyVariable) : anyVariable(_anyVariable)
// END eventually add or modify the anyVariable argument
{
// START Code of Ctor of an EASEAQuadCrossover object
// END Code of Ctor of an EASEAQuadCrossover object
}
/// The class name. Used to display statistics
string className() const { return "EASEAQuadCrossover"; }
/**
* eoQuad crossover - modifies both genotypes
*/
bool operator()(GenotypeT& child1, GenotypeT & child2)
{
GenotypeT parent1(child1);
GenotypeT parent2(child2);
// START code for crossover of child1 and child2 objects
\INSERT_CROSSOVER
return (parent1!=child1)||(parent2!=child2);
// END code for crossover of child1 and child2 objects
}
private:
// START Private data of an EASEAQuadCrossover object
// varType anyVariable; // for example ...
// END Private data of an EASEAQuadCrossover object
};
#endif
\START_EO_CONTINUE_TPL// -*- mode: c++; c-indent-level: 2; c++-member-init-indent: 8; comment-column: 35; -*-
//
// (The above line is useful in Emacs-like editors)
//
//*************************************
//
// EASEA_make_continue.h
//
// C++ file generated by AESAE-EO v0.7
//
//*************************************
//
#ifndef _make_continue_h
#define _make_continue_h
/*
Contains the templatized version of parser-based choice of stopping criterion
It can then be instantiated, and compiled on its own for a given EOType
(see e.g. in dir ga, ga.cpp)
*/
// Continuators - all include eoContinue.h
#include <eoCombinedContinue.h>
#include <eoGenContinue.h>
#include <eoSteadyFitContinue.h>
#include <eoEvalContinue.h>
#include <eoFitContinue.h>
#ifndef _MSC_VER
#include <eoCtrlCContinue.h> // CtrlC handling (using 2 global variables!)
#endif
// also need the parser and param includes
#include <utils/eoParser.h>
#include <utils/eoState.h>
/////////////////// the stopping criterion ////////////////
template <class Indi>
eoCombinedContinue<Indi> * make_combinedContinue(eoCombinedContinue<Indi> *_combined, eoContinue<Indi> *_cont)
{
if (_combined) // already exists
_combined->add(*_cont);
else
_combined = new eoCombinedContinue<Indi>(*_cont);
return _combined;
}
template <class Indi>
eoContinue<Indi> & do_make_continue(eoParser& _parser, eoState& _state, eoEvalFuncCounter<Indi> & _eval)
{
//////////// Stopping criterion ///////////////////
// the combined continue - to be filled
eoCombinedContinue<Indi> *continuator = NULL;
// for each possible criterion, check if wanted, otherwise do nothing
// First the eoGenContinue - need a default value so you can run blind
// but we also need to be able to avoid it <--> 0
eoValueParam<unsigned>& maxGenParam = _parser.createParam(\NB_GEN, "maxGen", "Maximum number of generations () = none)",'G',"Stopping criterion");
// and give control to EASEA
EZ_NB_GEN = maxGenParam.value();
pEZ_NB_GEN = & maxGenParam.value();
// do not test for positivity in EASEA
// if (maxGenParam.value()) // positive: -> define and store
// {
eoGenContinue<Indi> *genCont = new eoGenContinue<Indi>(maxGenParam.value());
_state.storeFunctor(genCont);
// and "add" to combined
continuator = make_combinedContinue<Indi>(continuator, genCont);
// }
// the steadyGen continue - only if user imput
eoValueParam<unsigned>& steadyGenParam = _parser.createParam(unsigned(100), "steadyGen", "Number of generations with no improvement",'s', "Stopping criterion");
eoValueParam<unsigned>& minGenParam = _parser.createParam(unsigned(0), "minGen", "Minimum number of generations",'g', "Stopping criterion");
if (_parser.isItThere(steadyGenParam))
{
eoSteadyFitContinue<Indi> *steadyCont = new eoSteadyFitContinue<Indi>
(minGenParam.value(), steadyGenParam.value());
// store
_state.storeFunctor(steadyCont);
// add to combinedContinue
continuator = make_combinedContinue<Indi>(continuator, steadyCont);
}
// Same thing with Eval - but here default value is 0
eoValueParam<unsigned long>& maxEvalParam = _parser.createParam((unsigned long)0, "maxEval", "Maximum number of evaluations (0 = none)",'E',"Stopping criterion");
if (maxEvalParam.value()) // positive: -> define and store
{
eoEvalContinue<Indi> *evalCont = new eoEvalContinue<Indi>(_eval, maxEvalParam.value());
_state.storeFunctor(evalCont);
// and "add" to combined
continuator = make_combinedContinue<Indi>(continuator, evalCont);
}
/*
// the steadyEval continue - only if user imput
eoValueParam<unsigned>& steadyGenParam = _parser.createParam(unsigned(100), "steadyGen", "Number of generations with no improvement",'s', "Stopping criterion");
eoValueParam<unsigned>& minGenParam = _parser.createParam(unsigned(0), "minGen", "Minimum number of generations",'g', "Stopping criterion");
if (_parser.isItThere(steadyGenParam))
{
eoSteadyGenContinue<Indi> *steadyCont = new eoSteadyFitContinue<Indi>
(minGenParam.value(), steadyGenParam.value());
// store
_state.storeFunctor(steadyCont);
// add to combinedContinue
continuator = make_combinedContinue<Indi>(continuator, steadyCont);
}
*/
// the target fitness
eoFitContinue<Indi> *fitCont;
eoValueParam<double>& targetFitnessParam = _parser.createParam(double(0.0), "targetFitness", "Stop when fitness reaches",'T', "Stopping criterion");
if (_parser.isItThere(targetFitnessParam))
{
fitCont = new eoFitContinue<Indi>
(targetFitnessParam.value());
// store
_state.storeFunctor(fitCont);
// add to combinedContinue
continuator = make_combinedContinue<Indi>(continuator, fitCont);
}
#ifndef _MSC_VER
// the CtrlC interception (Linux only I'm afraid)
eoCtrlCContinue<Indi> *ctrlCCont;
eoValueParam<bool>& ctrlCParam = _parser.createParam(false, "CtrlC", "Terminate current generation upon Ctrl C",'C', "Stopping criterion");
if (_parser.isItThere(ctrlCParam))
{
ctrlCCont = new eoCtrlCContinue<Indi>;
// store
_state.storeFunctor(ctrlCCont);
// add to combinedContinue
continuator = make_combinedContinue<Indi>(continuator, ctrlCCont);
}
#endif
// now check that there is at least one!
if (!continuator)
throw runtime_error("You MUST provide a stopping criterion");
// OK, it's there: store in the eoState
_state.storeFunctor(continuator);
// and return
return *continuator;
}
#endif
\START_EO_PARAM_TPL#*************************************
#
# EASEA.prm
#
# Parameter file generated by AESAE-EO v0.7
#
#*************************************
###### General ######
# --help=0 # -h : Prints this message
# --stopOnUnknownParam=1 # Stop if unknown param entered
--seed=0 # -S : Random number seed
###### Evolution Engine ######
--popSize=\POP_SIZE # -P : Population Size
--selection=\SELECTOR\SELECT_PRM # -S : Selection: Roulette, Ranking(p,e), DetTour(T), StochTour(t) or Sequential(ordered/unordered)
--nbOffspring=\OFF_SIZE # -O : Nb of offspring (percentage or absolute)
--replacement=General # Type of replacement: Generational, ESComma, ESPlus, SSGA(T), EP(T)
###### Evolution Engine / Replacement ######
--elite=\ELITE_SIZE # Nb of elite parents (percentage or absolute)
--eliteType=\ELITISM # Strong (true) or weak (false) elitism (set elite to 0 for none)
--surviveParents=\SURV_PAR_SIZE # Nb of surviving parents (percentage or absolute)
--reduceParents=\RED_PAR\RED_PAR_PRM # Parents reducer: Deterministic, EP(T), DetTour(T), StochTour(t), Uniform
--surviveOffspring=\SURV_OFF_SIZE # Nb of surviving offspring (percentage or absolute)
--reduceOffspring=\RED_OFF\RED_OFF_PRM # Offspring reducer: Deterministic, EP(T), DetTour(T), StochTour(t), Uniform
--reduceFinal=\RED_FINAL\RED_FINAL_PRM # Final reducer: Deterministic, EP(T), DetTour(T), StochTour(t), Uniform
###### Output ######
# --useEval=1 # Use nb of eval. as counter (vs nb of gen.)
# --useTime=1 # Display time (s) every generation
# --printBestStat=1 # Print Best/avg/stdev every gen.
# --printPop=0 # Print sorted pop. every gen.
###### Output - Disk ######
# --resDir=Res # Directory to store DISK outputs
# --eraseDir=1 # erase files in dirName if any
# --fileBestStat=0 # Output bes/avg/std to file
###### Output - Graphical ######
# --plotBestStat=0 # Plot Best/avg Stat
# --plotHisto=0 # Plot histogram of fitnesses
###### Persistence ######
# --Load= # -L : A save file to restart from
# --recomputeFitness=0 # -r : Recompute the fitness after re-loading the pop.?
# --saveFrequency=0 # Save every F generation (0 = only final state, absent = never)
# --saveTimeInterval=0 # Save every T seconds (0 or absent = never)
# --status=OneMaxGenomeEA.status # Status file
###### Stopping criterion ######
# --maxGen=100 # -G : Maximum number of generations () = none)
# --steadyGen=100 # -s : Number of generations with no improvement
# --minGen=0 # -g : Minimum number of generations
# --maxEval=0 # -E : Maximum number of evaluations (0 = none)
# --targetFitness=0 # -T : Stop when fitness reaches
# --CtrlC=0 # -C : Terminate current generation upon Ctrl C
###### Variation Operators ######
# --cross1Rate=1 # -1 : Relative rate for crossover 1
# --mut1Rate=1 # -1 : Relative rate for mutation 1
--pCross=\XOVER_PROB # -C : Probability of Crossover
--pMut=\MUT_PROB # -M : Probability of Mutation
\START_EO_MAKEFILE_TPL#*************************************
#
# EASEA.mak
#
# Makefile generated by AESAE-EO v0.7
#
#*************************************
# sample makefile for building an EA evolving a new genotype
DIR_EO = \EO_DIR
.cpp: ; c++ -DPACKAGE=\"eo\" -I. -I$(DIR_EO)/src -Wall -g -o $@ $*.cpp $(DIR_EO)/src/libeo.a $(DIR_EO)/src/utils/libeoutils.a
.cpp.o: ; c++ -DPACKAGE=\"eo\" -I. -I\EO_DIR/src -Wall -g -c $*.cpp
LIB_EO = $(DIR_EO)/src/utils/libeoutils.a $(DIR_EO)/src/libeo.a
SOURCES = EASEA.cpp \
EASEAEvalFunc.h \
EASEAGenome.h \
EASEAInit.h \
EASEAMutation.h \
EASEAQuadCrossover.h \
$(LIB_EO)
ALL = EASEA
EASEA : $(SOURCES)
c++ -g -I. -I$(DIR_EO)/src -o $@ EASEA.cpp $(LIB_EO) -lm
all : $(ALL)
clean : ; /bin/rm *.o $(ALL)
\TEMPLATE_END

View file

@ -0,0 +1,28 @@
# sample makefile for building an EA evolving a new genotype
# START eventually modify the name of EO dir
DIR_EO = ../../src
# END eventually modify the name of EO dir
LIB_EO = $(DIR_EO)/utils/libeoutils.a $(DIR_EO)/libeo.a
.cpp: ; c++ -DPACKAGE=\"eo\" -DVERSION=\"0.9.3\" -I. -I$(DIR_EO) -Wall -Wno-deprecated -g -o $@ $*.cpp $(LIB_EO)
.cpp.o: ; c++ -DPACKAGE=\"eo\" -DVERSION=\"0.9.3\" -I. -I$(DIR_EO) -Wall -Wno-deprecated -g -c $*.cpp
# local sources
SOURCES = MyStructEA.cpp \
eoMyStruct.h \
eoMyStructEvalFunc.h \
eoMyStructInit.h \
eoMyStructMutation.h \
eoMyStructQuadCrossover.h
MyStructEA : MyStructEA.cpp
c++ -I. -I$(DIR_EO) -Wno-deprecated -g -o $@ MyStructEA.cpp $(LIB_EO) -lm
tar : ; tar czvf MyStruct.tgz *.h *.cpp Makefile
clean : ; /bin/rm *.o MyStructEA
########## local dependencies
MyStructEA : $(SOURCES)

View file

@ -0,0 +1,48 @@
# sample makefile for building an EA evolving a new genotype
# START eventually modify the name of EO dir
DIR_EO = ../../src
# END eventually modify the name of EO dir
# eo libs
LIB_EO = $(DIR_EO)/utils/libeoutils.a $(DIR_EO)/libeo.a
# implicit compile rules
.SUFFIXES: .cpp
.cpp: ; $(CXX) -DPACKAGE=\"eo\" -DVERSION=\"0.9.3\" -I. -I$(DIR_EO) -Wall -g -o $@ $*.cpp $(LIB_EO)
.cpp.o: ; $(CXX) -DPACKAGE=\"eo\" -DVERSION=\"0.9.3\" -I. -I$(DIR_EO) -Wall -g -c $*.cpp
# local sources
COMMON_SOURCES = eoMyStruct.h \
eoMyStructEvalFunc.h \
eoMyStructInit.h \
eoMyStructMutation.h \
eoMyStructQuadCrossover.h \
make_genotype_MyStruct.h \
make_op_MyStruct.h
NO_LIB_SOURCES = MyStructEA.cpp
LIB_SOURCES = MyStructLibEA.cpp make_MyStruct.cpp
SOURCES = $(COMMON_SOURCES) MyStructEA.cpp MyStructLibEA.cpp make_MyStruct.cpp
ALL = MyStructEA MyStructLibEA
MyStructEA : MyStructEA.cpp
$(CXX) -I. -I$(DIR_EO) -g -o $@ MyStructEA.cpp $(LIB_EO) -lm
MyStructLibEA : MyStructLibEA.o make_MyStruct.o
$(CXX) -g -o $@ MyStructLibEA.o make_MyStruct.o $(LIB_EO) -lm
tar : ; tar czvf MyStruct.tgz *.h *.cpp Makefile
all : $(ALL)
clean : ; /bin/rm *.o $(ALL)
########## local dependencies
MyStructEA.cpp : $(COMMON_SOURCES)
MyStructLibEA.o : $(COMMON_SOURCES) MyStructLibEA.cpp
make_MyStruct.o : make_MyStruct.cpp eoMyStruct.h

View file

@ -0,0 +1,188 @@
/** -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*-
The above line is usefulin Emacs-like editors
*/
/*
Template for creating a new representation in EO
================================================
This is the template main file.
It includes all other files that have been generated by the script create.sh
so it is the only file to compile.
In case you want to build up a separate library for your new Evolving Object,
you'll need some work - follow what's done in the src/ga dir, used in the
main file BitEA in tutorial/Lesson4 dir.
Or you can wait until we do it :-)
*/
// Miscilaneous include and declaration
#include <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 eoMyStruct MUST derive from EO<FitT> for some fitness
*/
#include "eoMyStruct.h"
/** definition of initilizqtion:
* class eoMyStructInit MUST derive from eoInit<eoMyStruct>
*/
#include "eoMyStructInit.h"
/** definition of evaluation:
* class eoMyStructEvalFunc MUST derive from eoEvalFunc<eoMyStruct>
* and should test for validity before doing any computation
* see tutorial/Templates/evalFunc.tmpl
*/
#include "eoMyStructEvalFunc.h"
// GENOTYPE eoMyStruct ***MUST*** be templatized over the fitness
//*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
// START fitness type: double or eoMaximizingFitness if you are maximizing
// eoMinimizingFitness if you are minimizing
typedef eoMinimizingFitness MyFitT ; // type of fitness
// END fitness type
//*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
// Then define your EO objects using that fitness type
typedef eoMyStruct<MyFitT> Indi; // ***MUST*** derive from EO
// create an initializer
#include "make_genotype_MyStruct.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_MyStruct.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
//////////////
eoMyStructEvalFunc<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;
}

View file

@ -0,0 +1,162 @@
/** -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*-
The above line is usefulin Emacs-like editors
*/
/*
Template for creating a new representation in EO
================================================
This is the template main file for compiling after creating a
"library", i.e. putting everything but the fitness in a separate file
(make_MyStruct.cpp) and compiling it once and for all.
*/
// 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 eoMyStruct MUST derive from EO<FitT> for some fitness
*/
#include "eoMyStruct.h"
/** definition of initilizqtion:
* class eoMyStructInit MUST derive from eoInit<eoMyStruct>
*/
#include "eoMyStructInit.h"
/** definition of evaluation:
* class eoMyStructEvalFunc MUST derive from eoEvalFunc<eoMyStruct>
* and should test for validity before doing any computation
* see tutorial/Templates/evalFunc.tmpl
*/
#include "eoMyStructEvalFunc.h"
// GENOTYPE eoMyStruct ***MUST*** be templatized over the fitness
//
// START fitness type: double or eoMaximizingFitness if you are maximizing
// eoMinimizingFitness if you are minimizing
typedef eoMinimizingFitness MyFitT ; // type of fitness
// END fitness type
//
// Then define your EO objects using that fitness type
typedef eoMyStruct<MyFitT> Indi; // ***MUST*** derive from EO
// create an initializer - done here and NOT in make_MyStruct.cpp
// because it is NOT representation independent
#include "make_genotype_MyStruct.h"
eoInit<Indi> & make_genotype(eoParser& _parser, eoState&_state, Indi _eo)
{
return do_make_genotype(_parser, _state, _eo);
}
// same thing for the variation operaotrs
#include "make_op_MyStruct.h"
eoGenOp<Indi>& make_op(eoParser& _parser, eoState& _state, eoInit<Indi>& _init)
{
return do_make_op(_parser, _state, _init);
}
// The representation independent routines are simply declared here
// how to initialize the population
// it IS representation independent if an eoInit is given
eoPop<Indi >& make_pop(eoParser& _parser, eoState& _state, eoInit<Indi> & _init);
// the stopping criterion
eoContinue<Indi>& make_continue(eoParser& _parser, eoState& _state, eoEvalFuncCounter<Indi> & _eval);
// outputs (stats, population dumps, ...)
eoCheckPoint<Indi>& make_checkpoint(eoParser& _parser, eoState& _state, eoEvalFuncCounter<Indi>& _eval, eoContinue<Indi>& _continue);
// evolution engine (selection and replacement)
eoAlgo<Indi>& make_algo_scalar(eoParser& _parser, eoState& _state, eoEvalFunc<Indi>& _eval, eoContinue<Indi>& _continue, eoGenOp<Indi>& _op);
// simple call to the algo. stays there for consistency reasons
// no template for that one
void run_ea(eoAlgo<Indi>& _ga, eoPop<Indi>& _pop);
// checks for help demand, and writes the status file
// and make_help; in libutils - just a declaration, code in libeoutils.a
void make_help(eoParser & _parser);
// now use all of the above, + representation dependent things
// from here on, no difference with eoMyStruct.cpp
int main(int argc, char* argv[])
{
try
{
eoParser parser(argc, argv); // for user-parameter reading
eoState state; // keeps all things allocated
// The fitness
//////////////
eoMyStructEvalFunc<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;
}

View file

@ -0,0 +1,350 @@
/** -*- 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 eoMyStruct MUST derive from EO<FitT> for some fitness
*/
#include "eoMyStruct.h"
/** definition of initilizqtion:
* class eoMyStructInit MUST derive from eoInit<eoMyStruct>
*/
#include "eoMyStructInit.h"
/** definition of evaluation:
* class eoMyStructEvalFunc MUST derive from eoEvalFunc<eoMyStruct>
* and should test for validity before doing any computation
* see tutorial/Templates/evalFunc.tmpl
*/
#include "eoMyStructEvalFunc.h"
/** definitions of operators: write as many classes as types of operators
* and include them here. In this simple example,
* one crossover (2->2) and one mutation (1->1) operators are used
*/
#include "eoMyStructQuadCrossover.h"
#include "eoMyStructMutation.h"
/* and (possibly) your personal statistics */
#include "eoMyStructStat.h"
// GENOTYPE eoMyStruct ***MUST*** be templatized over the fitness
//*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
// START fitness type: double or eoMaximizingFitness if you are maximizing
// eoMinimizingFitness if you are minimizing
typedef eoMinimizingFitness MyFitT ; // type of fitness
// END fitness type
//*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
// Then define your EO objects using that fitness type
typedef eoMyStruct<MyFitT> Indi; // ***MUST*** derive from EO
// Use existing modules to define representation independent routines
// how to initialize the population
// it IS representation independent if an eoInit is given
#include <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, eoDistance<Indi> *_dist = NULL)
{
return do_make_algo_scalar(_parser, _state, _eval, _continue, _op, _dist);
}
// 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
//////////////
eoMyStructEvalFunc<Indi> plainEval/* (varType _anyVariable) */;
// turn that object into an evaluation counter
eoEvalFuncCounter<Indi> eval(plainEval);
// a genotype initializer
eoMyStructInit<Indi> init;
// or, if you need some parameters, you might as well
// - write a constructor of the eoMyStructInit that uses a parser
// - call it from here:
// eoMyStructInit<Indi> init(parser);
// if you want to do sharing, you'll need a distance.
// see file utils/eoDistance.h
//
// IF you representation has an operator[]() double-castable,
// then you can use for instance the quadratic distance (L2 norm)
// eoQuadDistance<Indi> dist;
// or the Hamming distance (L1 norm)
// eoHammingDistance<Indi> dist;
// Build the variation operator (any seq/prop construct)
// here, a simple example with only 1 crossover (2->2, a QuadOp) and
// one mutation, is given.
// Hints to have choice among multiple crossovers and mutations are given
// A (first) crossover (possibly use the parser in its Ctor)
eoMyStructQuadCrossover<Indi> cross /* (eoParser parser) */;
// IF MORE THAN ONE:
// read its relative rate in the combination
// double cross1Rate = parser.createParam(1.0, "cross1Rate", "Relative rate for crossover 1", '1', "Variation Operators").value();
// create the combined operator with the first one (rename it cross1 !!!)
// eoPropCombinedQuadOp<Indi> cross(cross1, cross1Rate);
// and as many as you want the following way:
// 1- write the new class by mimicking eoMyStructQuadCrossover.h
// 2- include that file here together with eoMyStructQuadCrossover above
// 3- uncomment and duplicate the following lines:
//
// eoMyStructSecondCrossover<Indi> cross2(eoParser parser);
// double cross2Rate = parser.createParam(1.0, "cross2Rate", "Relative rate for crossover 2", '2', "Variation Operators").value();
// cross.add(cross2, cross2Rate);
// NOTE: if you want some gentle output, the last one shoudl be like
// cross.add(cross, crossXXXRate, true);
/////////////// Same thing for MUTATION
// a (first) mutation (possibly use the parser in its Ctor)
eoMyStructMutation<Indi> mut /* (parser) */;
// IF MORE THAN ONE:
// read its relative rate in the combination
// double mut1Rate = parser.createParam(1.0, "mut1Rate", "Relative rate for mutation 1", '1', "Variation Operators").value();
// create the combined operator with the first one (rename it cross1 !!!)
// eoPropCombinedMonOp<Indi> mut(mut1, mut1Rate);
// and as many as you want the following way:
// 1- write the new class by mimicking eoMyStructMutation.h
// 2- include that file here together with eoMyStructMutation above
// 3- uncomment and duplicate the following lines:
//
// eoMyStructSecondMutation<Indi> mut2(eoParser parser);
// double mut2Rate = parser.createParam(1.0, "mut2Rate", "Relative rate for mutation 2", '2', "Variation Operators").value();
// mut.add(mut2, mut2Rate);
// NOTE: if you want some gentle output, the last one shoudl be like
// mut.add(mut, mutXXXRate, true);
// now encapsulate your crossover(s) and mutation(s) into an eoGeneralOp
// so you can fully benefit of the existing evolution engines
// First read the individual level parameters
double pCross = parser.createParam(0.6, "pCross", "Probability of Crossover", 'C', "Variation Operators" ).value();
// minimum check
if ( (pCross < 0) || (pCross > 1) )
throw runtime_error("Invalid pCross");
double pMut = parser.createParam(0.1, "pMut", "Probability of Mutation", 'M', "Variation Operators" ).value();
// minimum check
if ( (pMut < 0) || (pMut > 1) )
throw runtime_error("Invalid pMut");
// now create the generalOp
eoSGAGenOp<Indi> op(cross, pCross, mut, pMut);
//// Now some representation-independent things
//
// You do not need to modify anything beyond this point
// unless you want to add specific statistics to the checkpoint
// in which case you should uncomment the corresponding block
// and possibly modify the parameters in the stat object creation
//////////////////////////////////////////////
// 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);
// UNCOMMENT the following commented block if you want to add you stats
// if uncommented, it is assumed that you will want to print some stat.
// if not, then the following objects will be created uselessly - but what the heck!
eoMyStructStat<Indi> myStat; // or maybe myStat(parser);
checkpoint.add(myStat);
// This one is probably redundant with the one in make_checkpoint, but w.t.h.
eoIncrementorParam<unsigned> generationCounter("Gen.");
checkpoint.add(generationCounter);
// need to get the name of the redDir param (if any)
std::string dirName = parser.getORcreateParam(std::string("Res"), "resDir", "Directory to store DISK outputs", '\0', "Output - Disk").value() + "/";
// those need to be pointers because of the if's
eoStdoutMonitor *myStdOutMonitor;
eoFileMonitor *myFileMonitor;
#ifdef HAVE_GNUPLOT
eoGnuplot1DMonitor *myGnuMonitor;
#endif
// now check how you want to output the stat:
bool printMyStructStat = parser.createParam(false, "coutMyStructStat", "Prints my stat to screen, one line per generation", '\0', "My application").value();
bool fileMyStructStat = parser.createParam(false, "fileMyStructStat", "Saves my stat to file (in resDir", '\0', "My application").value();
bool plotMyStructStat = parser.createParam(false, "plotMyStructStat", "On-line plots my stat using gnuplot", '\0', "My application").value();
// should we write it on StdOut ?
if (printMyStructStat)
{
myStdOutMonitor = new eoStdoutMonitor(false);
// don't forget to store the memory in the state
state.storeFunctor(myStdOutMonitor);
// and of course to add the monitor to the checkpoint
checkpoint.add(*myStdOutMonitor);
// and the different fields to the monitor
myStdOutMonitor->add(generationCounter);
myStdOutMonitor->add(eval);
myStdOutMonitor->add(myStat);
}
// first check the directory (and creates it if not exists already):
if (fileMyStructStat || plotMyStructStat)
if (! testDirRes(dirName, true) )
throw runtime_error("Problem with resDir");
// should we write it to a file ?
if (fileMyStructStat)
{
// the file name is hard-coded - of course you can read
// a string parameter in the parser if you prefer
myFileMonitor = new eoFileMonitor(dirName + "myStat.xg");
// don't forget to store the memory in the state
state.storeFunctor(myFileMonitor);
// and of course to add the monitor to the checkpoint
checkpoint.add(*myFileMonitor);
// and the different fields to the monitor
myFileMonitor->add(generationCounter);
myFileMonitor->add(eval);
myFileMonitor->add(myStat);
}
#ifdef HAVE_GNUPLOT
// should we PLOT it on StdOut ? (one dot per generation, incremental plot)
if (plotMyStructStat)
{
myGnuMonitor = new eoGnuplot1DMonitor(dirName+"plot_myStat.xg",minimizing_fitness<Indi>());
// NOTE: you cand send commands to gnuplot at any time with the method
// myGnuMonitor->gnuplotCommand(string)
// par exemple, gnuplotCommand("set logscale y")
// don't forget to store the memory in the state
state.storeFunctor(myGnuMonitor);
// and of course to add the monitor to the checkpoint
checkpoint.add(*myGnuMonitor);
// and the different fields to the monitor (X = eval, Y = myStat)
myGnuMonitor->add(eval);
myGnuMonitor->add(myStat);
}
#endif
// algorithm (need the operator!)
eoAlgo<Indi>& ga = make_algo_scalar(parser, state, eval, checkpoint, op);
// and the distance if you want to do sharing
// eoAlgo<Indi>& ga = make_algo_scalar(parser, state, eval, checkpoint, op, &dist);
///// 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;
}

View file

@ -0,0 +1,149 @@
Quick NOTE: This version of README is obsolete (May 25, 2004)
In particular, a simpler version of the algorithm can be generated
using the script
createSimple
with the same syntax. It is also more powerful, allowing for instance
to create you own statistics on the population, saving it in a file
and/or plotting on on-line during the run (see eoStat.tmpl).
More details some day, when I have some time ...
============= Old README (most is still accurate, though) ==========
This directory contains sample files that should make it easy to
create an EO algorithm to evolve any type of structure
(EO comes with two examples, bitstrings and vector of real variables,
so you'll need this as soon as you want to evolve something else).
At the moment, only algorithms involving a scalar fitness (double)
are implemented (see test dir for Pareto optimization of multiple-
objective fitness - or be patient :-)
This file will help you to build the same algorithm than the ones
in the Lesson4 of the tutorial, but with YOUR genotype instead of
bitstrings or vector<double>. More details in Lesson5 of the tutorial.
It is assumed in the following that you have read the first part of
the tutorial (Lessons 1 to 4).
Creating the algorithm for your genotype
----------------------------------------
In what follows, we will suppose that you want to evolve some data
structure, and that you have enough programming skills to be able to
write C code for its random initilialization, its crossover, its
mutation and the computation of its fitness.
The helper script * create.sh * will create for you the files you need
from the samples in tutorial/Templates dir, and all you'll have to do
is to include the actual code where indicated in those files (between
keywords START and END).
First, let's choose a name: let's call the new EO class eoAppli.
All newly created classes will be named eoAppliXXX (in the file
eoAppliXXX)
1- cd to the tutorial dir
2- create the directory for your application (let's assume you call it
APPLICATION): type in
mkdir APPLICATION
3- go to the Templates dir
cd Templates
and run the helper script create.sh with the following arguments
./create.sh Appli ../APPLICATION
4- cd to the APPLICATION dir (cd ../APPLICATION).
You should see there the following files:
AppliEA.cpp the main file, includes all other, to be compiled
Makefile with default target eoAppliEA
eoAppli.h class eoAppli<FitT>, FitT = template fitness
eoAppliEvalFunc.h class for the computation of fotness
eoAppliInit.h class for genotype initlialization
eoAppliMutation.h class for mutation
eoAppliQuadCrossover.h class for (quadratic) crossover
make_genotype_Appli.h helper function that create the initializer
make_op_Appli.h helper function that creates the variatin operators
Note: You can go directly to step 6 and 7: you'll get a lot of
warnings, but will be able to run an EA that does nothing!
5- Edit those files to suit your needs. The minimal addition you'll need
to make are
in eoAppli.h define your genotype
in eoAppliInit.h define the initialization of one genotype
in eoAppliMutation.h define the mutation of one genotype
in eoAppliQuadCrossover.h define the crossover of 2 genotypes
HINT: look for keywords START and END and modify code in between.
6- Compile eoAppliEA.cpp. If your APPLICATION dir is in the tutorial
dir, you don't need to modify Makefile. Just type in
% make
7- Run the resulting program:
% eoAppliEA
The default output is one line per generation with the generation
number, the number of evaluations performed, the best and average
fitnesses in the population.
The algorithm stops by default after 100 generations.
8- Customize the parameters: copy eoAppliEA.status into
e.g. eoAppliEA.param, edit eoAppliEA.param (uncomment the lines you
want to become active), and run
% eoAppliEA @eoAppliEA.param
(see the Lesson 5 of the tutorial for more details now).
HINTS
-----
1- If some new classes you create require some user parameter, you can
either read them in the file where they are created (e.g.
make_op_Appli.h for variation operators), or pass the eoParser to the
constructor of the class, and read the parameter from the parser.
2- If you stick to privacy for the data in your EO class, you will
probably need to write accessors to those data, as well as some public
methods to modify them, as soon as some other methods need them too.
3- The sample make_op_Appli.h supposes that you ony have one crossover
and one mutation operator. However, the code for multiple operators is
there: you can have for instance 2 crossover operators, and choose
among them according to relative weights (proportional choice) - same
for mutation. Look at the operator section in eoAppliEA.cpp In
particular, the user parameters cross1Rate and mut1Rate are totally
useless for a single operator.
To add another operator, you have to create another class by mimicking
what has been done for the first operator.
For instance, let's suppose you want to create another mutation.
* duplicate the code for eoAppliMutation class
* in the second version, change the class name (eoAppliMutation) into
another name (let's say eoAppliBetterMutation) - you must change the
name in the class declaration, in the constructor and in the
className() method.
* in the new eoAppliBetterMutation class, change the code for the
operator() - and eventually the code for the constructor.
* in the make_op_Appli.h file, in the mutation section, uncomment the
lines
mut = new eoAppliSecondMutation<Indi>(varType _anyVariable);
_state.storeFunctor(mut);
double mut2Rate = _parser.createParam(1.0, "mut2Rate", "Relative rate for mutation 2", '2', "Variation Operators").value();
propMutation.add(*mut, mut2Rate);
and change the name of the class from eoAppliSecondMutation to your
name eoAppliBetterMutation (you can also change the keyword from
mut2Rate to something more meaningful like BetterMutationRate).
You're done!
In case of problem: Marc.Schoenauer@inria.fr

View file

@ -0,0 +1,70 @@
/** -*- 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 binary crossover operators
==============================================
Binary crossover operators modify the first genotype only,
based on the second
*/
#ifndef eoMyStructBinCrossover_H
#define eoMyStructBinCrossover_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 eoMyStructBinCrossover: public eoBinOp<GenotypeT>
{
public:
/**
* Ctor - no requirement
*/
// START eventually add or modify the anyVariable argument
eoMyStructBinCrossover()
// eoMyStructBinCrossover( varType _anyVariable) : anyVariable(_anyVariable)
// END eventually add or modify the anyVariable argument
{
// START Code of Ctor of an eoMyStructEvalFunc object
// END Code of Ctor of an eoMyStructEvalFunc object
}
/// The class name. Used to display statistics
string className() const { return "eoMyStructBinCrossover"; }
/**
* binCrossover - modifies first genotype only
* @param _genotype1 The first genotype
* @param _genotype2 The second genotype - const
*/
bool operator()(GenotypeT & _genotype1, const GenotypeT & _genotype2)
{
// START code for crossover of _genotype1 and _genotype2 objects
/** Requirement
* if _genotype1 has been modified
* return true;
* otherwise
* return false;
*/
// END code for crossover of _genotype1 and _genotype2 objects
}
private:
// START Private data of an eoMyStructBinCrossover object
// varType anyVariable; // for example ...
// END Private data of an eoMyStructBinCrossover object
};
#endif

View file

@ -0,0 +1,65 @@
/** -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*-
The above line is usefulin Emacs-like editors
*/
/*
Template for continuator in EO, i.e. stopping conditions for EO algorithms
==========================================================================
*/
#ifndef _eoMyStructContinue_h
#define _eoMyStructContinue_h
// include the base definition of eoContinue
#include <eoContinue.h>
/**
* Always write a comment in this format before class definition
* if you want the class to be documented by Doxygen
*
* ATTENTION, class EOT *must* derive from EO, as operator() will
* be called with an eoPop<EOT>
*/
template< class EOT>
class eoMyStructContinue: public eoContinue<EOT> {
public:
/**
* Ctor - no requirement
*/
// START eventually add or modify the anyVariable argument
eoMyStructContinue()
// eoMyStructBinCrossover( varType _anyVariable) : anyVariable(_anyVariable)
// END eventually add or modify the anyVariable argument
{
// START Code of Ctor of an eoMyStructEvalFunc object
// END Code of Ctor of an eoMyStructEvalFunc object
}
/** Returns false when you want to stop
*
* @param _pop an eoPop
*/
virtual bool operator() ( const eoPop<EOT>& _pop )
{
bool stopCondition ; // to store the stopping condition
// START Code of computation of stopping condition
// stopCondition = blablabla
// END Code of computation of stopping condition
if (stopCondition) // the algo will stop upon return FALSE
{
cout << "STOP in eoMyStructContinue \n";
return false;
}
return true; // == do not stop
}
private:
// START Private data of an eoMyStructContinue object
// varType anyVariable; // for example ...
// END Private data of an eoMyStructContinue object
};
#endif

View file

@ -0,0 +1,62 @@
#! /bin/tcsh -f
if ($PWD:t != Templates) then
echo You must be in the Template dir to run that script
exit
endif
if ($#argv < 1) then
echo "Usage $0 ApplicationName [TargetDirName]"
echo " will create ../TargetDirName if necessary"
echo " (default dir name = ApplicationName),"
echo " and will put there all files that are strictly necessary"
echo " to compile and run you Application from there"
exit
endif
echo " " # we're going to do something
if ($#argv == 1) then
set TargetDir = ../$1
else
set TargetDir = ../$2
endif
if (! -e $TargetDir) then
mkdir $TargetDir
endif
if ( (-f $TargetDir/eo$1.h) || (-f $TargetDir/eo$1Init.h) || (-f $TargetDir/eo$1EvalFunc.h) || (-f $TargetDir/eo$1Mutation.h) || (-f $TargetDir/eo$1QuadCrossover.h) || (-f $TargetDir/$1EA.cpp) || (-f $TargetDir/make_genotype_$1.h) || (-f $TargetDir/make_op_$1.h) ) then
echo WARNING: some files already exist there.
echo -n "Overwrite ALL (yes/no)? "
set REP = $<
if ($REP != "yes") then
echo Nothing done!
exit
endif
endif
if (-f $TargetDir/Makefile) then
echo A Makefile already exists there.
echo I'm creating Makefile.$1. You'll have to merge them both,
echo OR to call make -f Makefile.$1
set MakeName = Makefile.$1
else
set MakeName = Makefile
endif
echo Creating source files for application $1 in $TargetDir/
sed s/MyStruct/$1/g eoMyStruct.tmpl > $TargetDir/eo$1.h
sed s/MyStruct/$1/g init.tmpl > $TargetDir/eo$1Init.h
sed s/MyStruct/$1/g evalFunc.tmpl > $TargetDir/eo$1EvalFunc.h
sed s/MyStruct/$1/g mutation.tmpl > $TargetDir/eo$1Mutation.h
sed s/MyStruct/$1/g quadCrossover.tmpl > $TargetDir/eo$1QuadCrossover.h
sed s/MyStruct/$1/g MyStructEA.cpp > $TargetDir/$1EA.cpp
sed s/MyStruct/$1/g make_genotype_MyStruct.h > $TargetDir/make_genotype_$1.h
sed s/MyStruct/$1/g make_op_MyStruct.h > $TargetDir/make_op_$1.h
sed s/MyStruct/$1/g make_MyStruct.cpp > $TargetDir/make_$1.cpp
sed s/MyStruct/$1/g MyStructLibEA.cpp > $TargetDir/$1LibEA.cpp
sed s/MyStruct/$1/g Makefile.tmpl > $TargetDir/$MakeName
echo Done!

View file

@ -0,0 +1,59 @@
#! /bin/tcsh -f
if ($PWD:t != Templates) then
echo You must be in the Template dir to run that script
exit
endif
if ($#argv < 1) then
echo "Usage $0 ApplicationName [TargetDirName]"
echo " will create ../TargetDirName if necessary"
echo " (default dir name = ApplicationName),"
echo " and will put there all files that are strictly necessary"
echo " to compile and run you Application from there"
exit
endif
echo " " # we're going to do something
if ($#argv == 1) then
set TargetDir = ../$1
else
set TargetDir = ../$2
endif
if (! -e $TargetDir) then
mkdir $TargetDir
endif
if ( (-f $TargetDir/eo$1.h) || (-f $TargetDir/eo$1Init.h) || (-f $TargetDir/eo$1EvalFunc.h) || (-f $TargetDir/eo$1Mutation.h) || (-f $TargetDir/eo$1QuadCrossover.h) || (-f $TargetDir/$1EA.cpp) || (-f $TargetDir/make_genotype_$1.h) || (-f $TargetDir/make_op_$1.h) ) then
echo WARNING: some files already exist there.
echo -n "Overwrite ALL (yes/no)? "
set REP = $<
if ($REP != "yes") then
echo Nothing done!
exit
endif
endif
if (-f $TargetDir/Makefile) then
echo A Makefile already exists there.
echo "I'm creating Makefile.$1. You'll have to merge them both,"
echo OR to call make -f Makefile.$1
set MakeName = Makefile.$1
else
set MakeName = Makefile
endif
echo Creating source files for application $1 in $TargetDir/
sed s/MyStruct/$1/g eoMyStruct.tmpl > $TargetDir/eo$1.h
sed s/MyStruct/$1/g init.tmpl > $TargetDir/eo$1Init.h
sed s/MyStruct/$1/g stat.tmpl > $TargetDir/eo$1Stat.h
sed s/MyStruct/$1/g evalFunc.tmpl > $TargetDir/eo$1EvalFunc.h
sed s/MyStruct/$1/g mutation.tmpl > $TargetDir/eo$1Mutation.h
sed s/MyStruct/$1/g quadCrossover.tmpl > $TargetDir/eo$1QuadCrossover.h
sed s/MyStruct/$1/g MyStructSEA.cpp > $TargetDir/$1EA.cpp
sed s/MyStruct/$1/g MakeSimple.tmpl > $TargetDir/$MakeName
echo Done!

View file

@ -0,0 +1,118 @@
/** -*- 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
================================================
Mandatory:
- a default constructor (constructor without any argument)
- the I/O functions (readFrom and printOn)
However, if you are using dynamic memory, there are 2 places
to allocate it: the default constructor (if possible?), or, more in
the EO spirit, the eoInit object, that you will need to write anyway
(template file init.tmpl).
But remember that a COPY CONSTRUCTOR will be used in many places in EO,
so make sure that the default copy constructor works, or, even better,
do write your own if in doubt.
And of course write the corresponding destructor!
*/
#ifndef _eoMyStruct_h
#define _eoMyStruct_h
/**
* Always write a comment in this format before class definition
* if you want the class to be documented by Doxygen
* Note that you MUST derive your structure from EO<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 eoMyStruct: public EO<FitT> {
public:
/** Ctor: you MUST provide a default ctor.
* though such individuals will generally be processed
* by some eoInit object
*/
eoMyStruct()
{
// START Code of default Ctor of an eoMyStruct object
// END Code of default Ctor of an eoMyStruct object
}
/** Copy Ctor: you MUST provide a copy ctor if the default
* one is not what you want
* If this is the case, uncomment and fill the following
*/
/*
eoMyStruct(const eoMyStruct &)
{
// START Code of copy Ctor of an eoMyStruct object
// END Code of copy Ctor of an eoMyStruct object
}
*/
virtual ~eoMyStruct()
{
// START Code of Destructor of an eoEASEAGenome object
// END Code of Destructor of an eoEASEAGenome object
}
virtual string className() const { return "eoMyStruct"; }
/** printing... */
void printOn(ostream& os) const
{
// First write the fitness
EO<FitT>::printOn(os);
os << ' ';
// START Code of default output
/** HINTS
* in EO we systematically write the sizes of things before the things
* so readFrom is easier to code (see below)
*/
// END Code of default output
}
/** reading...
* of course, your readFrom must be able to read what printOn writes!!!
*/
void readFrom(istream& is)
{
// of course you should read the fitness first!
EO<FitT>::readFrom(is);
// START Code of input
/** HINTS
* remember the eoMyStruct object will come from the default ctor
* this is why having the sizes written out is useful
*/
// END Code of input
}
private: // put all data here
// START Private data of an eoMyStruct object
// END Private data of an eoMyStruct object
};
#endif

View file

@ -0,0 +1,65 @@
/** -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*-
The above line is usefulin Emacs-like editors
*/
/*
Template for evaluator in EO, a functor that computes the fitness of an EO
==========================================================================
*/
#ifndef _eoMyStructEvalFunc_h
#define _eoMyStructEvalFunc_h
// include whatever general include you need
#include <stdexcept>
#include <fstream>
// include the base definition of eoEvalFunc
#include "eoEvalFunc.h"
/**
Always write a comment in this format before class definition
if you want the class to be documented by Doxygen
*/
template <class EOT>
class eoMyStructEvalFunc : public eoEvalFunc<EOT>
{
public:
/// Ctor - no requirement
// START eventually add or modify the anyVariable argument
eoMyStructEvalFunc()
// eoMyStructEvalFunc( varType _anyVariable) : anyVariable(_anyVariable)
// END eventually add or modify the anyVariable argument
{
// START Code of Ctor of an eoMyStructEvalFunc object
// END Code of Ctor of an eoMyStructEvalFunc object
}
/** Actually compute the fitness
*
* @param EOT & _eo the EO object to evaluate
* it should stay templatized to be usable
* with any fitness type
*/
void operator()(EOT & _eo)
{
// test for invalid to avoid recomputing fitness of unmodified individuals
if (_eo.invalid())
{
double fit; // to hold fitness value
// START Code of computation of fitness of the eoMyStruct object
// fit = blablabla
// END Code of computation of fitness of the eoMyStruct object
_eo.fitness(fit);
}
}
private:
// START Private data of an eoMyStructEvalFunc object
// varType anyVariable; // for example ...
// END Private data of an eoMyStructEvalFunc object
};
#endif

View file

@ -0,0 +1,58 @@
/** -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*-
The above line is usefulin Emacs-like editors
*/
/*
Template for EO objects initialization in EO
============================================
*/
#ifndef _eoMyStructInit_h
#define _eoMyStructInit_h
// include the base definition of eoInit
#include <eoInit.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 (e.g. to initialize
* atoms of an eoVector you will need an eoInit<AtomType>)
*/
template <class GenotypeT>
class eoMyStructInit: public eoInit<GenotypeT> {
public:
/// Ctor - no requirement
// START eventually add or modify the anyVariable argument
eoMyStructInit()
// eoMyStructInit( varType _anyVariable) : anyVariable(_anyVariable)
// END eventually add or modify the anyVariable argument
{
// START Code of Ctor of an eoMyStructInit object
// END Code of Ctor of an eoMyStructInit object
}
/** initialize a genotype
*
* @param _genotype generally a genotype that has been default-constructed
* whatever it contains will be lost
*/
void operator()(GenotypeT & _genotype)
{
// START Code of random initialization of an eoMyStruct object
// END Code of random initialization of an eoMyStruct object
_genotype.invalidate(); // IMPORTANT in case the _genotype is old
}
private:
// START Private data of an eoMyStructInit object
// varType anyVariable; // for example ...
// END Private data of an eoMyStructInit object
};
#endif

View file

@ -0,0 +1,81 @@
/** -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*-
The above line is usefulin Emacs-like editors
*/
/*
Template for general operators
===============================
i.e. that takes any number of parents and generates any number of offspring
a GenOp that creates less offspring than there are parents
Second version, get parents using an external eoSelectOne
*/
#ifndef eoLessOffspringExternalSelectorGenOp_H
#define eoLessOffspringExternalSelectorGenOp_H
#include <eoGenOp.h>
/**
* Always write a comment in this format before class definition
* if you want the class to be documented by Doxygen
*
* ATTENTION, class EOT *must* derive from EO, as method invalidate()
* must be called if the genotypes of the indis is modified
*/
template<class EOT>
class eoLessOffspringExternalSelectorGenOp: public eoGenOp<EOT>
{
public:
/**
* (Default) Constructor.
*/
eoLessOffspringExternalSelectorGenOp(eoSelectOne<EOT> & _sel, paramType _anyParameter) :
sel(_sel), anyParameter(_anyParameter) {}
/// The class name. Used to display statistics
string className() const { return "eoLessOffspringExternalSelectorGenOp"; }
/// The TOTAL number of offspring (here = nb of parents modified in place)
unsigned max_production(void) { return NbLeftParents; }
/**
* eoShrinkGen operator - modifies some parents in the populator
* using extra "parents" selected from an external selector
*
* @param _pop a POPULATOR (not a simple population)
*/
void apply(eoPopulator<EOT>& _plop)
{
// First, select as many parents as you will have offspring
EOT& parent1 = *_plop; // select the first parent
++_plop; // advance once for each selected parents
...
EOT& parentN = *_plop; // say you want N offspring
// get extra parents - use private selector
// _plop.source() is the eoPop<EOT> used by _plop to get parents
// WARNING: you are not allowed to modify them (mandatory "const")
const EOT& parentN+1 = sel(_plop.source());
...
const EOT& parentN+K = sel(_plop.source());
// modify (in place) the "true" parents
// (i.e. parent1, ..., parentsN)
...
// invalidate fitnesses of modified parents
parent1.invalidate();
...
parentN.invalidate();
}
private:
eoSelectOne<EOT> & sel;
paramType anyParameter
};
#endif

View file

@ -0,0 +1,76 @@
/** -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*-
The above line is usefulin Emacs-like editors
*/
/*
Template for general operators
===============================
i.e. that takes any number of parents and generates any number of offspring
a GenOp that creates less offspring than there are parents
First version, get parents from populator using the imbedded select() method
*/
#ifndef eoLessOffspringSameSelectorGenOp_H
#define eoLessOffspringSameSelectorGenOp_H
#include <eoGenOp.h>
/**
* Always write a comment in this format before class definition
* if you want the class to be documented by Doxygen
*
* ATTENTION, class EOT *must* derive from EO, as method invalidate()
* must be called if the genotypes of the indis is modified
*/
template<class EOT>
class eoLessOffspringSameSelectorGenOp: public eoGenOp<EOT>
{
public:
/**
* (Default) Constructor.
*/
eoLessOffspringSameSelectorGenOp(paramType _anyParameter) :
anyParameter(_anyParameter) {}
/// The class name. Used to display statistics
string className() const { return "eoLessOffspringSameSelectorGenOp"; }
/// The TOTAL number of offspring (here = nb of remaining modified parents)
unsigned max_production(void) { return NbLeftParents; }
/**
* eoLesOffspringSameSelectorGenOp operator -
* gets extra parents from the populator
*
* @param _pop a POPULATOR (not a simple population)
*/
void apply(eoPopulator<EOT>& _plop)
{
// First, select as many parents as you will have offspring
EOT& parent1 = *_plop; // select the first parent
++_plop; // advance once for each selected parents
...
EOT& parentN = *_plop; // say you want N offspring
// Now select extra parents from the populator
EOT& parentN+1 = _plop.select();
...
EOT& parentN+K = _plop.select();
// modify the first N parents
...
// oh right, and invalidate their fitnesses
parent1.invalidate();
...
parentN.invalidate();
}
private:
paramType anyParameter
};
#endif

Some files were not shown because too many files have changed in this diff Show more