00001 //----------------------------------------------------------------------------- 00002 // FirstRealEA.cpp 00003 //----------------------------------------------------------------------------- 00004 //* 00005 // Still an instance of a VERY simple Real-coded 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 <es.h> 00020 00021 // REPRESENTATION 00022 //----------------------------------------------------------------------------- 00023 // define your individuals 00024 typedef eoReal<double> Indi; 00025 00026 // Use functions from namespace std 00027 using namespace std; 00028 00029 // EVALFUNC 00030 //----------------------------------------------------------------------------- 00031 // a simple fitness function that computes the euclidian norm of a real vector 00032 // Now in a separate file, and declared as binary_value(const vector<bool> &) 00033 00034 #include "real_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 object variables 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 float P_CROSS = 0.8; // Crossover probability 00052 const float P_MUT = 0.5; // mutation probability 00053 00054 const double EPSILON = 0.01; // range for real uniform mutation 00055 double SIGMA = 0.3; // std dev. for normal mutation 00056 // some parameters for chosing among different operators 00057 const double hypercubeRate = 0.5; // relative weight for hypercube Xover 00058 const double segmentRate = 0.5; // relative weight for segment Xover 00059 const double uniformMutRate = 0.5; // relative weight for uniform mutation 00060 const double detMutRate = 0.5; // relative weight for det-uniform mutation 00061 const double normalMutRate = 0.5; // relative weight for normal mutation 00062 00063 // GENERAL 00065 // Random seed 00067 //reproducible random seed: if you don't change SEED above, 00068 // you'll aways get the same result, NOT a random run 00069 rng.reseed(SEED); 00070 00071 // EVAL 00073 // Fitness function 00075 // Evaluation: from a plain C++ fn to an EvalFunc Object 00076 // you need to give the full description of the function 00077 eoEvalFuncPtr<Indi, double, const vector<double>& > eval( real_value ); 00078 00079 // INIT 00081 // Initilisation of population 00083 // based on a uniform generator 00084 eoUniformGenerator<double> uGen(-1.0, 1.0); 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); 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 // uniform chooce on segment made by the parents 00120 eoSegmentCrossover<Indi> xoverS; 00121 // uniform choice in hypercube built by the parents 00122 eoHypercubeCrossover<Indi> xoverA; 00123 // Combine them with relative weights 00124 eoPropCombinedQuadOp<Indi> xover(xoverS, segmentRate); 00125 xover.add(xoverA, hypercubeRate, true); 00126 00127 // MUTATION 00128 // offspring(i) uniformly chosen in [parent(i)-epsilon, parent(i)+epsilon] 00129 eoUniformMutation<Indi> mutationU(EPSILON); 00130 // k (=1) coordinates of parents are uniformly modified 00131 eoDetUniformMutation<Indi> mutationD(EPSILON); 00132 // all coordinates of parents are normally modified (stDev SIGMA) 00133 eoNormalMutation<Indi> mutationN(SIGMA); 00134 // Combine them with relative weights 00135 eoPropCombinedMonOp<Indi> mutation(mutationU, uniformMutRate); 00136 mutation.add(mutationD, detMutRate); 00137 mutation.add(mutationN, normalMutRate, true); 00138 00139 // STOP 00140 // CHECKPOINT 00142 // termination conditions: use more than one 00144 // stop after MAX_GEN generations 00145 eoGenContinue<Indi> genCont(MAX_GEN); 00146 // do MIN_GEN gen., then stop after STEADY_GEN gen. without improvement 00147 eoSteadyFitContinue<Indi> steadyCont(MIN_GEN, STEADY_GEN); 00148 // stop when fitness reaches a target (here VEC_SIZE) 00149 eoFitContinue<Indi> fitCont(0); 00150 // do stop when one of the above says so 00151 eoCombinedContinue<Indi> continuator(genCont); 00152 continuator.add(steadyCont); 00153 continuator.add(fitCont); 00154 00155 // The operators are encapsulated into an eoTRansform object 00156 eoSGATransform<Indi> transform(xover, P_CROSS, mutation, P_MUT); 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 try 00183 { 00184 main_function(argc, argv); 00185 } 00186 catch(exception& e) 00187 { 00188 cout << "Exception: " << e.what() << '\n'; 00189 } 00190 00191 return 1; 00192 }