00001 /*************************************************************************** 00002 * Copyright (C) 2005-2009 by Robot Group Leipzig * 00003 * martius@informatik.uni-leipzig.de * 00004 * fhesse@informatik.uni-leipzig.de * 00005 * der@informatik.uni-leipzig.de * 00006 * guettler@informatik.uni-leipzig.de * 00007 * jhoffmann@informatik.uni-leipzig.de * 00008 * joergweide84@aol.com (robot12) * 00009 * * 00010 * This program is free software; you can redistribute it and/or modify * 00011 * it under the terms of the GNU General Public License as published by * 00012 * the Free Software Foundation; either version 2 of the License, or * 00013 * (at your option) any later version. * 00014 * * 00015 * This program is distributed in the hope that it will be useful, * 00016 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 00017 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 00018 * GNU General Public License for more details. * 00019 * * 00020 * You should have received a copy of the GNU General Public License * 00021 * along with this program; if not, write to the * 00022 * Free Software Foundation, Inc., * 00023 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * 00024 *************************************************************************** 00025 * * 00026 * This class is the engine of the gen. alg. It control all elements * 00027 * inside, prepare the next steps and hold the alg. on running. * 00028 * * 00029 * $Log: SingletonGenEngine.h,v $ 00030 * Revision 1.12 2009/10/23 10:47:45 robot12 00031 * bugfix in store and restore 00032 * 00033 * Revision 1.11 2009/10/21 14:08:06 robot12 00034 * add restore and store functions to the ga package 00035 * 00036 * Revision 1.10 2009/08/11 12:57:38 robot12 00037 * change the genetic algorithm (first crossover, second select) 00038 * 00039 * Revision 1.9 2009/07/28 13:19:27 robot12 00040 * add member variable m_cleanStrategies 00041 * 00042 * Revision 1.8 2009/07/21 08:39:01 robot12 00043 * rename "crosover" to crossover 00044 * 00045 * Revision 1.7 2009/07/15 12:53:36 robot12 00046 * some bugfix's and new functions 00047 * 00048 * Revision 1.6 2009/07/06 15:06:35 robot12 00049 * bugfix 00050 * 00051 * Revision 1.5 2009/07/02 15:25:41 robot12 00052 * update 00053 * 00054 * Revision 1.4 2009/06/30 10:30:04 robot12 00055 * GenEngine finish and some comments added 00056 * 00057 * Revision 1.3 2009/05/12 13:29:26 robot12 00058 * some new function 00059 * -> toString methodes 00060 * 00061 * Revision 1.2 2009/05/11 14:08:52 robot12 00062 * patch some bugfix.... 00063 * 00064 * Revision 1.1 2009/05/04 15:27:55 robot12 00065 * rename of some files and moving files to other positions 00066 * - SingletonGenAlgAPI has one error!!! --> is not ready now 00067 * 00068 * Revision 1.6 2009/04/30 14:32:34 robot12 00069 * some implements... Part5 00070 * 00071 * Revision 1.5 2009/04/30 11:35:53 robot12 00072 * some changes: 00073 * - insert a SelectStrategie 00074 * - insert a MutationStrategie 00075 * - reorganisation of the design 00076 * 00077 * Revision 1.4 2009/04/29 14:32:28 robot12 00078 * some implements... Part4 00079 * 00080 * Revision 1.3 2009/04/29 11:36:41 robot12 00081 * some implements... Part3 00082 * 00083 * Revision 1.2 2009/04/28 13:23:55 robot12 00084 * some implements... Part2 00085 * 00086 * Revision 1.1 2009/04/27 10:59:33 robot12 00087 * some implements 00088 * 00089 * 00090 ***************************************************************************/ 00091 00092 #ifndef SINGLETONGENENGINE_H_ 00093 #define SINGLETONGENENGINE_H_ 00094 00095 //includes 00096 #include <vector> 00097 #include <map> 00098 #include <string> 00099 #include <selforg/randomgenerator.h> 00100 #include <selforg/inspectableproxy.h> 00101 //#include <selforg/storeable.h> not possible because the restore function need more information!!! 00102 00103 //forward declaration 00104 class Gen; 00105 class GenPrototype; 00106 class GenContext; 00107 class Individual; 00108 class Generation; 00109 class IMutationStrategy; 00110 class IMutationFactorStrategy; 00111 class ISelectStrategy; 00112 class IGenerationSizeStrategy; 00113 class IRandomStrategy; 00114 class IValue; 00115 class IFitnessStrategy; 00116 struct RESTORE_GA_GENERATION; 00117 struct RESTORE_GA_INDIVIDUAL; 00118 struct RESTORE_GA_GENE; 00119 template<class Typ>struct RESTORE_GA_TEMPLATE; 00120 00121 //forward declaration for LPZROBOTS 00122 class PlotOptionEngine; 00123 00124 /** 00125 * This is the engine of the gen. alg. 00126 * 00127 * Over this is the class as singleton concepted. Only one engine for a run. 00128 */ 00129 class SingletonGenEngine{ 00130 public: 00131 /** 00132 * this function returns a set of all registered GenPrototypes. 00133 * @return (vector<GenPrototype*>&) the set 00134 */ 00135 inline const std::vector<GenPrototype*>& getSetOfGenPrototyps(void) const {return m_prototype;} 00136 00137 /** 00138 * this function return the number of Generation inside. 00139 * @return (int) the number of Generation in the storage 00140 */ 00141 inline int getNumGeneration(void) const {return m_generation.size();} 00142 00143 /** 00144 * this function returns one Generation 00145 * @param x (int) the index of the Generation which is searched 00146 * @return (Generation*) the searched Generation. If x not a right index, than the result is zero. 00147 */ 00148 inline Generation* getGeneration(int x) {if(x<getNumGeneration())return m_generation[x];return NULL;} 00149 00150 /** 00151 * returns the actual generation number, on which the alg. work 00152 * @return (int) the actual generation number 00153 */ 00154 inline int getActualGenerationNumber(void) const {return m_actualGeneration;} 00155 00156 /** 00157 * returns the actual Generation. 00158 * @return (Generation*) the actual generation 00159 */ 00160 inline Generation* getActualGeneration(void) {return m_generation[m_actualGeneration];} 00161 00162 /** 00163 * returns the number of individual inside the alg. 00164 * @return (int) number of individual 00165 */ 00166 inline int getNumIndividual(void) const {return m_individual.size();} 00167 00168 /** 00169 * returns one individual 00170 * @param x (int) index of the individual which is searched. 00171 * @return (Individual*) the searched individual 00172 */ 00173 inline Individual* getIndividual(int x) const {if(x<getNumIndividual())return m_individual[x];return NULL;} 00174 00175 /** 00176 * registered a GenPrototype in the engine. 00177 * @param prototype (GenPrototype*) the prototype which should be registered. 00178 */ 00179 inline void addGenPrototype(GenPrototype* prototype) {m_prototype.push_back(prototype);} 00180 00181 /** 00182 * registered a Gen in the engine. Normal only used by the alg. self. 00183 * @param gen (Gen*) the Gen which should be registered. 00184 */ 00185 inline void addGen(Gen* gen) {m_gen.push_back(gen);} 00186 00187 /** 00188 * returns one gene 00189 * @param x (int) index of the gene which is searched 00190 * @return (Gen*) the searched gene 00191 */ 00192 inline Gen* getGen(int x)const {if((unsigned int)x<m_gen.size())return m_gen[x];return NULL;} 00193 00194 /** 00195 * registered a individual in the engine. Normal only used by the alg. self. 00196 * @param individual (Individual*) the individual 00197 */ 00198 inline void addIndividual(Individual* individual) {m_individual.push_back(individual);} 00199 00200 /** 00201 * add a Generation to the alg. Normal only used by the alg. self. 00202 * @param generation (Generation*) the generation 00203 */ 00204 inline void addGeneration(Generation* generation) {m_generation.push_back(generation);} 00205 00206 /** 00207 * prepare the alg. and create his fisrt generation. 00208 * @param startSize (int) Number of individual with which the alg. will be start. 00209 * @param numChildren (int) Number of individual which will be created by crossover. 00210 * @param random (RandGen*) A random generator 00211 * @param withUpdate (bool) if true, than makes this function on the end a update. 00212 */ 00213 void generateFirstGeneration(int startSize, int numChildren, RandGen* random, bool withUpdate = true); 00214 00215 /** 00216 * prepare the next generation. Mean create the GenContext for every GenPrototype. 00217 * @param size (int) size of the next generation 00218 * @param numChildren (int) Number of individual which will be created by crossover 00219 */ 00220 void prepareNextGeneration(int size, int numChildren); 00221 00222 /** 00223 * prepare the first generation with "generateFirstGeneration" and init the measures. 00224 * @param startSize (int) Number of individual with which the alg. will be start. 00225 * @param numChildren (int) Number of individual which will be created by crossover 00226 * @param proxyGeneration (InspectableProxy*&) the generation which is controlled by measures 00227 * @param proxyGene (InspectableProxy*&) the proxy for control measure 00228 * @param random (RandGen*) A random generator 00229 * @param plotEngine (PlotOptionEngine*) logging the data for later control 00230 * @param plotEngineGenContext (PlotOptionEngine*) logging the data of the GenContext for later control 00231 * @param withUpdate (bool) is needed for the function "generateFirstGeneration" 00232 */ 00233 void prepare(int startSize, int numChildren, InspectableProxy*& proxyGeneration, InspectableProxy*& proxyGene, RandGen* random, PlotOptionEngine* plotEngine = 0, PlotOptionEngine* plotEngineGenContext = 0, bool withUpdate = true); 00234 00235 /** 00236 * return the size of the next generation. 00237 * @return (int) the size 00238 */ 00239 int getNextGenerationSize(); 00240 00241 /** 00242 * makes a step in the measure 00243 * @param time (double) the time stamp in the measure 00244 * @param proxyGeneration (InspectableProxy*&) the generation which is controlled by measures 00245 * @param proxyGene (InspectableProxy*&) the proxy for control measure 00246 */ 00247 void measureStep(double time,InspectableProxy*& proxyGeneration, InspectableProxy*& proxyGene, PlotOptionEngine* plotEngine = 0, PlotOptionEngine* plotEngineGenContext = 0); 00248 00249 /** 00250 * this function is for a automatically run of the gen. alg. 00251 * @param startSize (int) Number of individual with which the alg. will be start. 00252 * @param numChildren (int) Number of individual which will be created by crossover. 00253 * @param numGeneration (int) Number of generation after this the alg. will end. 00254 * @param random (RandGen*) a random generator 00255 * @param plotEngine (PlotOptionEngine*) logging the data for later control 00256 * @param plotEngineGenContext (PlotOptionEngine*) logging the data of the GenContext for later control 00257 */ 00258 void runGenAlg(int startSize, int numChildren, int numGeneration, RandGen* random, PlotOptionEngine* plotEngine = 0, PlotOptionEngine* plotEngineGenContext = 0); 00259 00260 /** 00261 * make the select of the actual generation and transfer it to the next generation 00262 * @param createNextGeneration (bool) normal=true. should be the next generation prepare 00263 */ 00264 void select(bool createNextGeneration=true); 00265 00266 /** 00267 * in the actual generation it will generate the children of the living individual 00268 * @param random (RanGen*) random generator 00269 */ 00270 void crossover(RandGen* random); 00271 00272 /** 00273 * this function makes a update on the statistical data of the gen. alg. 00274 * @param factor (double) the factor is for the whisker distance 00275 */ 00276 void update(double factor = 1.5); 00277 00278 /** 00279 * decid the select strategy 00280 * @param strategy (ISelectStrategy*) the select strategy of the alg. 00281 */ 00282 inline void setSelectStrategy(ISelectStrategy* strategy) {m_selectStrategy = strategy;} 00283 00284 /** 00285 * decide the generation size strategy. 00286 * @param strategy (IGenerationSizeStrategy*) the generation size strategy of the alg. 00287 */ 00288 inline void setGenerationSizeStrategy(IGenerationSizeStrategy* strategy) {m_generationSizeStrategy = strategy;} 00289 00290 /** 00291 * decide the fitness strategy. 00292 * @param strategy (IFitnessStrategy*) the fitness strategy of the alg. 00293 */ 00294 inline void setFitnessStrategy(IFitnessStrategy* strategy) {m_fitnessStrategy = strategy;} 00295 00296 /** 00297 * calculate for a individual the fitness value. 00298 * @param individual (Individual*) the individual for which the fitness should be calculated 00299 * @return (double) the fitness value. 00300 */ 00301 double getFitness(const Individual* individual); 00302 00303 /** 00304 * returns the best individual (where the fitness is next to zero) which the alg. have found. 00305 * @return (Individual*) the best. 00306 */ 00307 Individual* getBestIndividual(void); 00308 00309 /** 00310 * returns a complete list of the inheritance of all individual. 00311 * @param withMutation (bool) normal=true. if every individual should be marked if it mutated. 00312 * @return (string) the list 00313 */ 00314 std::string getIndividualRoot(bool withMutation=true)const; 00315 00316 /** 00317 * returns a list of all individual and there gens values. 00318 * @return (string) the list 00319 */ 00320 std::string getAllIndividualAsString(void)const; 00321 00322 /** stores the object to the given file stream (binary). 00323 */ 00324 virtual bool store(FILE* f) const; 00325 00326 /** loads the object from the given file stream (binary). 00327 */ 00328 virtual bool restore(FILE* f, InspectableProxy*& proxyGeneration, InspectableProxy*& proxyGene, PlotOptionEngine* plotEngine, PlotOptionEngine* plotEngineGenContext); 00329 00330 /** 00331 * returns the only existing engine. 00332 * @return (SingletonGenEngine*) the engine 00333 */ 00334 inline static SingletonGenEngine* getInstance(void) { if(m_engine==0) m_engine = new SingletonGenEngine();return m_engine; } 00335 00336 /** 00337 * destroy the only existing engine. 00338 */ 00339 inline static void destroyGenEngine(bool cleanStrategies=false) {getInstance()->m_cleanStrategies=cleanStrategies; if(m_engine!=0){delete m_engine;m_engine=0;}} 00340 00341 protected: 00342 /** 00343 * managment storage for all Genprototypes. 00344 */ 00345 std::vector<GenPrototype*> m_prototype; 00346 00347 /** 00348 * managment storage for all Generation 00349 */ 00350 std::vector<Generation*> m_generation; 00351 00352 /** 00353 * management storage for all Individual 00354 */ 00355 std::vector<Individual*> m_individual; 00356 00357 /** 00358 * management storage for all Gens 00359 */ 00360 std::vector<Gen*> m_gen; 00361 00362 /** 00363 * the number of the actual generation 00364 */ 00365 int m_actualGeneration; 00366 00367 /** 00368 * the select strategy of the alg. 00369 */ 00370 ISelectStrategy* m_selectStrategy; 00371 00372 /** 00373 * the fitness strategy of the alg. 00374 */ 00375 IFitnessStrategy* m_fitnessStrategy; 00376 00377 /** 00378 * the generation size strategy of the alg. 00379 */ 00380 IGenerationSizeStrategy* m_generationSizeStrategy; 00381 00382 /** 00383 * the one and only GenEngine. 00384 */ 00385 static SingletonGenEngine* m_engine; 00386 00387 /** 00388 * flag for clean the seted strategies 00389 */ 00390 bool m_cleanStrategies; 00391 00392 /** 00393 * Map for restoring the generations from a run before 00394 */ 00395 std::map<int,RESTORE_GA_GENERATION*> m_restoreGeneration; 00396 00397 /** 00398 * Map for restoring the individuals from a run before 00399 */ 00400 std::map<int,RESTORE_GA_INDIVIDUAL*> m_restoreIndividual; 00401 00402 /** 00403 * Map for restoring the individual generation link from a run before 00404 */ 00405 std::map<int,std::vector<int> > m_restoreIndividualInGeneration; 00406 00407 /** 00408 * Map for restoring the genes individual link from a run before 00409 */ 00410 std::map<int,std::vector<int> > m_restoreGeneInIndividual; 00411 00412 /** 00413 * Map for restoring the names of the individuals 00414 */ 00415 std::map<int,std::string> m_restoreNameOfIndividuals; 00416 00417 private: 00418 /** 00419 * disable the default constructor 00420 */ 00421 SingletonGenEngine(); 00422 00423 /** 00424 * disable the default destructor 00425 * @return 00426 */ 00427 virtual ~SingletonGenEngine(); 00428 }; 00429 00430 #endif /* SINGLETONGENENGINE_H_ */