# FirstRealGA.cpp

    00001 //-----------------------------------------------------------------------------
    00002 // FirstRealGA.cpp
    00003 //-----------------------------------------------------------------------------
    00004 //*
    00005 // An instance of a VERY simple Real-coded Genetic Algorithm
    00006 //
    00007 //-----------------------------------------------------------------------------
    00008 #ifdef HAVE_CONFIG_H
    00009 #include <config.h>
    00010 #endif
    00011
    00012 #include <stdexcept>
    00013 #include <iostream>
    00014 #include <sstream>
    00015
    00016 #include <eo>
    00017 #include <es.h>
    00018
    00019 // Use functions from namespace std
    00020 using namespace std;
    00021
    00022 // REPRESENTATION
    00023 //-----------------------------------------------------------------------------
    00024 // define your individuals
    00025  typedef eoReal<double> Indi;
    00026
    00027 // EVAL
    00028 //-----------------------------------------------------------------------------
    00029 // a simple fitness function that computes the euclidian norm of a real vector
    00030 //    @param _indi A real-valued individual
    00031
    00032 double real_value(const Indi & _indi)
    00033 {
    00034   double sum = 0;
    00035   for (unsigned i = 0; i < _indi.size(); i++)
    00036       sum += _indi[i]*_indi[i];
    00037   return (-sum);            // maximizing only
    00038 }
    00039 // GENERAL
    00040 //-----------------------------------------------------------------------------
    00041 void main_function(int argc, char **argv)
    00042 {
    00043 // PARAMETRES
    00044   // all parameters are hard-coded!
    00045   const unsigned int SEED = 42; // seed for random number generator
    00046   const unsigned int VEC_SIZE = 8; // Number of object variables in genotypes
    00047   const unsigned int POP_SIZE = 20; // Size of population
    00048   const unsigned int T_SIZE = 3; // size for tournament selection
    00049   const unsigned int MAX_GEN = 500; // Maximum number of generation before STOP
    00050   const float CROSS_RATE = 0.8; // Crossover rate
    00051   const double EPSILON = 0.01;  // range for real uniform mutation
    00052   const float MUT_RATE = 0.5;   // mutation rate
    00053
    00054 // GENERAL
    00056   //  Random seed
    00058   //reproducible random seed: if you don't change SEED above,
    00059   // you'll aways get the same result, NOT a random run
    00060   rng.reseed(SEED);
    00061
    00062 // EVAL
    00064   // Fitness function
    00066   // Evaluation: from a plain C++ fn to an EvalFunc Object
    00067   eoEvalFuncPtr<Indi> eval(  real_value );
    00068
    00069 // INIT
    00071   // Initilisation of population
    00073
    00074   // declare the population
    00075   eoPop<Indi> pop;
    00076   // fill it!
    00077   for (unsigned int igeno=0; igeno<POP_SIZE; igeno++)
    00078     {
    00079       Indi v;          // void individual, to be filled
    00080       for (unsigned ivar=0; ivar<VEC_SIZE; ivar++)
    00081         {
    00082           double r = 2*rng.uniform() - 1; // new value, random in [-1,1)
    00083           v.push_back(r);       // append that random value to v
    00084         }
    00085       eval(v);                  // evaluate it
    00086       pop.push_back(v);         // and put it in the population
    00087     }
    00088
    00089 // OUTPUT
    00090   // sort pop before printing it!
    00091   pop.sort();
    00092   // Print (sorted) intial population (raw printout)
    00093   cout << "Initial Population" << endl;
    00094   cout << pop;
    00095
    00096 // ENGINE
    00098   // selection and replacement
    00100 // SELECT
    00101   // The robust tournament selection
    00102   eoDetTournamentSelect<Indi> select(T_SIZE);       // T_SIZE in [2,POP_SIZE]
    00103
    00104 // REPLACE
    00105   // eoSGA uses generational replacement by default
    00106   // so no replacement procedure has to be given
    00107
    00108 // OPERATORS
    00110   // The variation operators
    00112 // CROSSOVER
    00113   // offspring(i) is a linear combination of parent(i)
    00114   eoSegmentCrossover<Indi> xover;
    00115 // MUTATION
    00116   // offspring(i) uniformly chosen in [parent(i)-epsilon, parent(i)+epsilon]
    00117   eoUniformMutation<Indi>  mutation(EPSILON);
    00118
    00119 // STOP
    00120 // CHECKPOINT
    00122   // termination condition
    00124   // stop after MAX_GEN generations
    00125   eoGenContinue<Indi> continuator(MAX_GEN);
    00126
    00127 // GENERATION
    00129   // the algorithm
    00131   // standard Generational GA requires
    00132   // selection, evaluation, crossover and mutation, stopping criterion
    00133
    00134
    00135   eoSGA<Indi> gga(select, xover, CROSS_RATE, mutation, MUT_RATE,
    00136                    eval, continuator);
    00137
    00138   // Apply algo to pop - that's it!
    00139   gga(pop);
    00140
    00141 // OUTPUT
    00142   // Print (sorted) intial population
    00143   pop.sort();
    00144   cout << "FINAL Population\n" << pop << endl;
    00145 // GENERAL
    00146 }
    00147
    00148 // A main that catches the exceptions
    00149
    00150 int main(int argc, char **argv)
    00151 {
    00152     try
    00153     {
    00154         main_function(argc, argv);
    00155     }
    00156     catch(exception& e)
    00157     {
    00158         cout << "Exception: " << e.what() << '\n';
    00159     }
    00160
    00161     return 1;
    00162 }