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 }