Initial version of the tutorial.
Warning: all Makefile's are hand-made, and will only work in Linux
This commit is contained in:
parent
a27dc53ef0
commit
b8d4e7faef
48 changed files with 9174 additions and 0 deletions
164
eo/tutorial/Lesson1/FirstBitGA.cpp
Normal file
164
eo/tutorial/Lesson1/FirstBitGA.cpp
Normal file
|
|
@ -0,0 +1,164 @@
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// FirstBitGA.cpp
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
//*
|
||||||
|
// An instance of a VERY simple Bitstring Genetic Algorithm
|
||||||
|
//
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// standard includes
|
||||||
|
#include <stdexcept> // runtime_error
|
||||||
|
#include <iostream> // cout
|
||||||
|
#include <strstream> // ostrstream, istrstream
|
||||||
|
|
||||||
|
// the general include for eo
|
||||||
|
|
||||||
|
#include <eo>
|
||||||
|
|
||||||
|
// REPRESENTATION
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// define your individuals
|
||||||
|
typedef eoBin<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 = 8; // Number of bits in genotypes
|
||||||
|
const unsigned int POP_SIZE = 20; // Size of population
|
||||||
|
const unsigned int MAX_GEN = 100; // Maximum number of generation before STOP
|
||||||
|
const float CROSS_RATE = 0.8; // Crossover rate
|
||||||
|
const double P_MUT_PER_BIT = 0.01; // probability of bit-flip mutation
|
||||||
|
const float MUT_RATE = 1.0; // mutation rate
|
||||||
|
|
||||||
|
// GENERAL
|
||||||
|
//////////////////////////
|
||||||
|
// Random seed
|
||||||
|
//////////////////////////
|
||||||
|
//reproducible random seed: if you don't change SEED above,
|
||||||
|
// you'll aways get the same result, NOT a random run
|
||||||
|
rng.reseed(SEED);
|
||||||
|
|
||||||
|
// EVAL
|
||||||
|
/////////////////////////////
|
||||||
|
// Fitness function
|
||||||
|
////////////////////////////
|
||||||
|
// Evaluation: from a plain C++ fn to an EvalFunc Object
|
||||||
|
eoEvalFuncPtr<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;
|
||||||
|
|
||||||
|
// ENGINE
|
||||||
|
/////////////////////////////////////
|
||||||
|
// selection and replacement
|
||||||
|
////////////////////////////////////
|
||||||
|
// SELECT
|
||||||
|
// The robust tournament selection
|
||||||
|
eoDetTournament<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 mutation for bitstring
|
||||||
|
eoBinCrossover<Indi> xover;
|
||||||
|
// MUTATION
|
||||||
|
// standard bit-flip mutation for bitstring
|
||||||
|
eoBinMutation<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)
|
||||||
|
{
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
// rng.reseed(42);
|
||||||
|
int flag = _CrtSetDbgFlag(_CRTDBG_LEAK_CHECK_DF);
|
||||||
|
flag |= _CRTDBG_LEAK_CHECK_DF;
|
||||||
|
_CrtSetDbgFlag(flag);
|
||||||
|
// _CrtSetBreakAlloc(100);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
main_function(argc, argv);
|
||||||
|
}
|
||||||
|
catch(exception& e)
|
||||||
|
{
|
||||||
|
cout << "Exception: " << e.what() << '\n';
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
165
eo/tutorial/Lesson1/FirstRealGA.cpp
Normal file
165
eo/tutorial/Lesson1/FirstRealGA.cpp
Normal file
|
|
@ -0,0 +1,165 @@
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// FirstRealGA.cpp
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
//*
|
||||||
|
// An instance of a VERY simple Real-coded Genetic Algorithm
|
||||||
|
//
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// standard includes
|
||||||
|
#include <stdexcept> // runtime_error
|
||||||
|
#include <iostream> // cout
|
||||||
|
#include <strstream> // ostrstream, istrstream
|
||||||
|
|
||||||
|
// the general include for eo
|
||||||
|
|
||||||
|
#include <eo>
|
||||||
|
|
||||||
|
// 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
|
||||||
|
eoDetTournament<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)
|
||||||
|
eoArithmeticCrossover<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)
|
||||||
|
{
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
// rng.reseed(42);
|
||||||
|
int flag = _CrtSetDbgFlag(_CRTDBG_LEAK_CHECK_DF);
|
||||||
|
flag |= _CRTDBG_LEAK_CHECK_DF;
|
||||||
|
_CrtSetDbgFlag(flag);
|
||||||
|
// _CrtSetBreakAlloc(100);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
main_function(argc, argv);
|
||||||
|
}
|
||||||
|
catch(exception& e)
|
||||||
|
{
|
||||||
|
cout << "Exception: " << e.what() << '\n';
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
12
eo/tutorial/Lesson1/Makefile
Normal file
12
eo/tutorial/Lesson1/Makefile
Normal file
|
|
@ -0,0 +1,12 @@
|
||||||
|
.cpp: ; g++ -DPACKAGE=\"eo\" -DVERSION=\"0.9.1\" -I. -I../../src -Wall -g -o $@ $*.cpp ../../src/libeo.a ../../src/utils/libeoutils.a
|
||||||
|
|
||||||
|
.cpp.o: ; g++ -DPACKAGE=\"eo\" -DVERSION=\"0.9.1\" -I. -I../../src -Wall -g -c $*.cpp
|
||||||
|
|
||||||
|
firstGA = FirstRealGA FirstBitGA
|
||||||
|
|
||||||
|
ALL = $(firstGA) exercise3
|
||||||
|
|
||||||
|
lesson1 : $(firstGA)
|
||||||
|
|
||||||
|
clean :
|
||||||
|
@/bin/rm $(ALL) *.o *~
|
||||||
165
eo/tutorial/Lesson1/exercise3.cpp
Normal file
165
eo/tutorial/Lesson1/exercise3.cpp
Normal file
|
|
@ -0,0 +1,165 @@
|
||||||
|
#include <stdexcept> // runtime_error
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// FirstBitGA.cpp
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
//*
|
||||||
|
// An instance of a VERY simple Bitstring Genetic Algorithm
|
||||||
|
//
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// standard includes
|
||||||
|
|
||||||
|
#include <iostream> // cout
|
||||||
|
#include <strstream> // ostrstream, istrstream
|
||||||
|
|
||||||
|
// the general include for eo
|
||||||
|
|
||||||
|
#include <eo>
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// define your individuals
|
||||||
|
typedef eoBin<double> Indi; // A bitstring with fitness double
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
/** a simple fitness function that computes the number of ones of a bitstring
|
||||||
|
@param _indi A biststring individual
|
||||||
|
*/
|
||||||
|
|
||||||
|
double binary_value(const Indi & _indi)
|
||||||
|
{
|
||||||
|
double sum = 0;
|
||||||
|
for (unsigned i = 0; i < _indi.size(); i++)
|
||||||
|
sum += _indi[i];
|
||||||
|
return sum;
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
void main_function(int argc, char **argv)
|
||||||
|
{
|
||||||
|
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
|
||||||
|
// eoProportional<Indi> select;
|
||||||
|
|
||||||
|
// could also use stochastic binary tournament selection
|
||||||
|
//
|
||||||
|
// const double RATE = 0.75;
|
||||||
|
// eoStochTournament<Indi> select(RATE); // RATE in ]0.5,1]
|
||||||
|
// The robust tournament selection
|
||||||
|
const unsigned int T_SIZE = 3; // size for tournament selection
|
||||||
|
eoDetTournament<Indi> select(T_SIZE); // T_SIZE in [2,POP_SIZE]
|
||||||
|
|
||||||
|
// and of course the random selection
|
||||||
|
// eoSelectRandom<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
|
||||||
|
eoBinMutation<Indi> mutation(P_MUT_PER_BIT);
|
||||||
|
// 1-point mutation for bitstring
|
||||||
|
eoBinCrossover<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)
|
||||||
|
{
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
// rng.reseed(42);
|
||||||
|
int flag = _CrtSetDbgFlag(_CRTDBG_LEAK_CHECK_DF);
|
||||||
|
flag |= _CRTDBG_LEAK_CHECK_DF;
|
||||||
|
_CrtSetDbgFlag(flag);
|
||||||
|
// _CrtSetBreakAlloc(100);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
main_function(argc, argv);
|
||||||
|
}
|
||||||
|
catch(exception& e)
|
||||||
|
{
|
||||||
|
cout << "Exception: " << e.what() << '\n';
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
193
eo/tutorial/Lesson2/FirstBitEA.cpp
Normal file
193
eo/tutorial/Lesson2/FirstBitEA.cpp
Normal 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
|
||||||
|
//
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// standard includes
|
||||||
|
#include <stdexcept> // runtime_error
|
||||||
|
#include <iostream> // cout
|
||||||
|
#include <strstream> // ostrstream, istrstream
|
||||||
|
|
||||||
|
// the general include for eo
|
||||||
|
#include <eo>
|
||||||
|
|
||||||
|
// REPRESENTATION
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// define your individuals
|
||||||
|
typedef eoBin<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/rnd_generator.h)
|
||||||
|
eoInitFixedLength<Indi, boolean_generator>
|
||||||
|
random(VEC_SIZE, boolean_generator());
|
||||||
|
// Initialization of the population
|
||||||
|
eoPop<Indi> pop(POP_SIZE, random);
|
||||||
|
|
||||||
|
// and evaluate it in one loop
|
||||||
|
apply<Indi>(eval, pop); // STL syntax
|
||||||
|
|
||||||
|
// OUTPUT
|
||||||
|
// sort pop before printing it!
|
||||||
|
pop.sort();
|
||||||
|
// Print (sorted) intial population (raw printout)
|
||||||
|
cout << "Initial Population" << endl;
|
||||||
|
cout << pop;
|
||||||
|
|
||||||
|
// ENGINE
|
||||||
|
/////////////////////////////////////
|
||||||
|
// selection and replacement
|
||||||
|
////////////////////////////////////
|
||||||
|
// SELECT
|
||||||
|
// The robust tournament selection
|
||||||
|
eoDetTournament<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 :-)
|
||||||
|
eoNoReplacement<Indi> replace;
|
||||||
|
|
||||||
|
// OPERATORS
|
||||||
|
//////////////////////////////////////
|
||||||
|
// The variation operators
|
||||||
|
//////////////////////////////////////
|
||||||
|
// CROSSOVER
|
||||||
|
// 1-point crossover for bitstring
|
||||||
|
eoBinCrossover<Indi> xover1;
|
||||||
|
// uniform crossover for bitstring
|
||||||
|
eoBinUxOver<Indi> xoverU;
|
||||||
|
// 2-pots xover
|
||||||
|
eoBinNxOver<Indi> xover2(2);
|
||||||
|
// Combine them with relative rates
|
||||||
|
eoPropCombinedQuadOp<Indi> xover(xover1, onePointRate);
|
||||||
|
xover.add(xoverU, URate);
|
||||||
|
xover.add(xover2, twoPointsRate, true);
|
||||||
|
|
||||||
|
// MUTATION
|
||||||
|
// standard bit-flip mutation for bitstring
|
||||||
|
eoBinMutation<Indi> mutationBitFlip(P_MUT_PER_BIT);
|
||||||
|
// mutate exactly 1 bit per individual
|
||||||
|
eoDetBitFlip<Indi> mutationOneBit;
|
||||||
|
// Combine them with relative rates
|
||||||
|
eoPropCombinedMonOp<Indi> mutation(mutationBitFlip, bitFlipRate);
|
||||||
|
mutation.add(mutationOneBit, oneBitRate, true);
|
||||||
|
|
||||||
|
// The operators are encapsulated into an eoTRansform object
|
||||||
|
eoSGATransform<Indi> transform(xover, 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)
|
||||||
|
{
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
// rng.reseed(42);
|
||||||
|
int flag = _CrtSetDbgFlag(_CRTDBG_LEAK_CHECK_DF);
|
||||||
|
flag |= _CRTDBG_LEAK_CHECK_DF;
|
||||||
|
_CrtSetDbgFlag(flag);
|
||||||
|
// _CrtSetBreakAlloc(100);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
main_function(argc, argv);
|
||||||
|
}
|
||||||
|
catch(exception& e)
|
||||||
|
{
|
||||||
|
cout << "Exception: " << e.what() << '\n';
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
188
eo/tutorial/Lesson2/FirstRealEA.cpp
Normal file
188
eo/tutorial/Lesson2/FirstRealEA.cpp
Normal file
|
|
@ -0,0 +1,188 @@
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// FirstRealEA.cpp
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
//*
|
||||||
|
// Still an instance of a VERY simple Real-coded Genetic Algorithm
|
||||||
|
// (see FirstBitGA.cpp) but now with Breeder - and Combined Ops
|
||||||
|
//
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// standard includes
|
||||||
|
#include <stdexcept> // runtime_error
|
||||||
|
#include <iostream> // cout
|
||||||
|
#include <strstream> // ostrstream, istrstream
|
||||||
|
|
||||||
|
// the general include for eo
|
||||||
|
#include <eo>
|
||||||
|
|
||||||
|
// REPRESENTATION
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// define your individuals
|
||||||
|
typedef eoReal<double> Indi;
|
||||||
|
|
||||||
|
// EVALFUNC
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// a simple fitness function that computes the euclidian norm of a real vector
|
||||||
|
// Now in a separate file, and declared as binary_value(const vector<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
|
||||||
|
// some parameters for chosing among different operators
|
||||||
|
const double segmentRate = 0.5; // rate for 1-pt Xover
|
||||||
|
const double arithmeticRate = 0.5; // rate for 2-pt Xover
|
||||||
|
const double uniformMutRate = 0.5; // rate for bit-flip mutation
|
||||||
|
const double detMutRate = 0.5; // rate for one-bit mutation
|
||||||
|
|
||||||
|
// GENERAL
|
||||||
|
//////////////////////////
|
||||||
|
// Random seed
|
||||||
|
//////////////////////////
|
||||||
|
//reproducible random seed: if you don't change SEED above,
|
||||||
|
// you'll aways get the same result, NOT a random run
|
||||||
|
rng.reseed(SEED);
|
||||||
|
|
||||||
|
// EVAL
|
||||||
|
/////////////////////////////
|
||||||
|
// Fitness function
|
||||||
|
////////////////////////////
|
||||||
|
// Evaluation: from a plain C++ fn to an EvalFunc Object
|
||||||
|
// you need to give the full description of the function
|
||||||
|
eoEvalFuncPtr<Indi, double, const vector<double>& > eval( real_value );
|
||||||
|
|
||||||
|
// INIT
|
||||||
|
////////////////////////////////
|
||||||
|
// Initilisation of population
|
||||||
|
////////////////////////////////
|
||||||
|
// based on a uniform generator
|
||||||
|
eoInitFixedLength<Indi, uniform_generator<double> >
|
||||||
|
random(VEC_SIZE, uniform_generator<double>(-1.0, 1.0));
|
||||||
|
// Initialization of the population
|
||||||
|
eoPop<Indi> pop(POP_SIZE, random);
|
||||||
|
|
||||||
|
// and evaluate it in one loop
|
||||||
|
apply<Indi>(eval, pop); // STL syntax
|
||||||
|
|
||||||
|
// OUTPUT
|
||||||
|
// sort pop before printing it!
|
||||||
|
pop.sort();
|
||||||
|
// Print (sorted) intial population (raw printout)
|
||||||
|
cout << "Initial Population" << endl;
|
||||||
|
cout << pop;
|
||||||
|
|
||||||
|
// ENGINE
|
||||||
|
/////////////////////////////////////
|
||||||
|
// selection and replacement
|
||||||
|
////////////////////////////////////
|
||||||
|
// SELECT
|
||||||
|
// The robust tournament selection
|
||||||
|
eoDetTournament<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 :-)
|
||||||
|
eoNoReplacement<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
|
||||||
|
eoArithmeticCrossover<Indi> xoverA;
|
||||||
|
// Combine them with relative rates
|
||||||
|
eoPropCombinedQuadOp<Indi> xover(xoverS, segmentRate);
|
||||||
|
xover.add(xoverA, arithmeticRate, 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);
|
||||||
|
// Combine them with relative rates
|
||||||
|
eoPropCombinedMonOp<Indi> mutation(mutationU, uniformMutRate);
|
||||||
|
mutation.add(mutationD, detMutRate, 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)
|
||||||
|
{
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
// rng.reseed(42);
|
||||||
|
int flag = _CrtSetDbgFlag(_CRTDBG_LEAK_CHECK_DF);
|
||||||
|
flag |= _CRTDBG_LEAK_CHECK_DF;
|
||||||
|
_CrtSetDbgFlag(flag);
|
||||||
|
// _CrtSetBreakAlloc(100);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
main_function(argc, argv);
|
||||||
|
}
|
||||||
|
catch(exception& e)
|
||||||
|
{
|
||||||
|
cout << "Exception: " << e.what() << '\n';
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
12
eo/tutorial/Lesson2/Makefile
Normal file
12
eo/tutorial/Lesson2/Makefile
Normal file
|
|
@ -0,0 +1,12 @@
|
||||||
|
.cpp: ; g++ -DPACKAGE=\"eo\" -DVERSION=\"0.9.1\" -I. -I../../src -Wall -g -o $@ $*.cpp ../../src/libeo.a ../../src/utils/libeoutils.a
|
||||||
|
|
||||||
|
.cpp.o: ; g++ -DPACKAGE=\"eo\" -DVERSION=\"0.9.1\" -I. -I../../src -Wall -g -c $*.cpp
|
||||||
|
|
||||||
|
firstEA = FirstRealEA FirstBitEA
|
||||||
|
|
||||||
|
ALL = $(firstEA) exercise1 exercise2 exercise3
|
||||||
|
|
||||||
|
lesson2 : $(firstEA)
|
||||||
|
|
||||||
|
clean :
|
||||||
|
@/bin/rm $(ALL) *.o *~
|
||||||
17
eo/tutorial/Lesson2/binary_value.h
Normal file
17
eo/tutorial/Lesson2/binary_value.h
Normal 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 vector<bool>& _chrom)
|
||||||
|
{
|
||||||
|
double sum = 0;
|
||||||
|
for (unsigned i = 0; i < _chrom.size(); i++)
|
||||||
|
sum += _chrom[i];
|
||||||
|
return sum;
|
||||||
|
}
|
||||||
|
|
||||||
195
eo/tutorial/Lesson2/exercise3.cpp
Normal file
195
eo/tutorial/Lesson2/exercise3.cpp
Normal file
|
|
@ -0,0 +1,195 @@
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// FirstBitEA.cpp
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
//*
|
||||||
|
// Still an instance of a VERY simple Bitstring Genetic Algorithm
|
||||||
|
// (see FirstBitGA.cpp) but now with Breeder - and Combined Ops
|
||||||
|
//
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// standard includes
|
||||||
|
#include <stdexcept> // runtime_error
|
||||||
|
#include <iostream> // cout
|
||||||
|
#include <strstream> // ostrstream, istrstream
|
||||||
|
|
||||||
|
// the general include for eo
|
||||||
|
#include <eo>
|
||||||
|
|
||||||
|
// REPRESENTATION
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// define your individuals
|
||||||
|
typedef eoBin<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
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
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/rnd_generator.h)
|
||||||
|
eoInitFixedLength<Indi, boolean_generator>
|
||||||
|
random(VEC_SIZE, boolean_generator());
|
||||||
|
// Initialization of the population
|
||||||
|
eoPop<Indi> pop(POP_SIZE, random);
|
||||||
|
|
||||||
|
// and evaluate it in one loop
|
||||||
|
apply<Indi>(eval, pop); // STL syntax
|
||||||
|
|
||||||
|
// OUTPUT
|
||||||
|
// sort pop before printing it!
|
||||||
|
pop.sort();
|
||||||
|
// Print (sorted) intial population (raw printout)
|
||||||
|
cout << "Initial Population" << endl;
|
||||||
|
cout << pop;
|
||||||
|
|
||||||
|
// ENGINE
|
||||||
|
/////////////////////////////////////
|
||||||
|
// selection and replacement
|
||||||
|
////////////////////////////////////
|
||||||
|
// SELECT
|
||||||
|
// The robust tournament selection
|
||||||
|
eoDetTournament<Indi> selectOne(T_SIZE); // T_SIZE in [2,POP_SIZE]
|
||||||
|
// solution solution solution solution solution solution solution
|
||||||
|
// modify the rate in the constructor
|
||||||
|
eoSelectPerc<Indi> select(selectOne,2.0);// rate is second arg.
|
||||||
|
|
||||||
|
// REPLACE
|
||||||
|
// solution solution solution solution solution solution solution
|
||||||
|
// eoCommaReplacement keeps the best among offspring
|
||||||
|
// eoPlusReplacement keeps the best among parents + offspring
|
||||||
|
// eoCommaReplacement<Indi> replace;
|
||||||
|
eoPlusReplacement<Indi> replace;
|
||||||
|
|
||||||
|
// OPERATORS
|
||||||
|
//////////////////////////////////////
|
||||||
|
// The variation operators
|
||||||
|
//////////////////////////////////////
|
||||||
|
// CROSSOVER
|
||||||
|
// 1-point crossover for bitstring
|
||||||
|
eoBinCrossover<Indi> xover1;
|
||||||
|
// uniform crossover for bitstring
|
||||||
|
eoBinUxOver<Indi> xoverU;
|
||||||
|
// 2-pots xover
|
||||||
|
eoBinNxOver<Indi> xover2(2);
|
||||||
|
// Combine them with relative rates
|
||||||
|
eoPropCombinedQuadOp<Indi> xover(xover1, onePointRate);
|
||||||
|
xover.add(xoverU, URate);
|
||||||
|
xover.add(xover2, twoPointsRate, true);
|
||||||
|
|
||||||
|
// MUTATION
|
||||||
|
// standard bit-flip mutation for bitstring
|
||||||
|
eoBinMutation<Indi> mutationBitFlip(P_MUT_PER_BIT);
|
||||||
|
// mutate exactly 1 bit per individual
|
||||||
|
eoDetBitFlip<Indi> mutationOneBit;
|
||||||
|
// Combine them with relative rates
|
||||||
|
eoPropCombinedMonOp<Indi> mutation(mutationBitFlip, bitFlipRate);
|
||||||
|
mutation.add(mutationOneBit, oneBitRate, true);
|
||||||
|
|
||||||
|
// The operators are encapsulated into an eoTRansform object
|
||||||
|
eoSGATransform<Indi> transform(xover, 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)
|
||||||
|
{
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
// rng.reseed(42);
|
||||||
|
int flag = _CrtSetDbgFlag(_CRTDBG_LEAK_CHECK_DF);
|
||||||
|
flag |= _CRTDBG_LEAK_CHECK_DF;
|
||||||
|
_CrtSetDbgFlag(flag);
|
||||||
|
// _CrtSetBreakAlloc(100);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
main_function(argc, argv);
|
||||||
|
}
|
||||||
|
catch(exception& e)
|
||||||
|
{
|
||||||
|
cout << "Exception: " << e.what() << '\n';
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
18
eo/tutorial/Lesson2/real_value.h
Normal file
18
eo/tutorial/Lesson2/real_value.h
Normal file
|
|
@ -0,0 +1,18 @@
|
||||||
|
#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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
12
eo/tutorial/Lesson3/Makefile
Normal file
12
eo/tutorial/Lesson3/Makefile
Normal file
|
|
@ -0,0 +1,12 @@
|
||||||
|
.cpp: ; g++ -DPACKAGE=\"eo\" -DVERSION=\"0.9.1\" -I. -I../../src -Wall -g -o $@ $*.cpp ../../src/libeo.a ../../src/utils/libeoutils.a
|
||||||
|
|
||||||
|
.cpp.o: ; g++ -DPACKAGE=\"eo\" -DVERSION=\"0.9.1\" -I. -I../../src -Wall -g -c $*.cpp
|
||||||
|
|
||||||
|
secondEA = SecondBitEA
|
||||||
|
|
||||||
|
ALL = $(secondEA) exercise1 exercise2 exercise3
|
||||||
|
|
||||||
|
lesson3 : $(secondEA)
|
||||||
|
|
||||||
|
clean :
|
||||||
|
@/bin/rm $(ALL) *.o *.sav *.xg *.status *~
|
||||||
375
eo/tutorial/Lesson3/SecondBitEA.cpp
Normal file
375
eo/tutorial/Lesson3/SecondBitEA.cpp
Normal file
|
|
@ -0,0 +1,375 @@
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// SecondGA.cpp
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
//*
|
||||||
|
// Same code than FirstBitEA as far as Evolutionary Computation is concerned
|
||||||
|
// but now you learn to enter the parameters in a more flexible way
|
||||||
|
// and to twidle the output to your preferences!
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// standard includes
|
||||||
|
#include <stdexcept> // runtime_error
|
||||||
|
#include <iostream> // cout
|
||||||
|
#include <strstream> // ostrstream, istrstream
|
||||||
|
#include <fstream>
|
||||||
|
|
||||||
|
// the general include for eo
|
||||||
|
#include <eo>
|
||||||
|
|
||||||
|
// EVAL
|
||||||
|
#include "binary_value.h"
|
||||||
|
|
||||||
|
// REPRESENTATION
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// define your genotype and fitness types
|
||||||
|
typedef eoBin<double> Indi;
|
||||||
|
|
||||||
|
// PARAMETRES
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// instead of having all values of useful parameters as constants, read them:
|
||||||
|
// either on the command line (--option=value or -o=value)
|
||||||
|
// or in a parameter file (same syntax, order independent,
|
||||||
|
// # = usual comment character
|
||||||
|
// or in the environment (TODO)
|
||||||
|
|
||||||
|
// note that the parameters are passed by reference so they can be updated
|
||||||
|
void read_param(int argc, char *argv[],
|
||||||
|
uint32 & _seed,
|
||||||
|
unsigned int & _vecSize,
|
||||||
|
unsigned int & _popSize,
|
||||||
|
unsigned int & _tSize,
|
||||||
|
double & _pCross,
|
||||||
|
double & _pMut,
|
||||||
|
string & _load_name,
|
||||||
|
unsigned int & _maxGen,
|
||||||
|
unsigned int & _minGen,
|
||||||
|
unsigned int & _steadyGen,
|
||||||
|
double & _onePointRate,
|
||||||
|
double & _twoPointsRate,
|
||||||
|
double & _uRate,
|
||||||
|
double & _pMutPerBit,
|
||||||
|
double & _bitFlipRate,
|
||||||
|
double & _oneBitRate
|
||||||
|
)
|
||||||
|
{
|
||||||
|
// define a parser from the command-line arguments
|
||||||
|
eoParser parser(argc, argv);
|
||||||
|
|
||||||
|
// For each parameter, define Parameters directly in the parser,
|
||||||
|
// and assign the value to the variable
|
||||||
|
eoValueParam<uint32>& seedParam = parser.createParam<uint32>(time(0), "seed", "Random number seed", 'S');
|
||||||
|
_seed = seedParam.value();
|
||||||
|
|
||||||
|
eoValueParam<unsigned int>& vecSizeParam = parser.createParam<unsigned int>(8, "vecSize", "Genotype size",'V', "Representation");
|
||||||
|
_vecSize = vecSizeParam.value();
|
||||||
|
|
||||||
|
eoValueParam<unsigned int>& popSizeParam = parser.createParam<unsigned int>(10, "popSize", "Population size",'P', "Evolution");
|
||||||
|
_popSize = popSizeParam.value();
|
||||||
|
|
||||||
|
eoValueParam<unsigned int>& tSizeParam = parser.createParam<unsigned int>(10, "tSize", "Tournament size",'T', "Evolution");
|
||||||
|
_tSize = tSizeParam.value();
|
||||||
|
|
||||||
|
eoValueParam<string>& load_nameParam = parser.createParam<string>("", "Load","A save file to restart from",'L', "Persistence");
|
||||||
|
_load_name = load_nameParam.value();
|
||||||
|
|
||||||
|
eoValueParam<unsigned int>& maxGenParam = parser.createParam<unsigned int>(100, "maxGen", "Maximum number of generations",'G', "Stopping criterion");
|
||||||
|
_maxGen = maxGenParam.value();
|
||||||
|
|
||||||
|
eoValueParam<unsigned int>& minGenParam = parser.createParam<unsigned int>(100, "minGen", "Minimum number of generations",'g', "Stopping criterion");
|
||||||
|
_minGen = minGenParam.value();
|
||||||
|
|
||||||
|
eoValueParam<unsigned int>& steadyGenParam = parser.createParam<unsigned int>(100, "steadyGen", "Number of generations with no improvement",'s', "Stopping criterion");
|
||||||
|
_steadyGen = steadyGenParam.value();
|
||||||
|
|
||||||
|
eoValueParam<double>& pCrossParam = parser.createParam<double>(0.6, "pCross", "Probability of Crossover", 'C', "Genetic Operators");
|
||||||
|
_pCross = pCrossParam.value();
|
||||||
|
|
||||||
|
eoValueParam<double>& pMutParam = parser.createParam<double>(0.1, "pMut", "Probability of Mutation", 'M', "Genetic Operators");
|
||||||
|
_pMut = pMutParam.value();
|
||||||
|
|
||||||
|
eoValueParam<double>& onePointRateParam = parser.createParam<double>(1, "onePointRate", "Relative rate for one point crossover", '1', "Genetic Operators");
|
||||||
|
_onePointRate = onePointRateParam.value();
|
||||||
|
|
||||||
|
eoValueParam<double>& twoPointsRateParam = parser.createParam<double>(1, "twoPointRate", "Relative rate for two point crossover", '2', "Genetic Operators");
|
||||||
|
_twoPointsRate = twoPointsRateParam.value();
|
||||||
|
|
||||||
|
eoValueParam<double>& uRateParam = parser.createParam<double>(2, "uRate", "Relative rate for uniform crossover", 'U', "Genetic Operators");
|
||||||
|
_uRate = uRateParam.value();
|
||||||
|
|
||||||
|
eoValueParam<double>& pMutPerBitParam = parser.createParam<double>(0.01, "pMutPerBit", "Probability of flipping 1 bit in bit-flip mutation", 'b', "Genetic Operators");
|
||||||
|
_pMutPerBit = pMutPerBitParam.value();
|
||||||
|
|
||||||
|
eoValueParam<double>& bitFlipRateParam = parser.createParam<double>(0.01, "bitFlipRate", "Relative rate for bit-flip mutation", 'B', "Genetic Operators");
|
||||||
|
_bitFlipRate = bitFlipRateParam.value();
|
||||||
|
|
||||||
|
eoValueParam<double>& oneBitRateParam = parser.createParam<double>(0.01, "oneBitRate", "Relative rate for deterministic bit-flip mutation", 'D', "Genetic Operators");
|
||||||
|
_oneBitRate = oneBitRateParam.value();
|
||||||
|
|
||||||
|
// the name of the "status" file where all actual parameter values will be saved
|
||||||
|
string str_status = parser.ProgramName() + ".status";
|
||||||
|
eoValueParam<string>& status_nameParam = parser.createParam<string>(str_status.c_str(), "status","Status file",'S', "Persistence");
|
||||||
|
|
||||||
|
// do the following AFTER ALL PARAMETERS HAVE BEEN PROCESSED
|
||||||
|
// i.e. in case you need parameters somewhere else, postpone these
|
||||||
|
if (parser.userNeedsHelp())
|
||||||
|
{
|
||||||
|
parser.printHelp(cout);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
if (status_nameParam.value() != "")
|
||||||
|
{
|
||||||
|
ofstream os(status_nameParam.value().c_str());
|
||||||
|
os << parser; // and you can use that file as parameter file
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// GENERAL
|
||||||
|
// now the main_function: nothing changed, except input/output
|
||||||
|
void main_function(int argc, char **argv)
|
||||||
|
{
|
||||||
|
// PARAMETRES
|
||||||
|
uint32 seed;
|
||||||
|
// decription of genotype
|
||||||
|
unsigned int vecSize;
|
||||||
|
// parameters for evolution engine
|
||||||
|
unsigned int popSize;
|
||||||
|
unsigned int tSize;
|
||||||
|
// operators probabilities at the algorithm level
|
||||||
|
double pCross;
|
||||||
|
double pMut;
|
||||||
|
// init and stop
|
||||||
|
string load_name;
|
||||||
|
unsigned int maxGen;
|
||||||
|
unsigned int minGen;
|
||||||
|
unsigned int steadyGen;
|
||||||
|
// rates for crossovers
|
||||||
|
double onePointRate;
|
||||||
|
double twoPointsRate;
|
||||||
|
double URate;
|
||||||
|
// rates and private parameters for mutations;
|
||||||
|
double pMutPerBit;
|
||||||
|
double bitFlipRate;
|
||||||
|
double oneBitRate;
|
||||||
|
|
||||||
|
// Now read the parameters of the program
|
||||||
|
read_param(argc, argv, seed, vecSize, popSize, tSize,
|
||||||
|
pCross, pMut, load_name, maxGen, minGen, steadyGen,
|
||||||
|
onePointRate, twoPointsRate, URate,
|
||||||
|
pMutPerBit, bitFlipRate, oneBitRate );
|
||||||
|
|
||||||
|
// EVAL
|
||||||
|
/////////////////////////////
|
||||||
|
// Fitness function
|
||||||
|
////////////////////////////
|
||||||
|
// Evaluation: from a plain C++ fn to an EvalFunc Object ...
|
||||||
|
eoEvalFuncPtr<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 (load_name != "")
|
||||||
|
{
|
||||||
|
inState.load(load_name); // load the pop and the rng
|
||||||
|
// the fitness is read in the file:
|
||||||
|
// do only evaluate the pop if the fitness has changed
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
rng.reseed(seed);
|
||||||
|
// a Indi random initializer
|
||||||
|
// based on boolean_generator class (see utils/rnd_generator.h)
|
||||||
|
eoInitFixedLength<Indi, boolean_generator>
|
||||||
|
random(vecSize, boolean_generator());
|
||||||
|
|
||||||
|
// Init pop from the randomizer: need to use the append function
|
||||||
|
pop.append(popSize, random);
|
||||||
|
// and evaluate pop (STL syntax)
|
||||||
|
apply<Indi>(eval, pop);
|
||||||
|
} // end of initializatio of the population
|
||||||
|
|
||||||
|
// OUTPUT
|
||||||
|
// sort pop for pretty printout
|
||||||
|
pop.sort();
|
||||||
|
// Print (sorted) intial population (raw printout)
|
||||||
|
cout << "Initial Population" << endl << pop << endl;
|
||||||
|
|
||||||
|
// ENGINE
|
||||||
|
/////////////////////////////////////
|
||||||
|
// selection and replacement
|
||||||
|
////////////////////////////////////
|
||||||
|
// SELECT
|
||||||
|
// The robust tournament selection
|
||||||
|
eoDetTournament<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
|
||||||
|
// no replacement (== generational replacement) at the moment :-)
|
||||||
|
eoNoReplacement<Indi> replace;
|
||||||
|
|
||||||
|
// OPERATORS
|
||||||
|
//////////////////////////////////////
|
||||||
|
// The variation operators
|
||||||
|
//////////////////////////////////////
|
||||||
|
// CROSSOVER
|
||||||
|
// 1-point crossover for bitstring
|
||||||
|
eoBinCrossover<Indi> xover1;
|
||||||
|
// uniform crossover for bitstring
|
||||||
|
eoBinUxOver<Indi> xoverU;
|
||||||
|
// 2-pots xover
|
||||||
|
eoBinNxOver<Indi> xover2(2);
|
||||||
|
// Combine them with relative rates
|
||||||
|
eoPropCombinedQuadOp<Indi> xover(xover1, onePointRate);
|
||||||
|
xover.add(xoverU, URate);
|
||||||
|
xover.add(xover2, twoPointsRate, true);
|
||||||
|
|
||||||
|
// MUTATION
|
||||||
|
// standard bit-flip mutation for bitstring
|
||||||
|
eoBinMutation<Indi> mutationBitFlip(pMutPerBit);
|
||||||
|
// mutate exactly 1 bit per individual
|
||||||
|
eoDetBitFlip<Indi> mutationOneBit;
|
||||||
|
// Combine them with relative rates
|
||||||
|
eoPropCombinedMonOp<Indi> mutation(mutationBitFlip, bitFlipRate);
|
||||||
|
mutation.add(mutationOneBit, oneBitRate, true);
|
||||||
|
|
||||||
|
// The operators are encapsulated into an eoTRansform object
|
||||||
|
eoSGATransform<Indi> transform(xover, pCross, mutation, pMut);
|
||||||
|
|
||||||
|
// 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(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)
|
||||||
|
{
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
int flag = _CrtSetDbgFlag(_CRTDBG_LEAK_CHECK_DF);
|
||||||
|
flag |= _CRTDBG_LEAK_CHECK_DF;
|
||||||
|
_CrtSetDbgFlag(flag);
|
||||||
|
// _CrtSetBreakAlloc(100);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
main_function(argc, argv);
|
||||||
|
}
|
||||||
|
catch(exception& e)
|
||||||
|
{
|
||||||
|
cout << "Exception: " << e.what() << '\n';
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
17
eo/tutorial/Lesson3/binary_value.h
Normal file
17
eo/tutorial/Lesson3/binary_value.h
Normal 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 vector<bool>& _chrom)
|
||||||
|
{
|
||||||
|
double sum = 0;
|
||||||
|
for (unsigned i = 0; i < _chrom.size(); i++)
|
||||||
|
sum += _chrom[i];
|
||||||
|
return sum;
|
||||||
|
}
|
||||||
|
|
||||||
384
eo/tutorial/Lesson3/exercise1.cpp
Normal file
384
eo/tutorial/Lesson3/exercise1.cpp
Normal file
|
|
@ -0,0 +1,384 @@
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// SecondBitGA.cpp
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
//*
|
||||||
|
// Same code than FirstBitEA as far as Evolutionary Computation is concerned
|
||||||
|
// but now you learn to enter the parameters in a more flexible way
|
||||||
|
// and to twidle the output to your preferences!
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// standard includes
|
||||||
|
#include <stdexcept> // runtime_error
|
||||||
|
#include <iostream> // cout
|
||||||
|
#include <strstream> // ostrstream, istrstream
|
||||||
|
#include <fstream>
|
||||||
|
|
||||||
|
// the general include for eo
|
||||||
|
#include <eo>
|
||||||
|
#include <utils/eoGnuplot1DMonitor.h>
|
||||||
|
|
||||||
|
// EVAL
|
||||||
|
#include "binary_value.h"
|
||||||
|
|
||||||
|
// REPRESENTATION
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// define your genotype and fitness types
|
||||||
|
typedef eoBin<double> Indi;
|
||||||
|
|
||||||
|
// PARAMETRES
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// instead of having all values of useful parameters as constants, read them:
|
||||||
|
// either on the command line (--option=value or -o=value)
|
||||||
|
// or in a parameter file (same syntax, order independent,
|
||||||
|
// # = usual comment character
|
||||||
|
// or in the environment (TODO)
|
||||||
|
|
||||||
|
// note that the parameters are passed by reference so they can be updated
|
||||||
|
void read_param(int argc, char *argv[],
|
||||||
|
uint32 & _seed,
|
||||||
|
unsigned int & _vecSize,
|
||||||
|
unsigned int & _popSize,
|
||||||
|
unsigned int & _tSize,
|
||||||
|
double & _pCross,
|
||||||
|
double & _pMut,
|
||||||
|
string & _load_name,
|
||||||
|
unsigned int & _maxGen,
|
||||||
|
unsigned int & _minGen,
|
||||||
|
unsigned int & _steadyGen,
|
||||||
|
double & _onePointRate,
|
||||||
|
double & _twoPointsRate,
|
||||||
|
double & _uRate,
|
||||||
|
double & _pMutPerBit,
|
||||||
|
double & _bitFlipRate,
|
||||||
|
double & _oneBitRate
|
||||||
|
)
|
||||||
|
{
|
||||||
|
// define a parser from the command-line arguments
|
||||||
|
eoParser parser(argc, argv);
|
||||||
|
|
||||||
|
// For each parameter, define Parameters directly in the parser,
|
||||||
|
// and assign the value to the variable
|
||||||
|
eoValueParam<uint32>& seedParam = parser.createParam<uint32>(time(0), "seed", "Random number seed", 'S');
|
||||||
|
_seed = seedParam.value();
|
||||||
|
|
||||||
|
eoValueParam<unsigned int>& vecSizeParam = parser.createParam<unsigned int>(8, "vecSize", "Genotype size",'V', "Representation");
|
||||||
|
_vecSize = vecSizeParam.value();
|
||||||
|
|
||||||
|
eoValueParam<unsigned int>& popSizeParam = parser.createParam<unsigned int>(10, "popSize", "Population size",'P', "Evolution");
|
||||||
|
_popSize = popSizeParam.value();
|
||||||
|
|
||||||
|
eoValueParam<unsigned int>& tSizeParam = parser.createParam<unsigned int>(10, "tSize", "Tournament size",'T', "Evolution");
|
||||||
|
_tSize = tSizeParam.value();
|
||||||
|
|
||||||
|
eoValueParam<string>& load_nameParam = parser.createParam<string>("", "Load","A save file to restart from",'L', "Persistence");
|
||||||
|
_load_name = load_nameParam.value();
|
||||||
|
|
||||||
|
eoValueParam<unsigned int>& maxGenParam = parser.createParam<unsigned int>(100, "maxGen", "Maximum number of generations",'G', "Stopping criterion");
|
||||||
|
_maxGen = maxGenParam.value();
|
||||||
|
|
||||||
|
eoValueParam<unsigned int>& minGenParam = parser.createParam<unsigned int>(100, "minGen", "Minimum number of generations",'g', "Stopping criterion");
|
||||||
|
_minGen = minGenParam.value();
|
||||||
|
|
||||||
|
eoValueParam<unsigned int>& steadyGenParam = parser.createParam<unsigned int>(100, "steadyGen", "Number of generations with no improvement",'s', "Stopping criterion");
|
||||||
|
_steadyGen = steadyGenParam.value();
|
||||||
|
|
||||||
|
eoValueParam<double>& pCrossParam = parser.createParam<double>(0.6, "pCross", "Probability of Crossover", 'C', "Genetic Operators");
|
||||||
|
_pCross = pCrossParam.value();
|
||||||
|
|
||||||
|
eoValueParam<double>& pMutParam = parser.createParam<double>(0.1, "pMut", "Probability of Mutation", 'M', "Genetic Operators");
|
||||||
|
_pMut = pMutParam.value();
|
||||||
|
|
||||||
|
eoValueParam<double>& onePointRateParam = parser.createParam<double>(1, "onePointRate", "Relative rate for one point crossover", '1', "Genetic Operators");
|
||||||
|
_onePointRate = onePointRateParam.value();
|
||||||
|
|
||||||
|
eoValueParam<double>& twoPointsRateParam = parser.createParam<double>(1, "twoPointRate", "Relative rate for two point crossover", '2', "Genetic Operators");
|
||||||
|
_twoPointsRate = twoPointsRateParam.value();
|
||||||
|
|
||||||
|
eoValueParam<double>& uRateParam = parser.createParam<double>(2, "uRate", "Relative rate for uniform crossover", 'U', "Genetic Operators");
|
||||||
|
_uRate = uRateParam.value();
|
||||||
|
|
||||||
|
eoValueParam<double>& pMutPerBitParam = parser.createParam<double>(0.01, "pMutPerBit", "Probability of flipping 1 bit in bit-flip mutation", 'b', "Genetic Operators");
|
||||||
|
_pMutPerBit = pMutPerBitParam.value();
|
||||||
|
|
||||||
|
eoValueParam<double>& bitFlipRateParam = parser.createParam<double>(0.01, "bitFlipRate", "Relative rate for bit-flip mutation", 'B', "Genetic Operators");
|
||||||
|
_bitFlipRate = bitFlipRateParam.value();
|
||||||
|
|
||||||
|
eoValueParam<double>& oneBitRateParam = parser.createParam<double>(0.01, "oneBitRate", "Relative rate for deterministic bit-flip mutation", 'D', "Genetic Operators");
|
||||||
|
_oneBitRate = oneBitRateParam.value();
|
||||||
|
|
||||||
|
// the name of the "status" file where all actual parameter values will be saved
|
||||||
|
string str_status = parser.ProgramName() + ".status";
|
||||||
|
eoValueParam<string>& status_nameParam = parser.createParam<string>(str_status.c_str(), "status","Status file",'S', "Persistence");
|
||||||
|
|
||||||
|
// do the following AFTER ALL PARAMETERS HAVE BEEN PROCESSED
|
||||||
|
// i.e. in case you need parameters somewhere else, postpone these
|
||||||
|
if (parser.userNeedsHelp())
|
||||||
|
{
|
||||||
|
parser.printHelp(cout);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
if (status_nameParam.value() != "")
|
||||||
|
{
|
||||||
|
ofstream os(status_nameParam.value().c_str());
|
||||||
|
os << parser; // and you can use that file as parameter file
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// GENERAL
|
||||||
|
// now the main_function: nothing changed, except input/output
|
||||||
|
void main_function(int argc, char **argv)
|
||||||
|
{
|
||||||
|
// PARAMETRES
|
||||||
|
uint32 seed;
|
||||||
|
// decription of genotype
|
||||||
|
unsigned int vecSize;
|
||||||
|
// parameters for evolution engine
|
||||||
|
unsigned int popSize;
|
||||||
|
unsigned int tSize;
|
||||||
|
// operators probabilities at the algorithm level
|
||||||
|
double pCross;
|
||||||
|
double pMut;
|
||||||
|
// init and stop
|
||||||
|
string load_name;
|
||||||
|
unsigned int maxGen;
|
||||||
|
unsigned int minGen;
|
||||||
|
unsigned int steadyGen;
|
||||||
|
// rates for crossovers
|
||||||
|
double onePointRate;
|
||||||
|
double twoPointsRate;
|
||||||
|
double URate;
|
||||||
|
// rates and private parameters for mutations;
|
||||||
|
double pMutPerBit;
|
||||||
|
double bitFlipRate;
|
||||||
|
double oneBitRate;
|
||||||
|
|
||||||
|
// Now read the parameters of the program
|
||||||
|
read_param(argc, argv, seed, vecSize, popSize, tSize,
|
||||||
|
pCross, pMut, load_name, maxGen, minGen, steadyGen,
|
||||||
|
onePointRate, twoPointsRate, URate,
|
||||||
|
pMutPerBit, bitFlipRate, oneBitRate );
|
||||||
|
|
||||||
|
// EVAL
|
||||||
|
/////////////////////////////
|
||||||
|
// Fitness function
|
||||||
|
////////////////////////////
|
||||||
|
// Evaluation: from a plain C++ fn to an EvalFunc Object ...
|
||||||
|
eoEvalFuncPtr<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 (load_name != "")
|
||||||
|
{
|
||||||
|
inState.load(load_name); // load the pop and the rng
|
||||||
|
// the fitness is read in the file:
|
||||||
|
// do only evaluate the pop if the fitness has changed
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
rng.reseed(seed);
|
||||||
|
// a Indi random initializer
|
||||||
|
// based on boolean_generator class (see utils/rnd_generator.h)
|
||||||
|
eoInitFixedLength<Indi, boolean_generator>
|
||||||
|
random(vecSize, boolean_generator());
|
||||||
|
|
||||||
|
// Init pop from the randomizer: need to use the append function
|
||||||
|
pop.append(popSize, random);
|
||||||
|
// and evaluate pop (STL syntax)
|
||||||
|
apply<Indi>(eval, pop);
|
||||||
|
} // end of initializatio of the population
|
||||||
|
|
||||||
|
// OUTPUT
|
||||||
|
// sort pop for pretty printout
|
||||||
|
pop.sort();
|
||||||
|
// Print (sorted) intial population (raw printout)
|
||||||
|
cout << "Initial Population" << endl << pop << endl;
|
||||||
|
|
||||||
|
// ENGINE
|
||||||
|
/////////////////////////////////////
|
||||||
|
// selection and replacement
|
||||||
|
////////////////////////////////////
|
||||||
|
// SELECT
|
||||||
|
// The robust tournament selection
|
||||||
|
eoDetTournament<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
|
||||||
|
// no replacement (== generational replacement) at the moment :-)
|
||||||
|
eoNoReplacement<Indi> replace;
|
||||||
|
|
||||||
|
// OPERATORS
|
||||||
|
//////////////////////////////////////
|
||||||
|
// The variation operators
|
||||||
|
//////////////////////////////////////
|
||||||
|
// CROSSOVER
|
||||||
|
// 1-point crossover for bitstring
|
||||||
|
eoBinCrossover<Indi> xover1;
|
||||||
|
// uniform crossover for bitstring
|
||||||
|
eoBinUxOver<Indi> xoverU;
|
||||||
|
// 2-pots xover
|
||||||
|
eoBinNxOver<Indi> xover2(2);
|
||||||
|
// Combine them with relative rates
|
||||||
|
eoPropCombinedQuadOp<Indi> xover(xover1, onePointRate);
|
||||||
|
xover.add(xoverU, URate);
|
||||||
|
xover.add(xover2, twoPointsRate, true);
|
||||||
|
|
||||||
|
// MUTATION
|
||||||
|
// standard bit-flip mutation for bitstring
|
||||||
|
eoBinMutation<Indi> mutationBitFlip(pMutPerBit);
|
||||||
|
// mutate exactly 1 bit per individual
|
||||||
|
eoDetBitFlip<Indi> mutationOneBit;
|
||||||
|
// Combine them with relative rates
|
||||||
|
eoPropCombinedMonOp<Indi> mutation(mutationBitFlip, bitFlipRate);
|
||||||
|
mutation.add(mutationOneBit, oneBitRate, true);
|
||||||
|
|
||||||
|
// The operators are encapsulated into an eoTRansform object
|
||||||
|
eoSGATransform<Indi> transform(xover, pCross, mutation, pMut);
|
||||||
|
|
||||||
|
// 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;
|
||||||
|
eoAverageStat<Indi> averageStat;
|
||||||
|
// 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(averageStat);
|
||||||
|
checkpoint.add(SecondStat);
|
||||||
|
|
||||||
|
// The Stdout monitor will print parameters to the screen ...
|
||||||
|
eoStdoutMonitor monitor(false);
|
||||||
|
|
||||||
|
// when called by the checkpoint (i.e. at every generation)
|
||||||
|
checkpoint.add(monitor);
|
||||||
|
|
||||||
|
// the monitor will output a series of parameters: add them
|
||||||
|
monitor.add(generationCounter);
|
||||||
|
monitor.add(eval); // because now eval is an eoEvalFuncCounter!
|
||||||
|
monitor.add(bestStat);
|
||||||
|
monitor.add(SecondStat);
|
||||||
|
|
||||||
|
// A file monitor: will print parameters to ... a File, yes, you got it!
|
||||||
|
eoFileMonitor fileMonitor("stats.xg", " ");
|
||||||
|
eoGnuplot1DMonitor gnuMonitor("best_average.xg");
|
||||||
|
|
||||||
|
// the checkpoint mechanism can handle multiple monitors
|
||||||
|
checkpoint.add(fileMonitor);
|
||||||
|
checkpoint.add(gnuMonitor);
|
||||||
|
|
||||||
|
// the fileMonitor can monitor parameters, too, but you must tell it!
|
||||||
|
fileMonitor.add(generationCounter);
|
||||||
|
fileMonitor.add(bestStat);
|
||||||
|
fileMonitor.add(SecondStat);
|
||||||
|
// the fileMonitor can monitor parameters, too, but you must tell it!
|
||||||
|
gnuMonitor.add(eval);
|
||||||
|
gnuMonitor.add(bestStat);
|
||||||
|
gnuMonitor.add(averageStat);
|
||||||
|
|
||||||
|
// Last type of item the eoCheckpoint can handle: state savers:
|
||||||
|
eoState outState;
|
||||||
|
// Register the algorithm into the state (so it has something to save!!)
|
||||||
|
outState.registerObject(rng);
|
||||||
|
outState.registerObject(pop);
|
||||||
|
|
||||||
|
// and feed the state to state savers
|
||||||
|
// save state every 100th generation
|
||||||
|
eoCountedStateSaver stateSaver1(100, outState, "generation");
|
||||||
|
// save state every 1 seconds
|
||||||
|
eoTimedStateSaver stateSaver2(1, outState, "time");
|
||||||
|
|
||||||
|
// Don't forget to add the two savers to the checkpoint
|
||||||
|
checkpoint.add(stateSaver1);
|
||||||
|
checkpoint.add(stateSaver2);
|
||||||
|
// and that's it for the (control and) output
|
||||||
|
|
||||||
|
// GENERATION
|
||||||
|
/////////////////////////////////////////
|
||||||
|
// the algorithm
|
||||||
|
////////////////////////////////////////
|
||||||
|
|
||||||
|
// Easy EA requires
|
||||||
|
// selection, transformation, eval, replacement, and stopping criterion
|
||||||
|
eoEasyEA<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)
|
||||||
|
{
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
int flag = _CrtSetDbgFlag(_CRTDBG_LEAK_CHECK_DF);
|
||||||
|
flag |= _CRTDBG_LEAK_CHECK_DF;
|
||||||
|
_CrtSetDbgFlag(flag);
|
||||||
|
// _CrtSetBreakAlloc(100);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
main_function(argc, argv);
|
||||||
|
}
|
||||||
|
catch(exception& e)
|
||||||
|
{
|
||||||
|
cout << "Exception: " << e.what() << '\n';
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
BIN
eo/tutorial/html/EA_tutorial.jpg
Normal file
BIN
eo/tutorial/html/EA_tutorial.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 53 KiB |
368
eo/tutorial/html/FirstBitEA.html
Normal file
368
eo/tutorial/html/FirstBitEA.html
Normal file
|
|
@ -0,0 +1,368 @@
|
||||||
|
<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||||
|
<meta name="GENERATOR" content="cpp2html Marc Schoenauer">
|
||||||
|
<title>FirstBitEA.cpp</title>
|
||||||
|
<!-- Changed by: Marc Schoenauer, 28-Nov-2000 -->
|
||||||
|
</head>
|
||||||
|
<body text="#000000" bgcolor="#C3C2B4" link="#0000EE" vlink="#551A8B" alink="#FF0000">
|
||||||
|
<a href="eoLesson2.html">Back to Lesson 2</a> - <a href="eoTutorial.html">Tutorial
|
||||||
|
main page </a>- <a href="eoTopDown.html">Top-Down page</a> - <a href="eoBottomUp.html">Bottom-up
|
||||||
|
page</a> - <a href="eoProgramming.html">Programming hints</a> - <font face="Arial,Helvetica"><a href="doc/html/index.html">EO
|
||||||
|
documentation</a></font>
|
||||||
|
<br>
|
||||||
|
<hr WIDTH="100%"><!-- -------------- End of header ------------------ --><!-- ----------------------------------------------- -->
|
||||||
|
<center>
|
||||||
|
<h1>
|
||||||
|
<font color="#FF0000">FirstBitEA.cpp</font></h1></center>
|
||||||
|
Click on the figure to see the corresponding code.<br>
|
||||||
|
In the code, the <a href="eoTutorial.html#colors">colors are meaningfull</a><br>
|
||||||
|
The actual code is in boldface and the comment in normal face.
|
||||||
|
<br><img SRC="EA_tutorial.jpg" USEMAP="#Map" >
|
||||||
|
<map NAME="Map">
|
||||||
|
<!-- Init -->
|
||||||
|
<area SHAPE="rect" HREF="#init" COORDS="14,31,135,70">
|
||||||
|
<area SHAPE="rect" HREF="#eval" COORDS="14,110,135,150">
|
||||||
|
<!-- main loop -->
|
||||||
|
<area SHAPE="rect" HREF="#representation" COORDS="170,110,295,150">
|
||||||
|
<area SHAPE="rect" HREF="#output" COORDS="280,45,480,70">
|
||||||
|
<area SHAPE="rect" HREF="#stop" COORDS="348,110,430,150">
|
||||||
|
<area SHAPE="rect" HREF="#select" COORDS="495,110,615,150">
|
||||||
|
<area SHAPE="rect" HREF="#representation" COORDS="495,190,615,230">
|
||||||
|
<area SHAPE="rect" HREF="#crossover" COORDS="495,265,625,287">
|
||||||
|
<area SHAPE="rect" HREF="#mutation" COORDS="495,287,625,305">
|
||||||
|
<area SHAPE="rect" HREF="#representation" COORDS="240,270,465,310">
|
||||||
|
<area SHAPE="rect" HREF="#eval" COORDS="170,270,295,310">
|
||||||
|
<area SHAPE="rect" HREF="#replace" COORDS="170,190,295,230">
|
||||||
|
<!-- Center of loop -->
|
||||||
|
<area SHAPE="rect" HREF="#generation" COORDS="310,160,485,260">
|
||||||
|
<!-- 4 bottom lines -->
|
||||||
|
<area SHAPE="rect" HREF="#operators" COORDS="15,350,260,370">
|
||||||
|
<area SHAPE="rect" HREF="#representation" COORDS="270,350,460,370">
|
||||||
|
<area SHAPE="rect" HREF="#engine" COORDS="15,377,400,397">
|
||||||
|
<area SHAPE="rect" HREF="#eval" COORDS="15,403,230,423">
|
||||||
|
<area SHAPE="rect" HREF="#checkpoint" COORDS="15,430,221,450">
|
||||||
|
<area SHAPE="rect" HREF="#stop" COORDS="221,430,345,450">
|
||||||
|
<area SHAPE="rect" HREF="#stat" COORDS="375,430,445,450">
|
||||||
|
<area SHAPE="rect" HREF="#parametres" COORDS="0,358,278,378">
|
||||||
|
</map>
|
||||||
|
<br>
|
||||||
|
<A NAME="start"></a>
|
||||||
|
<table BORDER=0 CELLSPACING=0 COLS=1 WIDTH="100%" BGCOLOR="#FFCC99" NOSAVE >
|
||||||
|
<tr NOSAVE>
|
||||||
|
<td NOSAVE><tt><font color="#993300">
|
||||||
|
//-----------------------------------------------------------------------------<br>
|
||||||
|
// FirstBitEA.cpp<br>
|
||||||
|
//-----------------------------------------------------------------------------<br>
|
||||||
|
//*<br>
|
||||||
|
// Still an instance of a VERY simple Bitstring Genetic Algorithm <br>
|
||||||
|
// (see FirstBitGA.cpp) but now with Breeder - and Combined Ops<br>
|
||||||
|
//<br>
|
||||||
|
//-----------------------------------------------------------------------------<br>
|
||||||
|
// standard includes<br>
|
||||||
|
<b>#include <stdexcept> </b>// runtime_error <br>
|
||||||
|
<b>#include <iostream> </b>// cout<br>
|
||||||
|
<b>#include <strstream> </b>// ostrstream, istrstream<br>
|
||||||
|
// the general include for eo<br>
|
||||||
|
<b>#include <eo></b><br>
|
||||||
|
</font></tt>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<a NAME="representation"></a><table BORDER=0 CELLSPACING=0 COLS=1 WIDTH="100%" BGCOLOR="#FFFFCC" NOSAVE >
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<tt><font color="#999900">
|
||||||
|
//-----------------------------------------------------------------------------<br>
|
||||||
|
// define your individuals<br>
|
||||||
|
<b>typedef eoBin<double> Indi; </b>// A bitstring with fitness double<br>
|
||||||
|
</font></tt>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<a NAME="evalfunc"></a><table BORDER=0 CELLSPACING=0 COLS=1 WIDTH="100%" BGCOLOR="#FFCCCC" NOSAVE >
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<tt><font color="#CC0000">
|
||||||
|
//-----------------------------------------------------------------------------<br>
|
||||||
|
// a simple fitness function that computes the number of ones of a bitstring<br>
|
||||||
|
// Now in a separate file, and declared as binary_value(const vector<bool> &)<br>
|
||||||
|
<b>#include "binary_value.h"</b><br>
|
||||||
|
</font></tt>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<a NAME="general"></a><table BORDER=0 CELLSPACING=0 COLS=1 WIDTH="100%" BGCOLOR="#FFCC99" NOSAVE >
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<tt><font color="#993300">
|
||||||
|
//-----------------------------------------------------------------------------<br>
|
||||||
|
<b>void main_function(int argc, char **argv)</b><br>
|
||||||
|
<b>{</b><br>
|
||||||
|
</font></tt>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<a NAME="parametres"></a><table BORDER=0 CELLSPACING=0 COLS=1 WIDTH="100%" BGCOLOR="#CCFFFF" NOSAVE >
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<tt><font color="#3366FF">
|
||||||
|
<b> const unsigned int SEED = 42; </b>// seed for random number generator<br>
|
||||||
|
<b> const unsigned int T_SIZE = 3; </b>// size for tournament selection<br>
|
||||||
|
<b> const unsigned int VEC_SIZE = 8; </b>// Number of bits in genotypes<br>
|
||||||
|
<b> const unsigned int POP_SIZE = 20; </b>// Size of population<br>
|
||||||
|
<b> const unsigned int MAX_GEN = 500; </b>// Maximum number of generation before STOP<br>
|
||||||
|
<b> const float CROSS_RATE = 0.8; </b>// Crossover rate<br>
|
||||||
|
<b> const double P_MUT_PER_BIT = 0.01; </b>// probability of bit-flip mutation<br>
|
||||||
|
<b> const float MUT_RATE = 1.0; </b>// mutation rate<br>
|
||||||
|
<b> </b>// some parameters for chosing among different operators<br>
|
||||||
|
<b> const double onePointRate = 0.5; </b>// rate for 1-pt Xover<br>
|
||||||
|
<b> const double twoPointsRate = 0.5; </b>// rate for 2-pt Xover<br>
|
||||||
|
<b> const double URate = 0.5; </b>// rate for Uniform Xover<br>
|
||||||
|
<b> const double bitFlipRate = 0.5; </b>// rate for bit-flip mutation<br>
|
||||||
|
<b> const double oneBitRate = 0.5; </b>// rate for one-bit mutation<br>
|
||||||
|
</font></tt>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<a NAME="general"></a><table BORDER=0 CELLSPACING=0 COLS=1 WIDTH="100%" BGCOLOR="#FFCC99" NOSAVE >
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<tt><font color="#993300">
|
||||||
|
<b> </b>//////////////////////////<br>
|
||||||
|
<b> </b>// Random seed<br>
|
||||||
|
<b> </b>//////////////////////////<br>
|
||||||
|
<b> </b>//reproducible random seed: if you don't change SEED above, <br>
|
||||||
|
<b> </b>// you'll aways get the same result, NOT a random run<br>
|
||||||
|
<b> rng.reseed(SEED);</b><br>
|
||||||
|
</font></tt>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<a NAME="eval"></a><table BORDER=0 CELLSPACING=0 COLS=1 WIDTH="100%" BGCOLOR="#FFCCCC" NOSAVE >
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<tt><font color="#CC0000">
|
||||||
|
<b> </b>/////////////////////////////<br>
|
||||||
|
<b> </b>// Fitness function<br>
|
||||||
|
<b> </b>////////////////////////////<br>
|
||||||
|
<b> </b>// Evaluation: from a plain C++ fn to an EvalFunc Object<br>
|
||||||
|
<b> </b>// you need to give the full description of the function<br>
|
||||||
|
<b> eoEvalFuncPtr<Indi, double, const vector<bool>& > eval( binary_value );</b><br>
|
||||||
|
</font></tt>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<a NAME="init"></a><table BORDER=0 CELLSPACING=0 COLS=1 WIDTH="100%" BGCOLOR="#FFCCFF" NOSAVE >
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<tt><font color="#993399">
|
||||||
|
<b> </b>////////////////////////////////<br>
|
||||||
|
<b> </b>// Initilisation of population<br>
|
||||||
|
<b> </b>////////////////////////////////<br>
|
||||||
|
<b> </b>// based on boolean_generator class (see utils/rnd_generator.h)<br>
|
||||||
|
<b> eoInitFixedLength<Indi, boolean_generator> </b><br>
|
||||||
|
<b> random(VEC_SIZE, boolean_generator());</b><br>
|
||||||
|
<b> </b>// Initialization of the population<br>
|
||||||
|
<b> eoPop<Indi> pop(POP_SIZE, random);</b><br>
|
||||||
|
<b> </b>// and evaluate it in one loop<br>
|
||||||
|
<b> apply<Indi>(eval, pop); </b>// STL syntax<br>
|
||||||
|
</font></tt>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<a NAME="output"></a><table BORDER=0 CELLSPACING=0 COLS=1 WIDTH="100%" BGCOLOR="#CCFFFF" NOSAVE >
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<tt><font color="#3366FF">
|
||||||
|
<b> </b>// sort pop before printing it!<br>
|
||||||
|
<b> pop.sort();</b><br>
|
||||||
|
<b> </b>// Print (sorted) intial population (raw printout)<br>
|
||||||
|
<b> cout << "Initial Population" << endl;</b><br>
|
||||||
|
<b> cout << pop;</b><br>
|
||||||
|
</font></tt>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<a NAME="engine"></a><table BORDER=0 CELLSPACING=0 COLS=1 WIDTH="100%" BGCOLOR="#99FFCC" NOSAVE >
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<tt><font color="#009900">
|
||||||
|
<b> </b>/////////////////////////////////////<br>
|
||||||
|
<b> </b>// selection and replacement<br>
|
||||||
|
<b> </b>////////////////////////////////////<br>
|
||||||
|
</font></tt>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<a NAME="select"></a><table BORDER=0 CELLSPACING=0 COLS=1 WIDTH="100%" BGCOLOR="#99FFCC" NOSAVE >
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<tt><font color="#009900">
|
||||||
|
<b> </b>// The robust tournament selection<br>
|
||||||
|
<b> eoDetTournament<Indi> selectOne(T_SIZE); </b>// T_SIZE in [2,POP_SIZE]<br>
|
||||||
|
<a NAME="select_encapsulate"></a>
|
||||||
|
<b> </b>// is now encapsulated in a eoSelectPerc (entage)<br>
|
||||||
|
<b> eoSelectPerc<Indi> select(selectOne);</b>// by default rate==1<br>
|
||||||
|
</font></tt>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<a NAME="replace"></a><table BORDER=0 CELLSPACING=0 COLS=1 WIDTH="100%" BGCOLOR="#99FFCC" NOSAVE >
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<tt><font color="#009900">
|
||||||
|
<b> </b>// And we now have the full slection/replacement - though with <br>
|
||||||
|
<b> </b>// no replacement (== generational replacement) at the moment :-)<br>
|
||||||
|
<b> eoNoReplacement<Indi> replace; </b><br>
|
||||||
|
</font></tt>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<a NAME="operators"></a><table BORDER=0 CELLSPACING=0 COLS=1 WIDTH="100%" BGCOLOR="#FFCCFF" NOSAVE >
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<tt><font color="#993399">
|
||||||
|
<b> </b>//////////////////////////////////////<br>
|
||||||
|
<b> </b>// The variation operators<br>
|
||||||
|
<b> </b>//////////////////////////////////////<br>
|
||||||
|
</font></tt>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<a NAME="crossover"></a><table BORDER=0 CELLSPACING=0 COLS=1 WIDTH="100%" BGCOLOR="#FFCCFF" NOSAVE >
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<tt><font color="#993399">
|
||||||
|
<b> </b>// 1-point crossover for bitstring<br>
|
||||||
|
<b> eoBinCrossover<Indi> xover1;</b><br>
|
||||||
|
<b> </b>// uniform crossover for bitstring<br>
|
||||||
|
<b> eoBinUxOver<Indi> xoverU;</b><br>
|
||||||
|
<b> </b>// 2-pots xover<br>
|
||||||
|
<b> eoBinNxOver<Indi> xover2(2);</b><br>
|
||||||
|
<b> </b>// Combine them with relative rates<br>
|
||||||
|
<b> eoPropCombinedQuadOp<Indi> xover(xover1, onePointRate);</b><br>
|
||||||
|
<b> xover.add(xoverU, URate);</b><br>
|
||||||
|
<b> xover.add(xover2, twoPointsRate, true);</b><br>
|
||||||
|
</font></tt>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<a NAME="mutation"></a><table BORDER=0 CELLSPACING=0 COLS=1 WIDTH="100%" BGCOLOR="#FFCCFF" NOSAVE >
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<tt><font color="#993399">
|
||||||
|
<b> </b><br>
|
||||||
|
<b> </b>// standard bit-flip mutation for bitstring<br>
|
||||||
|
<b> eoBinMutation<Indi> mutationBitFlip(P_MUT_PER_BIT);</b><br>
|
||||||
|
<b> </b>// mutate exactly 1 bit per individual<br>
|
||||||
|
<b> eoDetBitFlip<Indi> mutationOneBit; </b><br>
|
||||||
|
<b> </b>// Combine them with relative rates<br>
|
||||||
|
<b> eoPropCombinedMonOp<Indi> mutation(mutationBitFlip, bitFlipRate);</b><br>
|
||||||
|
<b> mutation.add(mutationOneBit, oneBitRate, true);</b><br>
|
||||||
|
<b> </b><br>
|
||||||
|
<a NAME="transform"></a>
|
||||||
|
<b> </b>// The operators are encapsulated into an eoTRansform object<br>
|
||||||
|
<b> eoSGATransform<Indi> transform(xover, CROSS_RATE, mutation, MUT_RATE);</b><br>
|
||||||
|
</font></tt>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<a NAME="stop"></a><table BORDER=0 CELLSPACING=0 COLS=1 WIDTH="100%" BGCOLOR="#CCFFFF" NOSAVE >
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<tt><font color="#3366FF">
|
||||||
|
</font></tt>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<a NAME="checkpoint"></a><table BORDER=0 CELLSPACING=0 COLS=1 WIDTH="100%" BGCOLOR="#CCFFFF" NOSAVE >
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<tt><font color="#3366FF">
|
||||||
|
<b> </b>//////////////////////////////////////<br>
|
||||||
|
<b> </b>// termination conditions: use more than one<br>
|
||||||
|
<b> </b>/////////////////////////////////////<br>
|
||||||
|
<b> </b>// stop after MAX_GEN generations<br>
|
||||||
|
<b> eoGenContinue<Indi> genCont(MAX_GEN);</b><br>
|
||||||
|
<b> </b>// do MIN_GEN gen., then stop after STEADY_GEN gen. without improvement<br>
|
||||||
|
<b> eoSteadyFitContinue<Indi> steadyCont(MIN_GEN, STEADY_GEN);</b><br>
|
||||||
|
<b> </b>// stop when fitness reaches a target (here VEC_SIZE)<br>
|
||||||
|
<b> eoFitContinue<Indi> fitCont(0);</b><br>
|
||||||
|
<b> </b>// do stop when one of the above says so<br>
|
||||||
|
<b> eoCombinedContinue<Indi> continuator(genCont);</b><br>
|
||||||
|
<b> continuator.add(steadyCont);</b><br>
|
||||||
|
<b> continuator.add(fitCont);</b><br>
|
||||||
|
</font></tt>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<a NAME="generation"></a><table BORDER=0 CELLSPACING=0 COLS=1 WIDTH="100%" BGCOLOR="#FFCC99" NOSAVE >
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<tt><font color="#FF6666">
|
||||||
|
<b> </b>/////////////////////////////////////////<br>
|
||||||
|
<b> </b>// the algorithm<br>
|
||||||
|
<b> </b>////////////////////////////////////////<br>
|
||||||
|
<b> </b>// Easy EA requires <br>
|
||||||
|
<b> </b>// selection, transformation, eval, replacement, and stopping criterion<br>
|
||||||
|
<b> eoEasyEA<Indi> gga(continuator, eval, select, transform, replace);</b><br>
|
||||||
|
<b> </b>// Apply algo to pop - that's it!<br>
|
||||||
|
<b> gga(pop);</b><br>
|
||||||
|
<b> </b><br>
|
||||||
|
</font></tt>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<a NAME="output"></a><table BORDER=0 CELLSPACING=0 COLS=1 WIDTH="100%" BGCOLOR="#CCFFFF" NOSAVE >
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<tt><font color="#3366FF">
|
||||||
|
<b> </b>// Print (sorted) intial population<br>
|
||||||
|
<b> pop.sort();</b><br>
|
||||||
|
<b> cout << "FINAL Population\n" << pop << endl;</b><br>
|
||||||
|
</font></tt>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<a NAME="general"></a><table BORDER=0 CELLSPACING=0 COLS=1 WIDTH="100%" BGCOLOR="#FFCC99" NOSAVE >
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<tt><font color="#993300">
|
||||||
|
<b>}</b><br>
|
||||||
|
// A main that catches the exceptions<br>
|
||||||
|
<b>int main(int argc, char **argv)</b><br>
|
||||||
|
<b>{</b><br>
|
||||||
|
<b>#ifdef _MSC_VER</b><br>
|
||||||
|
<b> </b>// rng.reseed(42);<br>
|
||||||
|
<b> int flag = _CrtSetDbgFlag(_CRTDBG_LEAK_CHECK_DF);</b><br>
|
||||||
|
<b> flag |= _CRTDBG_LEAK_CHECK_DF;</b><br>
|
||||||
|
<b> _CrtSetDbgFlag(flag);</b><br>
|
||||||
|
// _CrtSetBreakAlloc(100);<br>
|
||||||
|
<b>#endif</b><br>
|
||||||
|
<b> try</b><br>
|
||||||
|
<b> {</b><br>
|
||||||
|
<b> main_function(argc, argv);</b><br>
|
||||||
|
<b> }</b><br>
|
||||||
|
<b> catch(exception& e)</b><br>
|
||||||
|
<b> {</b><br>
|
||||||
|
<b> cout << "Exception: " << e.what() << '\n';</b><br>
|
||||||
|
<b> }</b><br>
|
||||||
|
<b> return 1;</b><br>
|
||||||
|
<b>}</b><br>
|
||||||
|
</font></font></font></td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<hr WIDTH="100%"><a href="eoLesson2.html">Back to Lesson 2</a> - <a href="eoTutorial.html">Tutorial
|
||||||
|
main page </a>- <a href="eoTopDown.html">Top-Down page</a> - <a href="eoBottomUp.html">Bottom-up
|
||||||
|
page</a> - <a href="eoProgramming.html">Programming hints</a> - <font face="Arial,Helvetica"><a href="doc/html/index.html">EO
|
||||||
|
documentation</a></font>
|
||||||
|
<hr>
|
||||||
|
<address>
|
||||||
|
<a href="mailto:marc.schoenauer@polytechnique.fr">Marc Schoenauer</a></address>
|
||||||
|
<br><!-- Created: Nov 2000 --><!-- hhmts start -->Last
|
||||||
|
modified: Sun Nov 19 22:26:27 2000
|
||||||
|
<!-- hhmts end -->
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
350
eo/tutorial/html/FirstBitGA.html
Normal file
350
eo/tutorial/html/FirstBitGA.html
Normal file
|
|
@ -0,0 +1,350 @@
|
||||||
|
<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||||
|
<meta name="GENERATOR" content="cpp2html Marc Schoenauer">
|
||||||
|
<title>FirstBitGA.html</title>
|
||||||
|
<!-- Changed by: Marc Schoenauer, 29-Nov-2000 -->
|
||||||
|
</head>
|
||||||
|
<body text="#000000" bgcolor="#C3C2B4" link="#0000EE" vlink="#551A8B" alink="#FF0000">
|
||||||
|
<a href="eoLesson1.html">Back to Lesson 1</a> - <a href="eoTutorial.html">Tutorial
|
||||||
|
main page </a>- <a href="eoTopDown.html">Top-Down page</a> - <a href="eoBottomUp.html">Bottom-up
|
||||||
|
page</a> - <a href="eoProgramming.html">Programming hints</a> - <font face="Arial,Helvetica"><a href="doc/html/index.html">EO
|
||||||
|
documentation</a></font>
|
||||||
|
<br>
|
||||||
|
<hr WIDTH="100%"><!-- -------------- End of header ------------------ --><!-- ----------------------------------------------- -->
|
||||||
|
<center>
|
||||||
|
<h1>
|
||||||
|
<font color="#FF0000">FirstBitGA.html</font></h1></center>
|
||||||
|
Click on the figure to see the corresponding code.<br>
|
||||||
|
In the code, the <a href="eoTutorial.html#colors">colors are meaningfull</a><br>
|
||||||
|
The actual code is in boldface and the comment in normal face.
|
||||||
|
<br><img SRC="EA_tutorial.jpg" USEMAP="#Map" >
|
||||||
|
<map NAME="Map">
|
||||||
|
<!-- Init -->
|
||||||
|
<area SHAPE="rect" HREF="#init" COORDS="14,31,135,70">
|
||||||
|
<area SHAPE="rect" HREF="#eval" COORDS="14,110,135,150">
|
||||||
|
<!-- main loop -->
|
||||||
|
<area SHAPE="rect" HREF="#representation" COORDS="170,110,295,150">
|
||||||
|
<area SHAPE="rect" HREF="#output" COORDS="280,45,480,70">
|
||||||
|
<area SHAPE="rect" HREF="#stop" COORDS="348,110,430,150">
|
||||||
|
<area SHAPE="rect" HREF="#select" COORDS="495,110,615,150">
|
||||||
|
<area SHAPE="rect" HREF="#representation" COORDS="495,190,615,230">
|
||||||
|
<area SHAPE="rect" HREF="#crossover" COORDS="495,265,625,287">
|
||||||
|
<area SHAPE="rect" HREF="#mutation" COORDS="495,287,625,305">
|
||||||
|
<area SHAPE="rect" HREF="#representation" COORDS="240,270,465,310">
|
||||||
|
<area SHAPE="rect" HREF="#eval" COORDS="170,270,295,310">
|
||||||
|
<area SHAPE="rect" HREF="#replace" COORDS="170,190,295,230">
|
||||||
|
<!-- Center of loop -->
|
||||||
|
<area SHAPE="rect" HREF="#generation" COORDS="310,160,485,260">
|
||||||
|
<!-- 4 bottom lines -->
|
||||||
|
<area SHAPE="rect" HREF="#operators" COORDS="15,350,260,370">
|
||||||
|
<area SHAPE="rect" HREF="#representation" COORDS="270,350,460,370">
|
||||||
|
<area SHAPE="rect" HREF="#engine" COORDS="15,377,400,397">
|
||||||
|
<area SHAPE="rect" HREF="#eval" COORDS="15,403,230,423">
|
||||||
|
<area SHAPE="rect" HREF="#checkpoint" COORDS="15,430,221,450">
|
||||||
|
<area SHAPE="rect" HREF="#stop" COORDS="221,430,345,450">
|
||||||
|
<area SHAPE="rect" HREF="#stat" COORDS="375,430,445,450">
|
||||||
|
<area SHAPE="rect" HREF="#parametres" COORDS="0,358,278,378">
|
||||||
|
</map>
|
||||||
|
<br>
|
||||||
|
<A NAME="start"></a>
|
||||||
|
<table BORDER=0 CELLSPACING=0 COLS=1 WIDTH="100%" BGCOLOR="#FFCC99" NOSAVE >
|
||||||
|
<tr NOSAVE>
|
||||||
|
<td NOSAVE><tt><font color="#993300">
|
||||||
|
//-----------------------------------------------------------------------------<br>
|
||||||
|
// FirstBitGA.cpp<br>
|
||||||
|
//-----------------------------------------------------------------------------<br>
|
||||||
|
//*<br>
|
||||||
|
// An instance of a VERY simple Bitstring Genetic Algorithm<br>
|
||||||
|
//<br>
|
||||||
|
//-----------------------------------------------------------------------------<br>
|
||||||
|
// standard includes<br>
|
||||||
|
<b>#include <stdexcept> </b>// runtime_error <br>
|
||||||
|
<b>#include <iostream> </b>// cout<br>
|
||||||
|
<b>#include <strstream> </b>// ostrstream, istrstream<br>
|
||||||
|
// the general include for eo<br>
|
||||||
|
<b>#include <eo></b><br>
|
||||||
|
</font></tt>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<a NAME="representation"></a><table BORDER=0 CELLSPACING=0 COLS=1 WIDTH="100%" BGCOLOR="#FFFFCC" NOSAVE >
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<tt><font color="#999900">
|
||||||
|
//-----------------------------------------------------------------------------<br>
|
||||||
|
// define your individuals<br>
|
||||||
|
<b>typedef eoBin<double> Indi; </b>// A bitstring with fitness double<br>
|
||||||
|
</font></tt>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<table BORDER=0 CELLSPACING=0 COLS=1 WIDTH="100%" BGCOLOR="#FFCCCC" NOSAVE >
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<tt><font color="#CC0000">
|
||||||
|
//-----------------------------------------------------------------------------<br>
|
||||||
|
// a simple fitness function that computes the number of ones of a bitstring<br>
|
||||||
|
// @param _indi A biststring individual<br>
|
||||||
|
<a name="evalfunc"></a>
|
||||||
|
<b>double binary_value(const Indi & _indi)</b><br>
|
||||||
|
<b>{</b><br>
|
||||||
|
<b> double sum = 0;</b><br>
|
||||||
|
<b> for (unsigned i = 0; i < _indi.size(); i++)</b><br>
|
||||||
|
<b> sum += _indi[i];</b><br>
|
||||||
|
<b> return sum;</b><br>
|
||||||
|
<b>}</b><br>
|
||||||
|
</font></tt>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<a NAME="general"></a><table BORDER=0 CELLSPACING=0 COLS=1 WIDTH="100%" BGCOLOR="#FFCC99" NOSAVE >
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<tt><font color="#993300">
|
||||||
|
//-----------------------------------------------------------------------------<br>
|
||||||
|
<b>void main_function(int argc, char **argv)</b><br>
|
||||||
|
<b>{</b><br>
|
||||||
|
</font></tt>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<a NAME="parametres"></a><table BORDER=0 CELLSPACING=0 COLS=1 WIDTH="100%" BGCOLOR="#CCFFFF" NOSAVE >
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<tt><font color="#3366FF">
|
||||||
|
<b> </b>// all parameters are hard-coded!<br>
|
||||||
|
<b> const unsigned int SEED = 42; </b>// seed for random number generator<br>
|
||||||
|
<b> const unsigned int T_SIZE = 3; </b>// size for tournament selection<br>
|
||||||
|
<b> const unsigned int VEC_SIZE = 8; </b>// Number of bits in genotypes<br>
|
||||||
|
<b> const unsigned int POP_SIZE = 20; </b>// Size of population<br>
|
||||||
|
<b> const unsigned int MAX_GEN = 100; </b>// Maximum number of generation before STOP<br>
|
||||||
|
<b> const float CROSS_RATE = 0.8; </b>// Crossover rate<br>
|
||||||
|
<b> const double P_MUT_PER_BIT = 0.01; </b>// probability of bit-flip mutation<br>
|
||||||
|
<b> const float MUT_RATE = 1.0; </b>// mutation rate<br>
|
||||||
|
</font></tt>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<a NAME="general"></a><table BORDER=0 CELLSPACING=0 COLS=1 WIDTH="100%" BGCOLOR="#FFCC99" NOSAVE >
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<tt><font color="#993300">
|
||||||
|
<a NAME="random"></a>
|
||||||
|
<b> </b>//////////////////////////<br>
|
||||||
|
<b> </b>// Random seed<br>
|
||||||
|
<b> </b>//////////////////////////<br>
|
||||||
|
<b> </b>//reproducible random seed: if you don't change SEED above, <br>
|
||||||
|
<b> </b>// you'll aways get the same result, NOT a random run<br>
|
||||||
|
<b> rng.reseed(SEED);</b><br>
|
||||||
|
</font></tt>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<a NAME="eval"></a><table BORDER=0 CELLSPACING=0 COLS=1 WIDTH="100%" BGCOLOR="#FFCCCC" NOSAVE >
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<tt><font color="#CC0000">
|
||||||
|
<b> </b>/////////////////////////////<br>
|
||||||
|
<b> </b>// Fitness function<br>
|
||||||
|
<b> </b>////////////////////////////<br>
|
||||||
|
<b> </b>// Evaluation: from a plain C++ fn to an EvalFunc Object<br>
|
||||||
|
<b> eoEvalFuncPtr<Indi> eval( binary_value );</b><br>
|
||||||
|
</font></tt>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<a NAME="init"></a><table BORDER=0 CELLSPACING=0 COLS=1 WIDTH="100%" BGCOLOR="#FFCCFF" NOSAVE >
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<tt><font color="#993399">
|
||||||
|
<b> </b>////////////////////////////////<br>
|
||||||
|
<b> </b>// Initilisation of population<br>
|
||||||
|
<b> </b>////////////////////////////////<br>
|
||||||
|
<b> </b>// declare the population<br>
|
||||||
|
<b> eoPop<Indi> pop;</b><br>
|
||||||
|
<b> </b>// fill it!<br>
|
||||||
|
<b> for (unsigned int igeno=0; igeno<POP_SIZE; igeno++)</b><br>
|
||||||
|
<b> {</b><br>
|
||||||
|
<b> Indi v; </b>// void individual, to be filled<br>
|
||||||
|
<b> for (unsigned ivar=0; ivar<VEC_SIZE; ivar++)</b><br>
|
||||||
|
<b> {</b><br>
|
||||||
|
<b> bool r = rng.flip(); </b>// new value, random in {0,1}<br>
|
||||||
|
<b> v.push_back(r); </b>// append that random value to v<br>
|
||||||
|
<b> }</b><br>
|
||||||
|
<b> eval(v); </b>// evaluate it<br>
|
||||||
|
<b> pop.push_back(v); </b>// and put it in the population<br>
|
||||||
|
<b> }</b><br>
|
||||||
|
</font></tt>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<a NAME="output"></a><table BORDER=0 CELLSPACING=0 COLS=1 WIDTH="100%" BGCOLOR="#CCFFFF" NOSAVE >
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<tt><font color="#3366FF">
|
||||||
|
<b> </b>// sort pop before printing it!<br>
|
||||||
|
<b> pop.sort();</b><br>
|
||||||
|
<b> </b>// Print (sorted) intial population (raw printout)<br>
|
||||||
|
<b> cout << "Initial Population" << endl;</b><br>
|
||||||
|
<b> cout << pop;</b><br>
|
||||||
|
</font></tt>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<a NAME="engine"></a><table BORDER=0 CELLSPACING=0 COLS=1 WIDTH="100%" BGCOLOR="#99FFCC" NOSAVE >
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<tt><font color="#009900">
|
||||||
|
<b> </b>/////////////////////////////////////<br>
|
||||||
|
<b> </b>// selection and replacement<br>
|
||||||
|
<b> </b>////////////////////////////////////<br>
|
||||||
|
</font></tt>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<a NAME="select"></a><table BORDER=0 CELLSPACING=0 COLS=1 WIDTH="100%" BGCOLOR="#99FFCC" NOSAVE >
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<tt><font color="#009900">
|
||||||
|
<b> </b>// The robust tournament selection<br>
|
||||||
|
<b> eoDetTournament<Indi> select(T_SIZE); </b>// T_SIZE in [2,POP_SIZE]<br>
|
||||||
|
</font></tt>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<a NAME="replace"></a><table BORDER=0 CELLSPACING=0 COLS=1 WIDTH="100%" BGCOLOR="#99FFCC" NOSAVE >
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<tt><font color="#009900">
|
||||||
|
<b> </b>// The simple GA evolution engine uses generational replacement<br>
|
||||||
|
<b> </b>// so no replacement procedure is needed<br>
|
||||||
|
</font></tt>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<a NAME="stop"></a><table BORDER=0 CELLSPACING=0 COLS=1 WIDTH="100%" BGCOLOR="#CCFFFF" NOSAVE >
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<tt><font color="#3366FF">
|
||||||
|
</font></tt>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<a NAME="operators"></a><table BORDER=0 CELLSPACING=0 COLS=1 WIDTH="100%" BGCOLOR="#FFCCFF" NOSAVE >
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<tt><font color="#993399">
|
||||||
|
<b> </b>//////////////////////////////////////<br>
|
||||||
|
<b> </b>// The variation operators<br>
|
||||||
|
<b> </b>//////////////////////////////////////<br>
|
||||||
|
</font></tt>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<a NAME="crossover"></a><table BORDER=0 CELLSPACING=0 COLS=1 WIDTH="100%" BGCOLOR="#FFCCFF" NOSAVE >
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<tt><font color="#993399">
|
||||||
|
<b> </b>// 1-point mutation for bitstring<br>
|
||||||
|
<b> eoBinCrossover<Indi> xover;</b><br>
|
||||||
|
</font></tt>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<a NAME="mutation"></a><table BORDER=0 CELLSPACING=0 COLS=1 WIDTH="100%" BGCOLOR="#FFCCFF" NOSAVE >
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<tt><font color="#993399">
|
||||||
|
<b> </b><br>
|
||||||
|
<b> </b>// standard bit-flip mutation for bitstring<br>
|
||||||
|
<b> eoBinMutation<Indi> mutation(P_MUT_PER_BIT);</b><br>
|
||||||
|
</font></tt>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<a NAME="checkpoint"></a><table BORDER=0 CELLSPACING=0 COLS=1 WIDTH="100%" BGCOLOR="#CCFFFF" NOSAVE >
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<tt><font color="#3366FF">
|
||||||
|
<b> </b>//////////////////////////////////////<br>
|
||||||
|
<b> </b>// termination condition<br>
|
||||||
|
<b> </b>/////////////////////////////////////<br>
|
||||||
|
<b> </b>// stop after MAX_GEN generations<br>
|
||||||
|
<b> eoGenContinue<Indi> continuator(MAX_GEN);</b><br>
|
||||||
|
<b> </b><br>
|
||||||
|
</font></tt>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<a NAME="generation"></a><table BORDER=0 CELLSPACING=0 COLS=1 WIDTH="100%" BGCOLOR="#FFCC99" NOSAVE >
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<tt><font color="#FF6666">
|
||||||
|
<b> </b>/////////////////////////////////////////<br>
|
||||||
|
<b> </b>// the algorithm<br>
|
||||||
|
<b> </b>////////////////////////////////////////<br>
|
||||||
|
<b> </b>// standard Generational GA requires as parameters<br>
|
||||||
|
<b> </b>// selection, evaluation, crossover and mutation, stopping criterion<br>
|
||||||
|
<b> </b><br>
|
||||||
|
<b> eoSGA<Indi> gga(select, xover, CROSS_RATE, mutation, MUT_RATE, </b><br>
|
||||||
|
<b> eval, continuator);</b><br>
|
||||||
|
<b> </b>// Apply algo to pop - that's it!<br>
|
||||||
|
<b> gga(pop);</b><br>
|
||||||
|
<b> </b><br>
|
||||||
|
</font></tt>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<a NAME="final_output"></a><table BORDER=0 CELLSPACING=0 COLS=1 WIDTH="100%" BGCOLOR="#CCFFFF" NOSAVE >
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<tt><font color="#3366FF">
|
||||||
|
<b> </b>// Print (sorted) intial population<br>
|
||||||
|
<b> pop.sort();</b><br>
|
||||||
|
<b> cout << "FINAL Population\n" << pop << endl;</b><br>
|
||||||
|
</font></tt>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<a NAME="main"></a><table BORDER=0 CELLSPACING=0 COLS=1 WIDTH="100%" BGCOLOR="#FFCC99" NOSAVE >
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<tt><font color="#993300">
|
||||||
|
<b>}</b><br>
|
||||||
|
<b> </b>// A main that catches the exceptions<br>
|
||||||
|
<b>int main(int argc, char **argv)</b><br>
|
||||||
|
<b>{</b><br>
|
||||||
|
<b>#ifdef _MSC_VER</b><br>
|
||||||
|
<b> </b>// rng.reseed(42);<br>
|
||||||
|
<b> int flag = _CrtSetDbgFlag(_CRTDBG_LEAK_CHECK_DF);</b><br>
|
||||||
|
<b> flag |= _CRTDBG_LEAK_CHECK_DF;</b><br>
|
||||||
|
<b> _CrtSetDbgFlag(flag);</b><br>
|
||||||
|
// _CrtSetBreakAlloc(100);<br>
|
||||||
|
<b>#endif</b><br>
|
||||||
|
<b> try</b><br>
|
||||||
|
<b> {</b><br>
|
||||||
|
<b> main_function(argc, argv);</b><br>
|
||||||
|
<b> }</b><br>
|
||||||
|
<b> catch(exception& e)</b><br>
|
||||||
|
<b> {</b><br>
|
||||||
|
<b> cout << "Exception: " << e.what() << '\n';</b><br>
|
||||||
|
<b> }</b><br>
|
||||||
|
<b> return 1;</b><br>
|
||||||
|
<b>}</b><br>
|
||||||
|
</font></font></font></td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<hr WIDTH="100%"><a href="eoLesson1.html">Back to Lesson 1</a> - <a href="eoTutorial.html">Tutorial
|
||||||
|
main page </a>- <a href="eoTopDown.html">Top-Down page</a> - <a href="eoBottomUp.html">Bottom-up
|
||||||
|
page</a> - <a href="eoProgramming.html">Programming hints</a> - <font face="Arial,Helvetica"><a href="doc/html/index.html">EO
|
||||||
|
documentation</a></font>
|
||||||
|
<hr>
|
||||||
|
<address>
|
||||||
|
<a href="mailto:marc.schoenauer@polytechnique.fr">Marc Schoenauer</a></address>
|
||||||
|
<br><!-- Created: Nov 2000 --><!-- hhmts start -->Last
|
||||||
|
modified: Sun Nov 19 08:31:26 2000
|
||||||
|
<!-- hhmts end -->
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
366
eo/tutorial/html/FirstRealEA.html
Normal file
366
eo/tutorial/html/FirstRealEA.html
Normal file
|
|
@ -0,0 +1,366 @@
|
||||||
|
<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||||
|
<meta name="GENERATOR" content="cpp2html Marc Schoenauer">
|
||||||
|
<title>FirstRealEA.cpp</title>
|
||||||
|
</head>
|
||||||
|
<body text="#000000" bgcolor="#C3C2B4" link="#0000EE" vlink="#551A8B" alink="#FF0000">
|
||||||
|
<a href="eoLesson2.html">Back to Lesson 2</a> - <a href="eoTutorial.html">Tutorial
|
||||||
|
main page </a>- <a href="eoTopDown.html">Top-Down page</a> - <a href="eoBottomUp.html">Bottom-up
|
||||||
|
page</a> - <a href="eoProgramming.html">Programming hints</a> - <font face="Arial,Helvetica"><a href="doc/html/index.html">EO
|
||||||
|
documentation</a></font>
|
||||||
|
<br>
|
||||||
|
<hr WIDTH="100%"><!-- -------------- End of header ------------------ --><!-- ----------------------------------------------- -->
|
||||||
|
<center>
|
||||||
|
<h1>
|
||||||
|
<font color="#FF0000">FirstRealEA.cpp</font></h1></center>
|
||||||
|
Click on the figure to see the corresponding code.<br>
|
||||||
|
In the code, the <a href="eoTutorial.html#colors">colors are meaningfull</a><br>
|
||||||
|
The actual code is in boldface and the comment in normal face.
|
||||||
|
<br><img SRC="EA_tutorial.jpg" USEMAP="#Map" >
|
||||||
|
<map NAME="Map">
|
||||||
|
<!-- Init -->
|
||||||
|
<area SHAPE="rect" HREF="#init" COORDS="14,31,135,70">
|
||||||
|
<area SHAPE="rect" HREF="#eval" COORDS="14,110,135,150">
|
||||||
|
<!-- main loop -->
|
||||||
|
<area SHAPE="rect" HREF="#representation" COORDS="170,110,295,150">
|
||||||
|
<area SHAPE="rect" HREF="#output" COORDS="280,45,480,70">
|
||||||
|
<area SHAPE="rect" HREF="#stop" COORDS="348,110,430,150">
|
||||||
|
<area SHAPE="rect" HREF="#select" COORDS="495,110,615,150">
|
||||||
|
<area SHAPE="rect" HREF="#representation" COORDS="495,190,615,230">
|
||||||
|
<area SHAPE="rect" HREF="#crossover" COORDS="495,265,625,287">
|
||||||
|
<area SHAPE="rect" HREF="#mutation" COORDS="495,287,625,305">
|
||||||
|
<area SHAPE="rect" HREF="#representation" COORDS="240,270,465,310">
|
||||||
|
<area SHAPE="rect" HREF="#eval" COORDS="170,270,295,310">
|
||||||
|
<area SHAPE="rect" HREF="#replace" COORDS="170,190,295,230">
|
||||||
|
<!-- Center of loop -->
|
||||||
|
<area SHAPE="rect" HREF="#generation" COORDS="310,160,485,260">
|
||||||
|
<!-- 4 bottom lines -->
|
||||||
|
<area SHAPE="rect" HREF="#operators" COORDS="15,350,260,370">
|
||||||
|
<area SHAPE="rect" HREF="#representation" COORDS="270,350,460,370">
|
||||||
|
<area SHAPE="rect" HREF="#engine" COORDS="15,377,400,397">
|
||||||
|
<area SHAPE="rect" HREF="#eval" COORDS="15,403,230,423">
|
||||||
|
<area SHAPE="rect" HREF="#checkpoint" COORDS="15,430,221,450">
|
||||||
|
<area SHAPE="rect" HREF="#stop" COORDS="221,430,345,450">
|
||||||
|
<area SHAPE="rect" HREF="#stat" COORDS="375,430,445,450">
|
||||||
|
<area SHAPE="rect" HREF="#parametres" COORDS="0,358,278,378">
|
||||||
|
</map>
|
||||||
|
<br>
|
||||||
|
<A NAME="start"></a>
|
||||||
|
<table BORDER=0 CELLSPACING=0 COLS=1 WIDTH="100%" BGCOLOR="#FFCC99" NOSAVE >
|
||||||
|
<tr NOSAVE>
|
||||||
|
<td NOSAVE><tt><font color="#993300">
|
||||||
|
//-----------------------------------------------------------------------------<br>
|
||||||
|
// FirstRealEA.cpp<br>
|
||||||
|
//-----------------------------------------------------------------------------<br>
|
||||||
|
//*<br>
|
||||||
|
// Still an instance of a VERY simple Real-coded Genetic Algorithm <br>
|
||||||
|
// (see FirstBitGA.cpp) but now with Breeder - and Combined Ops<br>
|
||||||
|
//<br>
|
||||||
|
//-----------------------------------------------------------------------------<br>
|
||||||
|
// standard includes<br>
|
||||||
|
<b>#include <stdexcept> </b>// runtime_error <br>
|
||||||
|
<b>#include <iostream> </b>// cout<br>
|
||||||
|
<b>#include <strstream> </b>// ostrstream, istrstream<br>
|
||||||
|
// the general include for eo<br>
|
||||||
|
<b>#include <eo></b><br>
|
||||||
|
</font></tt>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<a NAME="representation"></a><table BORDER=0 CELLSPACING=0 COLS=1 WIDTH="100%" BGCOLOR="#FFFFCC" NOSAVE >
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<tt><font color="#999900">
|
||||||
|
//-----------------------------------------------------------------------------<br>
|
||||||
|
// define your individuals<br>
|
||||||
|
<b>typedef eoReal<double> Indi; </b><br>
|
||||||
|
</font></tt>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<a NAME="evalfunc"></a><table BORDER=0 CELLSPACING=0 COLS=1 WIDTH="100%" BGCOLOR="#FFCCCC" NOSAVE >
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<tt><font color="#CC0000">
|
||||||
|
//-----------------------------------------------------------------------------<br>
|
||||||
|
// a simple fitness function that computes the euclidian norm of a real vector<br>
|
||||||
|
// Now in a separate file, and declared as binary_value(const vector<bool> &)<br>
|
||||||
|
<b>#include "real_value.h"</b><br>
|
||||||
|
</font></tt>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<a NAME="general"></a><table BORDER=0 CELLSPACING=0 COLS=1 WIDTH="100%" BGCOLOR="#FFCC99" NOSAVE >
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<tt><font color="#993300">
|
||||||
|
//-----------------------------------------------------------------------------<br>
|
||||||
|
<b>void main_function(int argc, char **argv)</b><br>
|
||||||
|
<b>{</b><br>
|
||||||
|
</font></tt>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<a NAME="parametres"></a><table BORDER=0 CELLSPACING=0 COLS=1 WIDTH="100%" BGCOLOR="#CCFFFF" NOSAVE >
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<tt><font color="#3366FF">
|
||||||
|
<b> const unsigned int SEED = 42; </b>// seed for random number generator<br>
|
||||||
|
<b> const unsigned int T_SIZE = 3; </b>// size for tournament selection<br>
|
||||||
|
<b> const unsigned int VEC_SIZE = 8; </b>// Number of object variables in genotypes<br>
|
||||||
|
<b> const unsigned int POP_SIZE = 20; </b>// Size of population<br>
|
||||||
|
<b> const unsigned int MAX_GEN = 500; </b>// Maximum number of generation before STOP<br>
|
||||||
|
<b> const unsigned int MIN_GEN = 10; </b>// Minimum number of generation before ...<br>
|
||||||
|
<b> const unsigned int STEADY_GEN = 50; </b>// stop after STEADY_GEN gen. without improvelent<br>
|
||||||
|
<b> const float P_CROSS = 0.8; </b>// Crossover probability<br>
|
||||||
|
<b> const float P_MUT = 0.5; </b>// mutation probability<br>
|
||||||
|
<b> const double EPSILON = 0.01; </b>// range for real uniform mutation<br>
|
||||||
|
<b> </b>// some parameters for chosing among different operators<br>
|
||||||
|
<b> const double segmentRate = 0.5; </b>// rate for 1-pt Xover<br>
|
||||||
|
<b> const double arithmeticRate = 0.5; </b>// rate for 2-pt Xover<br>
|
||||||
|
<b> const double uniformMutRate = 0.5; </b>// rate for bit-flip mutation<br>
|
||||||
|
<b> const double detMutRate = 0.5; </b>// rate for one-bit mutation<br>
|
||||||
|
</font></tt>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<a NAME="general"></a><table BORDER=0 CELLSPACING=0 COLS=1 WIDTH="100%" BGCOLOR="#FFCC99" NOSAVE >
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<tt><font color="#993300">
|
||||||
|
<b> </b>//////////////////////////<br>
|
||||||
|
<b> </b>// Random seed<br>
|
||||||
|
<b> </b>//////////////////////////<br>
|
||||||
|
<b> </b>//reproducible random seed: if you don't change SEED above, <br>
|
||||||
|
<b> </b>// you'll aways get the same result, NOT a random run<br>
|
||||||
|
<b> rng.reseed(SEED);</b><br>
|
||||||
|
</font></tt>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<a NAME="eval"></a><table BORDER=0 CELLSPACING=0 COLS=1 WIDTH="100%" BGCOLOR="#FFCCCC" NOSAVE >
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<tt><font color="#CC0000">
|
||||||
|
<b> </b>/////////////////////////////<br>
|
||||||
|
<b> </b>// Fitness function<br>
|
||||||
|
<b> </b>////////////////////////////<br>
|
||||||
|
<b> </b>// Evaluation: from a plain C++ fn to an EvalFunc Object<br>
|
||||||
|
<b> </b>// you need to give the full description of the function<br>
|
||||||
|
<b> eoEvalFuncPtr<Indi, double, const vector<double>& > eval( real_value );</b><br>
|
||||||
|
</font></tt>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<a NAME="init"></a><table BORDER=0 CELLSPACING=0 COLS=1 WIDTH="100%" BGCOLOR="#FFCCFF" NOSAVE >
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<tt><font color="#993399">
|
||||||
|
<b> </b>////////////////////////////////<br>
|
||||||
|
<b> </b>// Initilisation of population<br>
|
||||||
|
<b> </b>////////////////////////////////<br>
|
||||||
|
<b> </b>// based on a uniform generator<br>
|
||||||
|
<b> eoInitFixedLength<Indi, uniform_generator<double> ></b><br>
|
||||||
|
<b> random(VEC_SIZE, uniform_generator<double>(-1.0, 1.0));</b><br>
|
||||||
|
<b> </b>// Initialization of the population<br>
|
||||||
|
<b> eoPop<Indi> pop(POP_SIZE, random);</b><br>
|
||||||
|
<b> </b><br>
|
||||||
|
<b> </b>// and evaluate it in one loop<br>
|
||||||
|
<b> apply<Indi>(eval, pop); </b>// STL syntax<br>
|
||||||
|
</font></tt>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<a NAME="output"></a><table BORDER=0 CELLSPACING=0 COLS=1 WIDTH="100%" BGCOLOR="#CCFFFF" NOSAVE >
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<tt><font color="#3366FF">
|
||||||
|
<b> </b>// sort pop before printing it!<br>
|
||||||
|
<b> pop.sort();</b><br>
|
||||||
|
<b> </b>// Print (sorted) intial population (raw printout)<br>
|
||||||
|
<b> cout << "Initial Population" << endl;</b><br>
|
||||||
|
<b> cout << pop;</b><br>
|
||||||
|
</font></tt>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<a NAME="engine"></a><table BORDER=0 CELLSPACING=0 COLS=1 WIDTH="100%" BGCOLOR="#99FFCC" NOSAVE >
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<tt><font color="#009900">
|
||||||
|
<b> </b>/////////////////////////////////////<br>
|
||||||
|
<b> </b>// selection and replacement<br>
|
||||||
|
<b> </b>////////////////////////////////////<br>
|
||||||
|
</font></tt>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<a NAME="select"></a><table BORDER=0 CELLSPACING=0 COLS=1 WIDTH="100%" BGCOLOR="#99FFCC" NOSAVE >
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<tt><font color="#009900">
|
||||||
|
<b> </b>// The robust tournament selection<br>
|
||||||
|
<b> eoDetTournament<Indi> selectOne(T_SIZE);</b><br>
|
||||||
|
<a NAME="select_encapsulate"></a>
|
||||||
|
<b> </b>// is now encapsulated in a eoSelectPerc (entage)<br>
|
||||||
|
<b> eoSelectPerc<Indi> select(selectOne);</b>// by default rate==1<br>
|
||||||
|
</font></tt>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<a NAME="replace"></a><table BORDER=0 CELLSPACING=0 COLS=1 WIDTH="100%" BGCOLOR="#99FFCC" NOSAVE >
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<tt><font color="#009900">
|
||||||
|
<b> </b>// And we now have the full slection/replacement - though with <br>
|
||||||
|
<b> </b>// no replacement (== generational replacement) at the moment :-)<br>
|
||||||
|
<b> eoNoReplacement<Indi> replace; </b><br>
|
||||||
|
</font></tt>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<a NAME="operators"></a><table BORDER=0 CELLSPACING=0 COLS=1 WIDTH="100%" BGCOLOR="#FFCCFF" NOSAVE >
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<tt><font color="#993399">
|
||||||
|
<b> </b>//////////////////////////////////////<br>
|
||||||
|
<b> </b>// The variation operators<br>
|
||||||
|
<b> </b>//////////////////////////////////////<br>
|
||||||
|
</font></tt>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<a NAME="crossover"></a><table BORDER=0 CELLSPACING=0 COLS=1 WIDTH="100%" BGCOLOR="#FFCCFF" NOSAVE >
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<tt><font color="#993399">
|
||||||
|
<b> </b>// uniform chooce on segment made by the parents<br>
|
||||||
|
<b> eoSegmentCrossover<Indi> xoverS;</b><br>
|
||||||
|
<b> </b>// uniform choice in hypercube built by the parents<br>
|
||||||
|
<b> eoArithmeticCrossover<Indi> xoverA;</b><br>
|
||||||
|
<b> </b>// Combine them with relative rates<br>
|
||||||
|
<b> eoPropCombinedQuadOp<Indi> xover(xoverS, segmentRate);</b><br>
|
||||||
|
<b> xover.add(xoverA, arithmeticRate, true);</b><br>
|
||||||
|
</font></tt>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<a NAME="mutation"></a><table BORDER=0 CELLSPACING=0 COLS=1 WIDTH="100%" BGCOLOR="#FFCCFF" NOSAVE >
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<tt><font color="#993399">
|
||||||
|
<b> </b><br>
|
||||||
|
<b> </b>// offspring(i) uniformly chosen in [parent(i)-epsilon, parent(i)+epsilon]<br>
|
||||||
|
<b> eoUniformMutation<Indi> mutationU(EPSILON); </b><br>
|
||||||
|
<b> </b>// k (=1) coordinates of parents are uniformly modified<br>
|
||||||
|
<b> eoDetUniformMutation<Indi> mutationD(EPSILON); </b><br>
|
||||||
|
<b> </b>// Combine them with relative rates<br>
|
||||||
|
<b> eoPropCombinedMonOp<Indi> mutation(mutationU, uniformMutRate);</b><br>
|
||||||
|
<b> mutation.add(mutationD, detMutRate, true);</b><br>
|
||||||
|
<b> </b><br>
|
||||||
|
<b> </b>// The operators are encapsulated into an eoTRansform object<br>
|
||||||
|
<b> eoSGATransform<Indi> transform(xover, P_CROSS, mutation, P_MUT);</b><br>
|
||||||
|
</font></tt>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<a NAME="stop"></a><table BORDER=0 CELLSPACING=0 COLS=1 WIDTH="100%" BGCOLOR="#CCFFFF" NOSAVE >
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<tt><font color="#3366FF">
|
||||||
|
</font></tt>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<a NAME="checkpoint"></a><table BORDER=0 CELLSPACING=0 COLS=1 WIDTH="100%" BGCOLOR="#CCFFFF" NOSAVE >
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<tt><font color="#3366FF">
|
||||||
|
<b> </b>//////////////////////////////////////<br>
|
||||||
|
<b> </b>// termination conditions: use more than one<br>
|
||||||
|
<b> </b>/////////////////////////////////////<br>
|
||||||
|
<b> </b>// stop after MAX_GEN generations<br>
|
||||||
|
<b> eoGenContinue<Indi> genCont(MAX_GEN);</b><br>
|
||||||
|
<b> </b>// do MIN_GEN gen., then stop after STEADY_GEN gen. without improvement<br>
|
||||||
|
<b> eoSteadyFitContinue<Indi> steadyCont(MIN_GEN, STEADY_GEN);</b><br>
|
||||||
|
<b> </b>// stop when fitness reaches a target (here VEC_SIZE)<br>
|
||||||
|
<b> eoFitContinue<Indi> fitCont(0);</b><br>
|
||||||
|
<b> </b>// do stop when one of the above says so<br>
|
||||||
|
<b> eoCombinedContinue<Indi> continuator(genCont);</b><br>
|
||||||
|
<b> continuator.add(steadyCont);</b><br>
|
||||||
|
<b> continuator.add(fitCont);</b><br>
|
||||||
|
</font></tt>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<a NAME="generation"></a><table BORDER=0 CELLSPACING=0 COLS=1 WIDTH="100%" BGCOLOR="#FFCC99" NOSAVE >
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<tt><font color="#FF6666">
|
||||||
|
<b> </b>/////////////////////////////////////////<br>
|
||||||
|
<b> </b>// the algorithm<br>
|
||||||
|
<b> </b>////////////////////////////////////////<br>
|
||||||
|
<b> </b>// Easy EA requires <br>
|
||||||
|
<b> </b>// selection, transformation, eval, replacement, and stopping criterion<br>
|
||||||
|
<b> eoEasyEA<Indi> gga(continuator, eval, select, transform, replace);</b><br>
|
||||||
|
<b> </b>// Apply algo to pop - that's it!<br>
|
||||||
|
<b> cout << "\n Here we go\n\n";</b><br>
|
||||||
|
<b> gga(pop);</b><br>
|
||||||
|
<b> </b><br>
|
||||||
|
</font></tt>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<a NAME="output"></a><table BORDER=0 CELLSPACING=0 COLS=1 WIDTH="100%" BGCOLOR="#CCFFFF" NOSAVE >
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<tt><font color="#3366FF">
|
||||||
|
<b> </b>// Print (sorted) intial population<br>
|
||||||
|
<b> pop.sort();</b><br>
|
||||||
|
<b> cout << "FINAL Population\n" << pop << endl;</b><br>
|
||||||
|
</font></tt>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<a NAME="general"></a><table BORDER=0 CELLSPACING=0 COLS=1 WIDTH="100%" BGCOLOR="#FFCC99" NOSAVE >
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<tt><font color="#993300">
|
||||||
|
<b>}</b><br>
|
||||||
|
// A main that catches the exceptions<br>
|
||||||
|
<b>int main(int argc, char **argv)</b><br>
|
||||||
|
<b>{</b><br>
|
||||||
|
<b>#ifdef _MSC_VER</b><br>
|
||||||
|
<b> </b>// rng.reseed(42);<br>
|
||||||
|
<b> int flag = _CrtSetDbgFlag(_CRTDBG_LEAK_CHECK_DF);</b><br>
|
||||||
|
<b> flag |= _CRTDBG_LEAK_CHECK_DF;</b><br>
|
||||||
|
<b> _CrtSetDbgFlag(flag);</b><br>
|
||||||
|
// _CrtSetBreakAlloc(100);<br>
|
||||||
|
<b>#endif</b><br>
|
||||||
|
<b> try</b><br>
|
||||||
|
<b> {</b><br>
|
||||||
|
<b> main_function(argc, argv);</b><br>
|
||||||
|
<b> }</b><br>
|
||||||
|
<b> catch(exception& e)</b><br>
|
||||||
|
<b> {</b><br>
|
||||||
|
<b> cout << "Exception: " << e.what() << '\n';</b><br>
|
||||||
|
<b> }</b><br>
|
||||||
|
<b> return 1;</b><br>
|
||||||
|
<b>}</b><br>
|
||||||
|
</font></font></font></td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<hr WIDTH="100%"><a href="eoLesson2.html">Back to Lesson 2</a> - <a href="eoTutorial.html">Tutorial
|
||||||
|
main page </a>- <a href="eoTopDown.html">Top-Down page</a> - <a href="eoBottomUp.html">Bottom-up
|
||||||
|
page</a> - <a href="eoProgramming.html">Programming hints</a> - <font face="Arial,Helvetica"><a href="doc/html/index.html">EO
|
||||||
|
documentation</a></font>
|
||||||
|
<hr>
|
||||||
|
<address>
|
||||||
|
<a href="mailto:marc.schoenauer@polytechnique.fr">Marc Schoenauer</a></address>
|
||||||
|
<br><!-- Created: Nov 2000 --><!-- hhmts start -->Last
|
||||||
|
modified: Wed Nov 29 07:38:36 2000
|
||||||
|
<!-- hhmts end -->
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
349
eo/tutorial/html/FirstRealGA.html
Normal file
349
eo/tutorial/html/FirstRealGA.html
Normal file
|
|
@ -0,0 +1,349 @@
|
||||||
|
<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||||
|
<meta name="GENERATOR" content="cpp2html Marc Schoenauer">
|
||||||
|
<title>../FirstRealGA.html</title>
|
||||||
|
<!-- Changed by: Marc Schoenauer, 29-Nov-2000 -->
|
||||||
|
</head>
|
||||||
|
<body text="#000000" bgcolor="#C3C2B4" link="#0000EE" vlink="#551A8B" alink="#FF0000">
|
||||||
|
<a href="eoLesson1.html">Back to Lesson 1</a> - <a href="eoTutorial.html">Tutorial
|
||||||
|
main page </a>- <a href="eoTopDown.html">Top-Down page</a> - <a href="eoBottomUp.html">Bottom-up
|
||||||
|
page</a> - <a href="eoProgramming.html">Programming hints</a> - <font face="Arial,Helvetica"><a href="doc/html/index.html">EO
|
||||||
|
documentation</a></font>
|
||||||
|
<br>
|
||||||
|
<hr WIDTH="100%"><!-- -------------- End of header ------------------ --><!-- ----------------------------------------------- -->
|
||||||
|
<center>
|
||||||
|
<h1>
|
||||||
|
<font color="#FF0000">../FirstRealGA.html</font></h1></center>
|
||||||
|
Click on the figure to see the corresponding code.<br>
|
||||||
|
In the code, the <a href="eoTutorial.html#colors">colors are meaningfull</a><br>
|
||||||
|
The actual code is in boldface and the comment in normal face.
|
||||||
|
<br><img SRC="EA_tutorial.jpg" USEMAP="#Map" >
|
||||||
|
<map NAME="Map">
|
||||||
|
<!-- Init -->
|
||||||
|
<area SHAPE="rect" HREF="#init" COORDS="14,31,135,70">
|
||||||
|
<area SHAPE="rect" HREF="#eval" COORDS="14,110,135,150">
|
||||||
|
<!-- main loop -->
|
||||||
|
<area SHAPE="rect" HREF="#representation" COORDS="170,110,295,150">
|
||||||
|
<area SHAPE="rect" HREF="#output" COORDS="280,45,480,70">
|
||||||
|
<area SHAPE="rect" HREF="#stop" COORDS="348,110,430,150">
|
||||||
|
<area SHAPE="rect" HREF="#select" COORDS="495,110,615,150">
|
||||||
|
<area SHAPE="rect" HREF="#representation" COORDS="495,190,615,230">
|
||||||
|
<area SHAPE="rect" HREF="#crossover" COORDS="495,265,625,287">
|
||||||
|
<area SHAPE="rect" HREF="#mutation" COORDS="495,287,625,305">
|
||||||
|
<area SHAPE="rect" HREF="#representation" COORDS="240,270,465,310">
|
||||||
|
<area SHAPE="rect" HREF="#eval" COORDS="170,270,295,310">
|
||||||
|
<area SHAPE="rect" HREF="#replace" COORDS="170,190,295,230">
|
||||||
|
<!-- Center of loop -->
|
||||||
|
<area SHAPE="rect" HREF="#generation" COORDS="310,160,485,260">
|
||||||
|
<!-- 4 bottom lines -->
|
||||||
|
<area SHAPE="rect" HREF="#operators" COORDS="15,350,260,370">
|
||||||
|
<area SHAPE="rect" HREF="#representation" COORDS="270,350,460,370">
|
||||||
|
<area SHAPE="rect" HREF="#engine" COORDS="15,377,400,397">
|
||||||
|
<area SHAPE="rect" HREF="#eval" COORDS="15,403,230,423">
|
||||||
|
<area SHAPE="rect" HREF="#checkpoint" COORDS="15,430,221,450">
|
||||||
|
<area SHAPE="rect" HREF="#stop" COORDS="221,430,345,450">
|
||||||
|
<area SHAPE="rect" HREF="#stat" COORDS="375,430,445,450">
|
||||||
|
<area SHAPE="rect" HREF="#parametres" COORDS="0,358,278,378">
|
||||||
|
</map>
|
||||||
|
<br>
|
||||||
|
<A NAME="start"></a>
|
||||||
|
<table BORDER=0 CELLSPACING=0 COLS=1 WIDTH="100%" BGCOLOR="#FFCC99" NOSAVE >
|
||||||
|
<tr NOSAVE>
|
||||||
|
<td NOSAVE><tt><font color="#993300">
|
||||||
|
//-----------------------------------------------------------------------------<br>
|
||||||
|
// FirstRealGA.cpp<br>
|
||||||
|
//-----------------------------------------------------------------------------<br>
|
||||||
|
//*<br>
|
||||||
|
// An instance of a VERY simple Real-coded Genetic Algorithm<br>
|
||||||
|
//<br>
|
||||||
|
//-----------------------------------------------------------------------------<br>
|
||||||
|
// standard includes<br>
|
||||||
|
<b>#include <stdexcept> </b>// runtime_error <br>
|
||||||
|
<b>#include <iostream> </b>// cout<br>
|
||||||
|
<b>#include <strstream> </b>// ostrstream, istrstream<br>
|
||||||
|
// the general include for eo<br>
|
||||||
|
<b>#include <eo></b><br>
|
||||||
|
</font></tt>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<a NAME="representation"></a><table BORDER=0 CELLSPACING=0 COLS=1 WIDTH="100%" BGCOLOR="#FFFFCC" NOSAVE >
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<tt><font color="#999900">
|
||||||
|
//-----------------------------------------------------------------------------<br>
|
||||||
|
// define your individuals<br>
|
||||||
|
<b> typedef eoReal<double> Indi;</b><br>
|
||||||
|
</font></tt>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<table BORDER=0 CELLSPACING=0 COLS=1 WIDTH="100%" BGCOLOR="#FFCCCC" NOSAVE >
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<tt><font color="#CC0000">
|
||||||
|
//-----------------------------------------------------------------------------<br>
|
||||||
|
// a simple fitness function that computes the euclidian norm of a real vector<br>
|
||||||
|
// @param _indi A real-valued individual <br>
|
||||||
|
<a name="evalfunc"></a>
|
||||||
|
<b>double real_value(const Indi & _indi)</b><br>
|
||||||
|
<b>{</b><br>
|
||||||
|
<b> double sum = 0;</b><br>
|
||||||
|
<b> for (unsigned i = 0; i < _indi.size(); i++)</b><br>
|
||||||
|
<b> sum += _indi[i]*_indi[i];</b><br>
|
||||||
|
<b> return (-sum); </b>// maximizing only<br>
|
||||||
|
<b>}</b><br>
|
||||||
|
</font></tt>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<a NAME="general"></a><table BORDER=0 CELLSPACING=0 COLS=1 WIDTH="100%" BGCOLOR="#FFCC99" NOSAVE >
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<tt><font color="#993300">
|
||||||
|
//-----------------------------------------------------------------------------<br>
|
||||||
|
<b>void main_function(int argc, char **argv)</b><br>
|
||||||
|
<b>{</b><br>
|
||||||
|
</font></tt>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<a NAME="parametres"></a><table BORDER=0 CELLSPACING=0 COLS=1 WIDTH="100%" BGCOLOR="#CCFFFF" NOSAVE >
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<tt><font color="#3366FF">
|
||||||
|
<b> </b>// all parameters are hard-coded!<br>
|
||||||
|
<b> const unsigned int SEED = 42; </b>// seed for random number generator<br>
|
||||||
|
<b> const unsigned int VEC_SIZE = 8; </b>// Number of object variables in genotypes<br>
|
||||||
|
<b> const unsigned int POP_SIZE = 20; </b>// Size of population<br>
|
||||||
|
<b> const unsigned int T_SIZE = 3; </b>// size for tournament selection<br>
|
||||||
|
<b> const unsigned int MAX_GEN = 500; </b>// Maximum number of generation before STOP<br>
|
||||||
|
<b> const float CROSS_RATE = 0.8; </b>// Crossover rate<br>
|
||||||
|
<b> const double EPSILON = 0.01; </b>// range for real uniform mutation<br>
|
||||||
|
<b> const float MUT_RATE = 0.5; </b>// mutation rate<br>
|
||||||
|
</font></tt>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<a NAME="general"></a><table BORDER=0 CELLSPACING=0 COLS=1 WIDTH="100%" BGCOLOR="#FFCC99" NOSAVE >
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<tt><font color="#993300">
|
||||||
|
<a NAME="random"></a>
|
||||||
|
<b> </b>//////////////////////////<br>
|
||||||
|
<b> </b>// Random seed<br>
|
||||||
|
<b> </b>//////////////////////////<br>
|
||||||
|
<b> </b>//reproducible random seed: if you don't change SEED above, <br>
|
||||||
|
<b> </b>// you'll aways get the same result, NOT a random run<br>
|
||||||
|
<b> rng.reseed(SEED);</b><br>
|
||||||
|
</font></tt>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<a NAME="eval"></a><table BORDER=0 CELLSPACING=0 COLS=1 WIDTH="100%" BGCOLOR="#FFCCCC" NOSAVE >
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<tt><font color="#CC0000">
|
||||||
|
<b> </b>/////////////////////////////<br>
|
||||||
|
<b> </b>// Fitness function<br>
|
||||||
|
<b> </b>////////////////////////////<br>
|
||||||
|
<b> </b>// Evaluation: from a plain C++ fn to an EvalFunc Object<br>
|
||||||
|
<b> eoEvalFuncPtr<Indi> eval( real_value );</b><br>
|
||||||
|
</font></tt>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<a NAME="init"></a><table BORDER=0 CELLSPACING=0 COLS=1 WIDTH="100%" BGCOLOR="#FFCCFF" NOSAVE >
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<tt><font color="#993399">
|
||||||
|
<b> </b>////////////////////////////////<br>
|
||||||
|
<b> </b>// Initilisation of population<br>
|
||||||
|
<b> </b>////////////////////////////////<br>
|
||||||
|
<b> </b>// declare the population<br>
|
||||||
|
<b> eoPop<Indi> pop;</b><br>
|
||||||
|
<b> </b>// fill it!<br>
|
||||||
|
<b> for (unsigned int igeno=0; igeno<POP_SIZE; igeno++)</b><br>
|
||||||
|
<b> {</b><br>
|
||||||
|
<b> Indi v; </b>// void individual, to be filled<br>
|
||||||
|
<b> for (unsigned ivar=0; ivar<VEC_SIZE; ivar++)</b><br>
|
||||||
|
<b> {</b><br>
|
||||||
|
<b> double r = 2*rng.uniform() - 1; </b>// new value, random in [-1,1)<br>
|
||||||
|
<b> v.push_back(r); </b>// append that random value to v<br>
|
||||||
|
<b> }</b><br>
|
||||||
|
<b> eval(v); </b>// evaluate it<br>
|
||||||
|
<b> pop.push_back(v); </b>// and put it in the population<br>
|
||||||
|
<b> }</b><br>
|
||||||
|
</font></tt>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<a NAME="output"></a><table BORDER=0 CELLSPACING=0 COLS=1 WIDTH="100%" BGCOLOR="#CCFFFF" NOSAVE >
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<tt><font color="#3366FF">
|
||||||
|
<b> </b>// sort pop before printing it!<br>
|
||||||
|
<b> pop.sort();</b><br>
|
||||||
|
<b> </b>// Print (sorted) intial population (raw printout)<br>
|
||||||
|
<b> cout << "Initial Population" << endl;</b><br>
|
||||||
|
<b> cout << pop;</b><br>
|
||||||
|
</font></tt>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<a NAME="engine"></a><table BORDER=0 CELLSPACING=0 COLS=1 WIDTH="100%" BGCOLOR="#99FFCC" NOSAVE >
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<tt><font color="#009900">
|
||||||
|
<b> </b>/////////////////////////////////////<br>
|
||||||
|
<b> </b>// selection and replacement<br>
|
||||||
|
<b> </b>////////////////////////////////////<br>
|
||||||
|
</font></tt>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<a NAME="select"></a><table BORDER=0 CELLSPACING=0 COLS=1 WIDTH="100%" BGCOLOR="#99FFCC" NOSAVE >
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<tt><font color="#009900">
|
||||||
|
<b> </b>// The robust tournament selection<br>
|
||||||
|
<b> eoDetTournament<Indi> select(T_SIZE); </b>// T_SIZE in [2,POP_SIZE]<br>
|
||||||
|
</font></tt>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<a NAME="replace"></a><table BORDER=0 CELLSPACING=0 COLS=1 WIDTH="100%" BGCOLOR="#99FFCC" NOSAVE >
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<tt><font color="#009900">
|
||||||
|
<b> </b>// eoSGA uses generational replacement by default<br>
|
||||||
|
<b> </b>// so no replacement procedure has to be given<br>
|
||||||
|
</font></tt>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<a NAME="stop"></a><table BORDER=0 CELLSPACING=0 COLS=1 WIDTH="100%" BGCOLOR="#CCFFFF" NOSAVE >
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<tt><font color="#3366FF">
|
||||||
|
</font></tt>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<a NAME="checkpoint"></a><table BORDER=0 CELLSPACING=0 COLS=1 WIDTH="100%" BGCOLOR="#CCFFFF" NOSAVE >
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<tt><font color="#3366FF">
|
||||||
|
<b> </b>//////////////////////////////////////<br>
|
||||||
|
<b> </b>// termination condition<br>
|
||||||
|
<b> </b>/////////////////////////////////////<br>
|
||||||
|
<b> </b>// stop after MAX_GEN generations<br>
|
||||||
|
<b> eoGenContinue<Indi> continuator(MAX_GEN);</b><br>
|
||||||
|
<b> </b><br>
|
||||||
|
</font></tt>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<a NAME="operators"></a><table BORDER=0 CELLSPACING=0 COLS=1 WIDTH="100%" BGCOLOR="#FFCCFF" NOSAVE >
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<tt><font color="#993399">
|
||||||
|
<b> </b>//////////////////////////////////////<br>
|
||||||
|
<b> </b>// The variation operators<br>
|
||||||
|
<b> </b>//////////////////////////////////////<br>
|
||||||
|
</font></tt>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<a NAME="mutation"></a><table BORDER=0 CELLSPACING=0 COLS=1 WIDTH="100%" BGCOLOR="#FFCCFF" NOSAVE >
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<tt><font color="#993399">
|
||||||
|
<b> </b>// offspring(i) uniformly chosen in [parent(i)-epsilon, parent(i)+epsilon]<br>
|
||||||
|
<b> eoUniformMutation<Indi> mutation(EPSILON); </b><br>
|
||||||
|
</font></tt>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<a NAME="crossover"></a><table BORDER=0 CELLSPACING=0 COLS=1 WIDTH="100%" BGCOLOR="#FFCCFF" NOSAVE >
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<tt><font color="#993399">
|
||||||
|
<b> </b>// offspring(i) is a linear combination of parent(i)<br>
|
||||||
|
<b> eoArithmeticCrossover<Indi> xover;</b><br>
|
||||||
|
</font></tt>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<a NAME="generation"></a><table BORDER=0 CELLSPACING=0 COLS=1 WIDTH="100%" BGCOLOR="#FFCC99" NOSAVE >
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<tt><font color="#FF6666">
|
||||||
|
<b> </b>/////////////////////////////////////////<br>
|
||||||
|
<b> </b>// the algorithm<br>
|
||||||
|
<b> </b>////////////////////////////////////////<br>
|
||||||
|
<b> </b>// standard Generational GA requires<br>
|
||||||
|
<b> </b>// selection, evaluation, crossover and mutation, stopping criterion<br>
|
||||||
|
<b> </b><br>
|
||||||
|
<b> eoSGA<Indi> gga(select, xover, CROSS_RATE, mutation, MUT_RATE, </b><br>
|
||||||
|
<b> eval, continuator);</b><br>
|
||||||
|
<b> </b>// Apply algo to pop - that's it!<br>
|
||||||
|
<b> gga(pop);</b><br>
|
||||||
|
<b> </b><br>
|
||||||
|
</font></tt>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<a NAME="final_output"></a><table BORDER=0 CELLSPACING=0 COLS=1 WIDTH="100%" BGCOLOR="#CCFFFF" NOSAVE >
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<tt><font color="#3366FF">
|
||||||
|
<b> </b>// Print (sorted) intial population<br>
|
||||||
|
<b> pop.sort();</b><br>
|
||||||
|
<b> cout << "FINAL Population\n" << pop << endl;</b><br>
|
||||||
|
</font></tt>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<a NAME="main"></a><table BORDER=0 CELLSPACING=0 COLS=1 WIDTH="100%" BGCOLOR="#FFCC99" NOSAVE >
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<tt><font color="#993300">
|
||||||
|
<b>}</b><br>
|
||||||
|
// A main that catches the exceptions<br>
|
||||||
|
<b>int main(int argc, char **argv)</b><br>
|
||||||
|
<b>{</b><br>
|
||||||
|
<b>#ifdef _MSC_VER</b><br>
|
||||||
|
<b> </b>// rng.reseed(42);<br>
|
||||||
|
<b> int flag = _CrtSetDbgFlag(_CRTDBG_LEAK_CHECK_DF);</b><br>
|
||||||
|
<b> flag |= _CRTDBG_LEAK_CHECK_DF;</b><br>
|
||||||
|
<b> _CrtSetDbgFlag(flag);</b><br>
|
||||||
|
// _CrtSetBreakAlloc(100);<br>
|
||||||
|
<b>#endif</b><br>
|
||||||
|
<b> try</b><br>
|
||||||
|
<b> {</b><br>
|
||||||
|
<b> main_function(argc, argv);</b><br>
|
||||||
|
<b> }</b><br>
|
||||||
|
<b> catch(exception& e)</b><br>
|
||||||
|
<b> {</b><br>
|
||||||
|
<b> cout << "Exception: " << e.what() << '\n';</b><br>
|
||||||
|
<b> }</b><br>
|
||||||
|
<b> return 1;</b><br>
|
||||||
|
<b>}</b><br>
|
||||||
|
</font></font></font></td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<hr WIDTH="100%"><a href="eoLesson1.html">Back to Lesson 1</a> - <a href="eoTutorial.html">Tutorial
|
||||||
|
main page </a>- <a href="eoTopDown.html">Top-Down page</a> - <a href="eoBottomUp.html">Bottom-up
|
||||||
|
page</a> - <a href="eoProgramming.html">Programming hints</a> - <font face="Arial,Helvetica"><a href="doc/html/index.html">EO
|
||||||
|
documentation</a></font>
|
||||||
|
<hr>
|
||||||
|
<address>
|
||||||
|
<a href="mailto:marc.schoenauer@polytechnique.fr">Marc Schoenauer</a></address>
|
||||||
|
<br><!-- Created: Nov 2000 --><!-- hhmts start -->Last
|
||||||
|
modified: Sun Nov 19 08:31:29 2000
|
||||||
|
<!-- hhmts end -->
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
278
eo/tutorial/html/FirstRealGA_old.html
Normal file
278
eo/tutorial/html/FirstRealGA_old.html
Normal file
|
|
@ -0,0 +1,278 @@
|
||||||
|
<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||||
|
<meta name="GENERATOR" content="Mozilla/4.51 [en] (X11; I; Linux 2.2.5-15 i686) [Netscape]">
|
||||||
|
<title>First Real GA</title>
|
||||||
|
</head>
|
||||||
|
<body text="#000000" bgcolor="#C3C2B4" link="#0000EE" vlink="#551A8B" alink="#FF0000">
|
||||||
|
<a href="eoLesson1.html">Back to Lesson 1</a> - <a href="eoTutorial.html">Tutorial
|
||||||
|
main page </a>- <a href="eoTopDown.html">Top-Down page</a> - <a href="eoBottomUp.html">Bottom-up
|
||||||
|
page</a> - <a href="eoProgramming.html">Programming hints</a> - <font face="Arial,Helvetica"><a href="doc/html/index.html">EO
|
||||||
|
documentation</a></font>
|
||||||
|
<br>
|
||||||
|
<hr WIDTH="100%"><!-- -------------- End of header ------------------ --><!-- ----------------------------------------------- -->
|
||||||
|
<center>
|
||||||
|
<h1>
|
||||||
|
<font color="#FF0000">A First Real GA</font></h1></center>
|
||||||
|
Click on the figure to see the corresponding code. Tutorial comments are
|
||||||
|
in variable length fonts, after the code.
|
||||||
|
<center>
|
||||||
|
<p><img SRC="EA_tutorial.jpg" USEMAP="#Map" ></center>
|
||||||
|
<map NAME="Map"><area SHAPE="rect" HREF="#init" COORDS="0,0,112,40"><area SHAPE="rect" HREF="#eval" COORDS="0,78,112,112"><area SHAPE="rect" HREF="#select" COORDS="395,70,507,107"><area SHAPE="rect" HREF="#replace" COORDS="145,144,253,182"><area SHAPE="rect" HREF="#crossover" COORDS="433,145,543,164"><area SHAPE="rect" HREF="#mutation" COORDS="433,164,543,182"><area SHAPE="rect" HREF="#eval" COORDS="218,217,325,252"><area SHAPE="rect" HREF="#output" COORDS="235,14,415,38"><area SHAPE="rect" HREF="#representation" COORDS="143,68,253,114"><area SHAPE="rect" HREF="#representation" COORDS="394,214,515,255"><area SHAPE="rect" HREF="#stop" COORDS="278,74,370,109"><area SHAPE="rect" HREF="#generation" COORDS="257,114,431,213"><!-- 4 lignes en bas --><area SHAPE="rect" HREF="#eval" COORDS="0,334,207,352"><area SHAPE="rect" HREF="#engine" COORDS="0,310,356,334"><area SHAPE="rect" HREF="#operators" COORDS="0,288,230,310"><area SHAPE="rect" HREF="#representation" COORDS="230,288,450,310"><area SHAPE="rect" HREF="#parametres" COORDS="0,358,278,378"></map>
|
||||||
|
<p><font face="Courier New,Courier"><font size=+1>//-----------------------------------------------------------------------------</font></font>
|
||||||
|
<p><font face="Courier New,Courier"><font color="#993300"><font size=+1>#include
|
||||||
|
<stdexcept > // runtime_error</font></font></font>
|
||||||
|
<p><font face="Courier New,Courier"><font size=+1>//-----------------------------------------------------------------------------</font></font>
|
||||||
|
<br><font face="Courier New,Courier"><font size=+1>// FirstRealGA.cpp</font></font>
|
||||||
|
<br><font face="Courier New,Courier"><font size=+1>//-----------------------------------------------------------------------------</font></font>
|
||||||
|
<br><font face="Courier New,Courier"><font size=+1>//*</font></font>
|
||||||
|
<br><font face="Courier New,Courier"><font size=+1>// An instance of a
|
||||||
|
VERY simple Real-coded Genetic Algorithm</font></font>
|
||||||
|
<br><font face="Courier New,Courier"><font size=+1>//</font></font>
|
||||||
|
<br><font face="Courier New,Courier"><font size=+1>//-----------------------------------------------------------------------------</font></font>
|
||||||
|
<br><font face="Courier New,Courier"><font size=+1>// standard includes</font></font>
|
||||||
|
<p><font face="Courier New,Courier"><font color="#993300"><font size=+1>#include
|
||||||
|
<iostream>// cout</font></font></font>
|
||||||
|
<br><font face="Courier New,Courier"><font color="#993300"><font size=+1>#include
|
||||||
|
<strstream>// ostrstream, istrstream</font></font></font>
|
||||||
|
<p><font face="Courier New,Courier"><font size=+1>// the general include
|
||||||
|
for eo</font></font>
|
||||||
|
<p><font face="Courier New,Courier"><font color="#FF6666"><font size=+1>#include
|
||||||
|
<eo></font></font></font>
|
||||||
|
<p><font face="Courier New,Courier"><font size=+1>// specific incluse,
|
||||||
|
as Real is not (yet) in the standard eo source dir</font></font>
|
||||||
|
<br><font face="Courier New,Courier"><font color="#FF6666"><font size=+1>#include
|
||||||
|
"eoeal.h"</font></font></font>
|
||||||
|
<br><font face="Courier New,Courier"><font color="#FF6666"><font size=+1>#include
|
||||||
|
"eoRealOp.h"</font></font></font>
|
||||||
|
<p><font face="Courier New,Courier"><font size=+1>//-----------------------------------------------------------------------------</font></font>
|
||||||
|
<br><font face="Courier New,Courier"><font size=+1>// define your individual:</font></font>
|
||||||
|
<p><a NAME="representation"></a><font face="Courier New,Courier"><font color="#FFFF00"><font size=+1>typedef
|
||||||
|
eoReal<double> Indi;</font></font></font>
|
||||||
|
<p>You say here that you will be handling <font face="Arial,Helvetica">arrays
|
||||||
|
of doubles</font>, whose fitness is a double
|
||||||
|
<br>Note that this makes Indi derive from <a href="eoProgramming.html#STL">STL
|
||||||
|
class</a> <font color="#993300">vector<double></font>
|
||||||
|
<br><font face="Courier New,Courier"><font size=+1>//-----------------------------------------------------------------------------</font></font>
|
||||||
|
<br><font face="Courier New,Courier"><font size=+1>/** a simple fitness
|
||||||
|
function that computes the euclidian norm of a real vector</font></font>
|
||||||
|
<br><font face="Courier New,Courier"><font size=+1> @param
|
||||||
|
_indi A real-valued individual</font></font>
|
||||||
|
<br><font face="Courier New,Courier"><font size=+1>*/</font></font>
|
||||||
|
<p><a NAME="evalfunc"></a><font face="Courier New,Courier"><font color="#CC0000"><font size=+1>double
|
||||||
|
real_value(const Indi & _indi)</font></font></font>
|
||||||
|
<br><font face="Courier New,Courier"><font color="#CC0000"><font size=+1>{</font></font></font>
|
||||||
|
<br><font face="Courier New,Courier"><font color="#CC0000"><font size=+1>
|
||||||
|
double sum = 0;</font></font></font>
|
||||||
|
<br><font face="Courier New,Courier"><font color="#CC0000"><font size=+1>
|
||||||
|
for (unsigned i = 0; i < _indi.size(); i++)</font></font></font>
|
||||||
|
<br><font face="Courier New,Courier"><font color="#CC0000"><font size=+1>
|
||||||
|
sum += _indi[i]*_indi[i];</font></font></font>
|
||||||
|
<br><font face="Courier New,Courier"><font color="#CC0000"><font size=+1>
|
||||||
|
return (-sum); // maximizing</font></font></font>
|
||||||
|
<br><font face="Courier New,Courier"><font color="#CC0000"><font size=+1>}</font></font></font>
|
||||||
|
<p>This simple function computes the sum of the squares of the variables
|
||||||
|
(remember Indi is here a vector of doubles)
|
||||||
|
<br><font face="Courier New,Courier"><font size=+1>//-----------------------------------------------------------------------------</font></font>
|
||||||
|
<p><font face="Courier New,Courier"><font color="#993300"><font size=+1>void
|
||||||
|
main_function(int argc, char **argv)</font></font></font>
|
||||||
|
<br><font face="Courier New,Courier"><font size=+1>{</font></font>
|
||||||
|
<br><font face="Courier New,Courier"><font color="#66FFFF"><font size=+1>const
|
||||||
|
unsigned int SEED = 42;// seed for random number generator</font></font></font>
|
||||||
|
<br><font face="Courier New,Courier"><font color="#66FFFF"><font size=+1>const
|
||||||
|
unsigned int VEC_SIZE = 8; // Number of object variables in genotypes</font></font></font>
|
||||||
|
<br><font face="Courier New,Courier"><font color="#66FFFF"><font size=+1>const
|
||||||
|
unsigned int POP_SIZE = 20; // Size of population</font></font></font>
|
||||||
|
<br><font face="Courier New,Courier"><font color="#66FFFF"><font size=+1>const
|
||||||
|
unsigned int T_SIZE = 3; // size for tournament selection</font></font></font>
|
||||||
|
<br><font face="Courier New,Courier"><font color="#66FFFF"><font size=+1>const
|
||||||
|
unsigned int MAX_GEN = 500; // Maximum number of generation before STOP</font></font></font>
|
||||||
|
<br><font face="Courier New,Courier"><font color="#66FFFF"><font size=+1>const
|
||||||
|
float CROSS_RATE = 0.8; // Crossover rate</font></font></font>
|
||||||
|
<br><font face="Courier New,Courier"><font color="#66FFFF"><font size=+1>const
|
||||||
|
double EPSILON = 0.01; // range for real uniform mutation</font></font></font>
|
||||||
|
<br><font face="Courier New,Courier"><font color="#66FFFF"><font size=+1>const
|
||||||
|
float MUT_RATE = 0.5; // mutation rate</font></font></font>
|
||||||
|
<br>
|
||||||
|
<p><font face="Courier New,Courier"><font size=+1>//////////////////////////</font></font>
|
||||||
|
<br><font face="Courier New,Courier"><font size=+1>// Random seed</font></font>
|
||||||
|
<br><font face="Courier New,Courier"><font size=+1>//////////////////////////</font></font>
|
||||||
|
<br><font face="Courier New,Courier"><font size=+1>//reproducible random
|
||||||
|
seed: if you don't change SEED above,</font></font>
|
||||||
|
<br><font face="Courier New,Courier"><font size=+1>// you'll aways get
|
||||||
|
the same result, NOT a random run</font></font>
|
||||||
|
<br><font face="Courier New,Courier"><font color="#FF6666"><font size=+1>rng.reseed(SEED);</font></font></font>
|
||||||
|
<p><font face="Courier New,Courier"><font size=+1>/////////////////////////////</font></font>
|
||||||
|
<br><font face="Courier New,Courier"><font size=+1>// Fitness function</font></font>
|
||||||
|
<br><font face="Courier New,Courier"><font size=+1>////////////////////////////</font></font>
|
||||||
|
<br><font face="Courier New,Courier"><font size=+1>// Evaluation: from
|
||||||
|
a plain C++ fn to an EvalFunc Object</font></font>
|
||||||
|
<br><a NAME="eval"></a><font face="Courier New,Courier"><font color="#CC0000"><font size=+1>eoEvalFuncPtr<Indi>
|
||||||
|
eval( <a href="#evalfunc">real_value</a> );</font></font></font>
|
||||||
|
<p>This encapsulate the C++ function real_value into a <a href="eoProgramming.html#functors">functor
|
||||||
|
object</a>
|
||||||
|
<p><font face="Courier New,Courier"><font size=+1>////////////////////////////////</font></font>
|
||||||
|
<br><font face="Courier New,Courier"><font size=+1>// Initilisation of
|
||||||
|
population</font></font>
|
||||||
|
<br><font face="Courier New,Courier"><font size=+1>////////////////////////////////</font></font>
|
||||||
|
<p><font face="Courier New,Courier"><font size=+1>// declare the population</font></font>
|
||||||
|
<br><font face="Courier New,Courier"><font color="#CC33CC"><font size=+1>eoPop<Indi>
|
||||||
|
pop;</font></font></font>
|
||||||
|
<p>Declares a <font face="Arial,Helvetica"><a href="doc/html/class_eopop.html">population
|
||||||
|
object</a>, </font>which is basically an <a href="eoProgramming.html#STL">STL</a>
|
||||||
|
<tt><font color="#993300"><font size=+1>vector<Indi></font></font></tt>
|
||||||
|
<p><font face="Courier New,Courier"><font size=+1>// fill it!</font></font>
|
||||||
|
<br><a NAME="init"></a><font face="Courier New,Courier"><font color="#CC33CC"><font size=+1>for
|
||||||
|
(unsigned int igeno=0; igeno<POP_SIZE; igeno++)</font></font></font>
|
||||||
|
<br><font face="Courier New,Courier"><font color="#CC33CC"><font size=+1>
|
||||||
|
{</font></font></font>
|
||||||
|
<br><font face="Courier New,Courier"><font color="#CC33CC"><font size=+1>
|
||||||
|
Indi v; // generate a random individual</font></font></font>
|
||||||
|
<br><font face="Courier New,Courier"><font color="#CC33CC"><font size=+1>
|
||||||
|
for (unsigned ivar=0; ivar<VEC_SIZE; ivar++)</font></font></font>
|
||||||
|
<br><font face="Courier New,Courier"><font color="#CC33CC"><font size=+1>
|
||||||
|
{</font></font></font>
|
||||||
|
<br><font face="Courier New,Courier"><font color="#CC33CC"><font size=+1>
|
||||||
|
double r = 2*rng.uniform() - 1; // new value, random in [-1,1)</font></font></font>
|
||||||
|
<br><font face="Courier New,Courier"><font color="#CC33CC"><font size=+1>
|
||||||
|
v.push_back(r); //</font></font></font>
|
||||||
|
<br><font face="Courier New,Courier"><font color="#CC33CC"><font size=+1>
|
||||||
|
}</font></font></font>
|
||||||
|
<br><font face="Courier New,Courier"><font color="#CC33CC"><font size=+1>
|
||||||
|
eval(v); // evaluate it</font></font></font>
|
||||||
|
<br><font face="Courier New,Courier"><font color="#CC33CC"><font size=+1>
|
||||||
|
pop.push_back(v); // and put it in the population</font></font></font>
|
||||||
|
<br><font face="Courier New,Courier"><font color="#CC33CC"><font size=+1>
|
||||||
|
}</font></font></font>
|
||||||
|
<p>This initialization of the population is straightforward
|
||||||
|
<br><font color="#CC33CC">rng.uniform()</font> generates a double <font face="Arial,Helvetica"><a href="doc/html/class_eorng.html">uniformly
|
||||||
|
in [0,1)</a>,</font>
|
||||||
|
<br><font color="#CC33CC">v.push_back</font> simply appends its argument
|
||||||
|
at the end of <a href="eoProgramming.html#STL">STL</a> vector <font face="Courier New,Courier"><font color="#CC33CC"><font size=+1>v</font></font></font>
|
||||||
|
<br><font color="#CC33CC">eval(v)</font>evaluates individal <font color="#CC33CC">v</font>
|
||||||
|
the <a href="eoProgramming.html#functors">functor way</a>, calling <font face="Courier New,Courier"><font color="#CC33CC"><font size=+1>eval.operator()(v)</font></font></font>
|
||||||
|
<p><font face="Courier New,Courier"><font size=+1>// sort pop before printing
|
||||||
|
it!</font></font>
|
||||||
|
<br><font face="Courier New,Courier"><font color="#66FFFF"><font size=+1>pop.sort();</font></font></font>
|
||||||
|
<p><font face="Courier New,Courier"><font size=+1>// Print (sorted) intial
|
||||||
|
population (raw printout)</font></font>
|
||||||
|
<br><font face="Courier New,Courier"><font color="#66FFFF"><font size=+1>cout
|
||||||
|
<< "Initial Population" << endl;</font></font></font>
|
||||||
|
<br><font face="Courier New,Courier"><font color="#66FFFF"><font size=+1>cout
|
||||||
|
<< pop;</font></font></font>
|
||||||
|
<p>If you looked at <font face="Arial,Helvetica"><a href="doc/html/class_eopop.html">eoPop</a></font>
|
||||||
|
inheritance diagram, you noticed that it derives from <font face="Arial,Helvetica"><a href="doc/html/class_eoprintable.html">eoPrintable</a>:</font>
|
||||||
|
hence you can stream them using the << operator. Of course, Indis
|
||||||
|
are <font face="Arial,Helvetica"><a href="doc/html/class_eo.html">EO objects</a>
|
||||||
|
</font>, which also are eoPrintable, and the << operator for eoPop
|
||||||
|
uses the << operator for Indi.
|
||||||
|
<p><font face="Courier New,Courier"><font size=+1>/////////////////////////////////////</font></font>
|
||||||
|
<br><a NAME="engine"></a><font face="Courier New,Courier"><font size=+1>//
|
||||||
|
selection and replacement</font></font>
|
||||||
|
<br><font face="Courier New,Courier"><font size=+1>////////////////////////////////////</font></font>
|
||||||
|
<br><font face="Courier New,Courier"><font size=+1>// The well-known roulette
|
||||||
|
selection</font></font>
|
||||||
|
<br><a NAME="select"></a><font face="Courier New,Courier"><font size=+1>//
|
||||||
|
The robust tournament selection</font></font>
|
||||||
|
<br><font face="Courier New,Courier"><font color="#009900"><font size=+1>eoDetTournament<Indi>
|
||||||
|
select(T_SIZE); // SIZE in [2,POP_SIZE]</font></font></font>
|
||||||
|
<p><a NAME="replace"></a><font face="Courier New,Courier"><font size=+1>//
|
||||||
|
eoSGA uses <font color="#009900">generational replacement</font> by default</font></font>
|
||||||
|
<br><font face="Courier New,Courier"><font size=+1>// so no replacement
|
||||||
|
procedure has to be given</font></font>
|
||||||
|
<p><font face="Courier New,Courier"><font size=+1>//////////////////////////////////////</font></font>
|
||||||
|
<br><font face="Courier New,Courier"><font size=+1>// termination condition</font></font>
|
||||||
|
<br><font face="Courier New,Courier"><font size=+1>/////////////////////////////////////</font></font>
|
||||||
|
<br><font face="Courier New,Courier"><font size=+1>// stop after MAX_GEN
|
||||||
|
generations</font></font>
|
||||||
|
<br><a NAME="stop"></a><font face="Courier New,Courier"><font color="#66FFFF"><font size=+1>eoGenContinue<Indi>
|
||||||
|
continuator(MAX_GEN);</font></font></font>
|
||||||
|
<p>This class is called <font face="Arial,Helvetica"><a href="doc/html/class_eogencontinue.html">eoGenContinue</a>
|
||||||
|
</font>because the main loop of all <font face="Arial,Helvetica"><a href="doc/html/class_eoalgo.html">eoAlgo</a>
|
||||||
|
</font>says ... while continuator(pop)
|
||||||
|
<p><font face="Courier New,Courier"><font size=+1>//////////////////////////////////////</font></font>
|
||||||
|
<br><a NAME="operators"></a><font face="Courier New,Courier"><font size=+1>//
|
||||||
|
The variation operators</font></font>
|
||||||
|
<br><font face="Courier New,Courier"><font size=+1>//////////////////////////////////////</font></font>
|
||||||
|
<p><a NAME="mutation"></a><font face="Courier New,Courier"><font size=+1>//
|
||||||
|
offspring(i) uniformly chosen in [parent(i)-epsilon, parent(i)+epsilon]</font></font>
|
||||||
|
<br><font face="Courier New,Courier"><font color="#CC33CC"><font size=+1>eoUniformMutation<Indi>
|
||||||
|
mutation(EPSILON);</font></font></font>
|
||||||
|
<br><a NAME="crossover"></a><font face="Courier New,Courier"><font size=+1>//
|
||||||
|
offspring(i) is a linear combination of parent(i)</font></font>
|
||||||
|
<br><font face="Courier New,Courier"><font color="#CC33CC"><font size=+1>eoArithmeticCrossover<Indi>
|
||||||
|
xover;</font></font></font>
|
||||||
|
<p>The <a href="eoOperators.html">variation operators</a> are respectively
|
||||||
|
an <font face="Arial,Helvetica"><a href="doc/html/class_eomonop.html">eoMonOp</a></font>
|
||||||
|
(unary operator) and an <font face="Arial,Helvetica"><a href="doc/html/class_eoquadraticop.html">eoQuadOp</a></font>
|
||||||
|
(binary operator that modifies both its arguments).
|
||||||
|
<p><font face="Courier New,Courier"><font size=+1>/////////////////////////////////////////</font></font>
|
||||||
|
<br><font face="Courier New,Courier"><font size=+1>// the algorithm</font></font>
|
||||||
|
<br><font face="Courier New,Courier"><font size=+1>////////////////////////////////////////</font></font>
|
||||||
|
<br><font face="Courier New,Courier"><font size=+1>// standard Generational
|
||||||
|
GA requires</font></font>
|
||||||
|
<br><font face="Courier New,Courier"><font size=+1>// selection, evaluation,
|
||||||
|
crossover and mutation, stopping criterion</font></font>
|
||||||
|
<br>
|
||||||
|
<p><a NAME="generation"></a><font face="Courier New,Courier"><font color="#FF6666"><font size=+1>eoSGA<Indi>
|
||||||
|
gga(select, xover, CROSS_RATE, mutation, MUT_RATE,</font></font></font>
|
||||||
|
<br><font face="Courier New,Courier"><font color="#FF6666"><font size=+1>eval,
|
||||||
|
continuator);</font></font></font>
|
||||||
|
<p><font face="Courier New,Courier"><font size=+1>// Apply algo to pop
|
||||||
|
- that's it!</font></font>
|
||||||
|
<br><font face="Courier New,Courier"><font color="#FF6666"><font size=+1>gga(pop);</font></font></font>
|
||||||
|
<p>This simple algorithm of class eoSGA is a <a href="eoProgramming.html#functors">functor
|
||||||
|
object</a>, and running the algorithm amounts to call the <font color="#993300">operator()</font>
|
||||||
|
on the initial population!
|
||||||
|
<p><font face="Courier New,Courier"><font size=+1>// Print (sorted) intial
|
||||||
|
population (raw printout)</font></font>
|
||||||
|
<br><a NAME="output"></a><font face="Courier New,Courier"><font color="#66FFFF"><font size=+1>pop.sort();</font></font></font>
|
||||||
|
<br><font face="Courier New,Courier"><font color="#66FFFF"><font size=+1>cout
|
||||||
|
<< "FINAL Population\n" << pop << endl;</font></font></font>
|
||||||
|
<p>that's it - just print the final population and you're done!!!
|
||||||
|
<p><font face="Courier New,Courier"><font size=+1>}</font></font>
|
||||||
|
<p><font face="Courier New,Courier"><font color="#000000"><font size=+1>//
|
||||||
|
A main that catches the exceptions - do not modify!</font></font></font>
|
||||||
|
<br><font face="Courier New,Courier"><font color="#993300"><font size=+1>int
|
||||||
|
main(int argc, char **argv)</font></font></font>
|
||||||
|
<br><font face="Courier New,Courier"><font color="#993300"><font size=+1>{</font></font></font>
|
||||||
|
<br><font face="Courier New,Courier"><font color="#993300"><font size=+1>#ifdef
|
||||||
|
_MSC_VER</font></font></font>
|
||||||
|
<br><font face="Courier New,Courier"><font color="#993300"><font size=+1>//
|
||||||
|
rng.reseed(42);</font></font></font>
|
||||||
|
<br><font face="Courier New,Courier"><font color="#993300"><font size=+1>int
|
||||||
|
flag = _CrtSetDbgFlag(_CRTDBG_LEAK_CHECK_DF);</font></font></font>
|
||||||
|
<br><font face="Courier New,Courier"><font color="#993300"><font size=+1>flag
|
||||||
|
|= _CRTDBG_LEAK_CHECK_DF;</font></font></font>
|
||||||
|
<br><font face="Courier New,Courier"><font color="#993300"><font size=+1>_CrtSetDbgFlag(flag);</font></font></font>
|
||||||
|
<br><font face="Courier New,Courier"><font color="#993300"><font size=+1>//
|
||||||
|
_CrtSetBreakAlloc(100);</font></font></font>
|
||||||
|
<br><font face="Courier New,Courier"><font color="#993300"><font size=+1>#endif</font></font></font>
|
||||||
|
<p><font face="Courier New,Courier"><font color="#993300"><font size=+1>try</font></font></font>
|
||||||
|
<br><font face="Courier New,Courier"><font color="#993300"><font size=+1>{</font></font></font>
|
||||||
|
<br><font face="Courier New,Courier"><font color="#993300"><font size=+1>main_function(argc,
|
||||||
|
argv);</font></font></font>
|
||||||
|
<br><font face="Courier New,Courier"><font color="#993300"><font size=+1>}</font></font></font>
|
||||||
|
<br><font face="Courier New,Courier"><font color="#993300"><font size=+1>catch(exception&
|
||||||
|
e)</font></font></font>
|
||||||
|
<br><font face="Courier New,Courier"><font color="#993300"><font size=+1>{</font></font></font>
|
||||||
|
<br><font face="Courier New,Courier"><font color="#993300"><font size=+1>cout
|
||||||
|
<< "Exception: " << e.what() << '\n';</font></font></font>
|
||||||
|
<br><font face="Courier New,Courier"><font color="#993300"><font size=+1>}</font></font></font>
|
||||||
|
<p><font face="Courier New,Courier"><font color="#993300"><font size=+1>return
|
||||||
|
1;</font></font></font>
|
||||||
|
<br><font face="Courier New,Courier"><font color="#993300"><font size=+1>}</font></font></font>
|
||||||
|
<p>
|
||||||
|
<hr WIDTH="100%"><a href="eoLesson1.html">Back to Lesson 1</a> - <a href="eoTutorial.html">Tutorial
|
||||||
|
main page </a>- <a href="eoTopDown.html">Top-Down page</a> - <a href="eoBottomUp.html">Bottom-up
|
||||||
|
page</a> - <a href="eoProgramming.html">Programming hints</a> - <font face="Arial,Helvetica"><a href="doc/html/index.html">EO
|
||||||
|
documentation</a></font>
|
||||||
|
<hr>
|
||||||
|
<address>
|
||||||
|
<a href="mailto:marc@cmapx.polytechnique.fr">Marc Schoenauer</a></address>
|
||||||
|
|
||||||
|
<br><!-- Created: Wed Nov 1 07:18:21 CET 2000 --><!-- hhmts start -->Last
|
||||||
|
modified: Wed Nov 6 17:22:43 CET 2000<!-- hhmts end -->
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue