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 #include <ga.h> 00020 00021 // Use functions from namespace std 00022 using namespace std; 00023 00024 // REPRESENTATION 00025 //----------------------------------------------------------------------------- 00026 // define your individuals 00027 typedef eoBit<double> Indi; // A bitstring with fitness double 00028 00029 // EVALFUNC 00030 //----------------------------------------------------------------------------- 00031 // a simple fitness function that computes the number of ones of a bitstring 00032 // Now in a separate file, and declared as binary_value(const vector<bool> &) 00033 00034 #include "binary_value.h" 00035 00036 // GENERAL 00037 //----------------------------------------------------------------------------- 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 = 8; // 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/eoRndGenerators.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 // is now encapsulated in a eoSelectPerc (entage) 00107 eoSelectPerc<Indi> select(selectOne);// by default rate==1 00108 00109 // REPLACE 00110 // And we now have the full slection/replacement - though with 00111 // no replacement (== generational replacement) at the moment :-) 00112 eoGenerationalReplacement<Indi> replace; 00113 00114 // OPERATORS 00116 // The variation operators 00118 // CROSSOVER 00119 // 1-point crossover for bitstring 00120 eo1PtBitXover<Indi> xover1; 00121 // uniform crossover for bitstring 00122 eoUBitXover<Indi> xoverU; 00123 // 2-pots xover 00124 eoNPtsBitXover<Indi> xover2(2); 00125 // Combine them with relative rates 00126 eoPropCombinedQuadOp<Indi> xover(xover1, onePointRate); 00127 xover.add(xoverU, URate); 00128 xover.add(xover2, twoPointsRate, true); 00129 00130 // MUTATION 00131 // standard bit-flip mutation for bitstring 00132 eoBitMutation<Indi> mutationBitFlip(P_MUT_PER_BIT); 00133 // mutate exactly 1 bit per individual 00134 eoDetBitFlip<Indi> mutationOneBit; 00135 // Combine them with relative rates 00136 eoPropCombinedMonOp<Indi> mutation(mutationBitFlip, bitFlipRate); 00137 mutation.add(mutationOneBit, oneBitRate, true); 00138 00139 // The operators are encapsulated into an eoTRansform object 00140 eoSGATransform<Indi> transform(xover, P_CROSS, mutation, P_MUT); 00141 00142 // STOP 00143 // CHECKPOINT 00145 // termination conditions: use more than one 00147 // stop after MAX_GEN generations 00148 eoGenContinue<Indi> genCont(MAX_GEN); 00149 // do MIN_GEN gen., then stop after STEADY_GEN gen. without improvement 00150 eoSteadyFitContinue<Indi> steadyCont(MIN_GEN, STEADY_GEN); 00151 // stop when fitness reaches a target (here VEC_SIZE) 00152 eoFitContinue<Indi> fitCont(VEC_SIZE); 00153 // do stop when one of the above says so 00154 eoCombinedContinue<Indi> continuator(genCont); 00155 continuator.add(steadyCont); 00156 continuator.add(fitCont); 00157 00158 // GENERATION 00160 // the algorithm 00162 00163 // Easy EA requires 00164 // selection, transformation, eval, replacement, and stopping criterion 00165 eoEasyEA<Indi> gga(continuator, eval, select, transform, replace); 00166 00167 // Apply algo to pop - that's it! 00168 cout << "\n Here we go\n\n"; 00169 gga(pop); 00170 00171 // OUTPUT 00172 // Print (sorted) intial population 00173 pop.sort(); 00174 cout << "FINAL Population\n" << pop << endl; 00175 // GENERAL 00176 } 00177 00178 // A main that catches the exceptions 00179 00180 int main(int argc, char **argv) 00181 { 00182 00183 try 00184 { 00185 main_function(argc, argv); 00186 } 00187 catch(exception& e) 00188 { 00189 cout << "Exception: " << e.what() << '\n'; 00190 } 00191 00192 return 1; 00193 }