# FirstBitGA.cpp

    00001 //-----------------------------------------------------------------------------
    00002 // FirstBitGA.cpp
    00003 //-----------------------------------------------------------------------------
    00004 //*
    00005 // An instance of a VERY simple Bitstring Genetic Algorithm
    00006 //
    00007 //-----------------------------------------------------------------------------
    00008
    00009 #ifdef HAVE_CONFIG_H
    00010 #include <config.h>
    00011 #endif
    00012
    00013 #include <stdexcept>
    00014 #include <iostream>
    00015
    00016 #include <eo>
    00017 #include <ga.h>
    00018
    00019 // Use functions from namespace std
    00020 using namespace std;
    00021
    00022 // REPRESENTATION
    00023 //-----------------------------------------------------------------------------
    00024 // define your individuals
    00025 typedef eoBit<double> Indi;     // A bitstring with fitness double
    00026
    00027 // EVAL
    00028 //-----------------------------------------------------------------------------
    00029 // a simple fitness function that computes the number of ones of a bitstring
    00030 //  @param _indi A biststring individual
    00031
    00032 double binary_value(const Indi & _indi)
    00033 {
    00034   double sum = 0;
    00035   for (unsigned i = 0; i < _indi.size(); i++)
    00036     sum += _indi[i];
    00037   return sum;
    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 T_SIZE = 3;     // size for tournament selection
    00047   const unsigned int VEC_SIZE = 16;   // Number of bits in genotypes
    00048   const unsigned int POP_SIZE = 100;  // Size of population
    00049   const unsigned int MAX_GEN = 400;  // Maximum number of generation before STOP
    00050   const float CROSS_RATE = 0.8;      // Crossover rate
    00051   const double P_MUT_PER_BIT = 0.01; // probability of bit-flip mutation
    00052   const float MUT_RATE = 1.0;        // 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(  binary_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           bool r = rng.flip(); // new value, random in {0,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   // shuffle  - this is a test
    00096   pop.shuffle();
    00097   // Print (sorted) intial population (raw printout)
    00098   cout << "Shuffled Population" << endl;
    00099   cout << pop;
    00100
    00101 // ENGINE
    00103   // selection and replacement
    00105 // SELECT
    00106   // The robust tournament selection
    00107   eoDetTournamentSelect<Indi> select(T_SIZE);  // T_SIZE in [2,POP_SIZE]
    00108
    00109 // REPLACE
    00110   // The simple GA evolution engine uses generational replacement
    00111   // so no replacement procedure is needed
    00112
    00113 // OPERATORS
    00115   // The variation operators
    00117 // CROSSOVER
    00118   // 1-point crossover for bitstring
    00119   eo1PtBitXover<Indi> xover;
    00120 // MUTATION
    00121   // standard bit-flip mutation for bitstring
    00122   eoBitMutation<Indi>  mutation(P_MUT_PER_BIT);
    00123
    00124 // STOP
    00125 // CHECKPOINT
    00127   // termination condition
    00129   // stop after MAX_GEN generations
    00130   eoGenContinue<Indi> continuator(MAX_GEN);
    00131
    00132 // GENERATION
    00134   // the algorithm
    00136   // standard Generational GA requires as parameters
    00137   // selection, evaluation, crossover and mutation, stopping criterion
    00138
    00139
    00140   eoSGA<Indi> gga(select, xover, CROSS_RATE, mutation, MUT_RATE,
    00141                   eval, continuator);
    00142
    00143   // Apply algo to pop - that's it!
    00144   gga(pop);
    00145
    00146 // OUTPUT
    00147   // Print (sorted) intial population
    00148   pop.sort();
    00149   cout << "FINAL Population\n" << pop << endl;
    00150 // GENERAL
    00151 }
    00152  // A main that catches the exceptions
    00153
    00154 int main(int argc, char **argv)
    00155 {
    00156
    00157     try
    00158     {
    00159         main_function(argc, argv);
    00160     }
    00161     catch(exception& e)
    00162     {
    00163         cout << "Exception: " << e.what() << '\n';
    00164     }
    00165
    00166     return 1;
    00167 }