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 }