# exercise2.3.cpp

    00001 //-----------------------------------------------------------------------------
    00002 // FirstBitEA.cpp
    00003 //-----------------------------------------------------------------------------
    00004 //*
    00005 // Still an instance of a VERY simple Bitstring Genetic Algorithm
    00006 // (see FirstBitGA.cpp) but now with  Breeder - and Combined Ops
    00007 //
    00008 //-----------------------------------------------------------------------------
    00009 #ifdef HAVE_CONFIG_H
    00010 #include <config.h>
    00011 #endif
    00012
    00013 // standard includes
    00014 #include <stdexcept>  // runtime_error
    00015 #include <iostream>   // cout
    00016
    00017 // the general include for eo
    00018 #include <eo>
    00019
    00020 // REPRESENTATION
    00021 //-----------------------------------------------------------------------------
    00022 // Include the corresponding file
    00023 #include <ga.h>          // bitstring representation & operators
    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 // Now in a separate file, and declared as binary_value(const vector<bool> &)
    00031
    00032 #include "binary_value.h"
    00033
    00034 // GENERAL
    00035 //-----------------------------------------------------------------------------
    00036
    00037 using namespace std;
    00038
    00039 void main_function(int argc, char **argv)
    00040 {
    00041 // PARAMETRES
    00042   const unsigned int SEED = 42; // seed for random number generator
    00043   const unsigned int T_SIZE = 3; // size for tournament selection
    00044   const unsigned int VEC_SIZE = 20; // Number of bits in genotypes
    00045   const unsigned int POP_SIZE = 20; // Size of population
    00046
    00047   const unsigned int MAX_GEN = 500; // Maximum number of generation before STOP
    00048   const unsigned int MIN_GEN = 10;  // Minimum number of generation before ...
    00049   const unsigned int STEADY_GEN = 50; // stop after STEADY_GEN gen. without improvelent
    00050
    00051   const double P_CROSS = 0.8;   // Crossover probability
    00052   const double P_MUT = 1.0;     // mutation probability
    00053
    00054   const double P_MUT_PER_BIT = 0.01;    // internal probability for bit-flip mutation
    00055   // some parameters for chosing among different operators
    00056   const double onePointRate = 0.5;     // rate for 1-pt Xover
    00057   const double twoPointsRate = 0.5;     // rate for 2-pt Xover
    00058   const double URate = 0.5;            // rate for Uniform Xover
    00059   const double bitFlipRate = 0.5;      // rate for bit-flip mutation
    00060   const double oneBitRate = 0.5;       // rate for one-bit mutation
    00061
    00062 // GENERAL
    00064   //  Random seed
    00066   //reproducible random seed: if you don't change SEED above,
    00067   // you'll aways get the same result, NOT a random run
    00068   rng.reseed(SEED);
    00069
    00070 // EVAL
    00072   // Fitness function
    00074   // Evaluation: from a plain C++ fn to an EvalFunc Object
    00075   // you need to give the full description of the function
    00076   eoEvalFuncPtr<Indi, double, const vector<bool>& > eval(  binary_value );
    00077
    00078 // INIT
    00080   // Initilisation of population
    00082
    00083   // based on boolean_generator class (see utils/rnd_generator.h)
    00084   eoUniformGenerator<bool> uGen;
    00085   eoInitFixedLength<Indi> random(VEC_SIZE, uGen);
    00086   // Initialization of the population
    00087   eoPop<Indi> pop(POP_SIZE, random);
    00088
    00089   // and evaluate it in one loop
    00090   apply<Indi>(eval, pop);       // STL syntax
    00091
    00092 // OUTPUT
    00093   // sort pop before printing it!
    00094   pop.sort();
    00095   // Print (sorted) intial population (raw printout)
    00096   cout << "Initial Population" << endl;
    00097   cout << pop;
    00098
    00099 // ENGINE
    00101   // selection and replacement
    00103 // SELECT
    00104   // The robust tournament selection
    00105   eoDetTournamentSelect<Indi> selectOne(T_SIZE);       // T_SIZE in [2,POP_SIZE]
    00106   // solution solution solution solution solution solution solution
    00107   // modify the nb offspring / rate in the constructor. 2 ways:
    00108   // second arg treated as integer
    00109   eoSelectMany<Indi> select(selectOne,2, eo_is_an_integer);
    00110   // second arg treated as a rate (default behavior)
    00111   //  eoSelectMany<Indi> select(selectOne,0.1);
    00112
    00113 // REPLACE
    00114   // solution solution solution solution solution solution solution
    00115   // eoCommaReplacement keeps the best among offspring
    00116   // eoPlusReplacement keeps the best among parents + offspring
    00117   //  eoCommaReplacement<Indi> replace;
    00118   eoPlusReplacement<Indi> replace;
    00119
    00120 // OPERATORS
    00122   // The variation operators
    00124 // CROSSOVER
    00125   // 1-point crossover for bitstring
    00126   eo1PtBitXover<Indi> xover1;
    00127   // uniform crossover for bitstring
    00128   eoUBitXover<Indi> xoverU;
    00129   // 2-pots xover
    00130   eoNPtsBitXover<Indi> xover2(2);
    00131   // Combine them with relative rates
    00132   eoPropCombinedQuadOp<Indi> xover(xover1, onePointRate);
    00133   xover.add(xoverU, URate);
    00134   xover.add(xover2, twoPointsRate, true);
    00135
    00136 // MUTATION
    00137   // standard bit-flip mutation for bitstring
    00138   eoBitMutation<Indi>  mutationBitFlip(P_MUT_PER_BIT);
    00139   // mutate exactly 1 bit per individual
    00140   eoDetBitFlip<Indi> mutationOneBit;
    00141   // Combine them with relative rates
    00142   eoPropCombinedMonOp<Indi> mutation(mutationBitFlip, bitFlipRate);
    00143   mutation.add(mutationOneBit, oneBitRate, true);
    00144
    00145   // The operators are  encapsulated into an eoTRansform object
    00146   eoSGATransform<Indi> transform(xover, P_CROSS, mutation, P_MUT);
    00147
    00148 // STOP
    00149 // CHECKPOINT
    00151   // termination conditions: use more than one
    00153   // stop after MAX_GEN generations
    00154   eoGenContinue<Indi> genCont(MAX_GEN);
    00155   // do MIN_GEN gen., then stop after STEADY_GEN gen. without improvement
    00156   eoSteadyFitContinue<Indi> steadyCont(MIN_GEN, STEADY_GEN);
    00157   // stop when fitness reaches a target (here VEC_SIZE)
    00158   eoFitContinue<Indi> fitCont(VEC_SIZE);
    00159   // do stop when one of the above says so
    00160   eoCombinedContinue<Indi> continuator(genCont);
    00161   continuator.add(steadyCont);
    00162   continuator.add(fitCont);
    00163
    00164 // GENERATION
    00166   // the algorithm
    00168
    00169   // Easy EA requires
    00170   // selection, transformation, eval, replacement, and stopping criterion
    00171   eoEasyEA<Indi> gga(continuator, eval, select, transform, replace);
    00172
    00173   // Apply algo to pop - that's it!
    00174   gga(pop);
    00175
    00176 // OUTPUT
    00177   // Print (sorted) intial population
    00178   pop.sort();
    00179   cout << "FINAL Population\n" << pop << endl;
    00180 // GENERAL
    00181 }
    00182
    00183 // A main that catches the exceptions
    00184
    00185 int main(int argc, char **argv)
    00186 {
    00187     try
    00188     {
    00189         main_function(argc, argv);
    00190     }
    00191     catch(exception& e)
    00192     {
    00193         cout << "Exception: " << e.what() << '\n';
    00194     }
    00195
    00196     return 1;
    00197 }