00001 /*************************************************************************** 00002 * Copyright (C) 2008-2011 LpzRobots development team * 00003 * Joerg Weider <joergweide84 at aol dot com> (robot12) * 00004 * Georg Martius <georg dot martius at web dot de> * 00005 * Frank Guettler <guettler at informatik dot uni-leipzig dot de * 00006 * Frank Hesse <frank at nld dot ds dot mpg dot de> * 00007 * Ralf Der <ralfder at mis dot mpg dot de> * 00008 * Joern Hoffmann <jhoffmann at informatik dot uni-leipzig dot de * 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 00027 #ifndef SINGLETONGENENGINE_H_ 00028 #define SINGLETONGENENGINE_H_ 00029 00030 //includes 00031 #include <vector> 00032 #include <map> 00033 #include <string> 00034 #include <selforg/randomgenerator.h> 00035 #include <selforg/inspectableproxy.h> 00036 //#include <selforg/storeable.h> not possible because the restore function need more information!!! 00037 00038 //forward declaration 00039 class Gen; 00040 class GenPrototype; 00041 class GenContext; 00042 class Individual; 00043 class Generation; 00044 class IMutationStrategy; 00045 class IMutationFactorStrategy; 00046 class ISelectStrategy; 00047 class IGenerationSizeStrategy; 00048 class IRandomStrategy; 00049 class IValue; 00050 class IFitnessStrategy; 00051 struct RESTORE_GA_GENERATION; 00052 struct RESTORE_GA_INDIVIDUAL; 00053 struct RESTORE_GA_GENE; 00054 template<class Typ>struct RESTORE_GA_TEMPLATE; 00055 00056 //forward declaration for LPZROBOTS 00057 class PlotOptionEngine; 00058 00059 /** 00060 * This is the engine of the gen. alg. 00061 * 00062 * Over this is the class as singleton concepted. Only one engine for a run. 00063 */ 00064 class SingletonGenEngine{ 00065 public: 00066 /** 00067 * this function returns a set of all registered GenPrototypes. 00068 * @return (vector<GenPrototype*>&) the set 00069 */ 00070 inline const std::vector<GenPrototype*>& getSetOfGenPrototyps(void) const {return m_prototype;} 00071 00072 /** 00073 * this function return the number of Generation inside. 00074 * @return (int) the number of Generation in the storage 00075 */ 00076 inline int getNumGeneration(void) const {return m_generation.size();} 00077 00078 /** 00079 * this function returns one Generation 00080 * @param x (int) the index of the Generation which is searched 00081 * @return (Generation*) the searched Generation. If x not a right index, than the result is zero. 00082 */ 00083 inline Generation* getGeneration(int x) {if(x<getNumGeneration())return m_generation[x];return NULL;} 00084 00085 /** 00086 * returns the actual generation number, on which the alg. work 00087 * @return (int) the actual generation number 00088 */ 00089 inline int getActualGenerationNumber(void) const {return m_actualGeneration;} 00090 00091 /** 00092 * returns the actual Generation. 00093 * @return (Generation*) the actual generation 00094 */ 00095 inline Generation* getActualGeneration(void) {return m_generation[m_actualGeneration];} 00096 00097 /** 00098 * returns the number of individual inside the alg. 00099 * @return (int) number of individual 00100 */ 00101 inline int getNumIndividual(void) const {return m_individual.size();} 00102 00103 /** 00104 * returns one individual 00105 * @param x (int) index of the individual which is searched. 00106 * @return (Individual*) the searched individual 00107 */ 00108 inline Individual* getIndividual(int x) const {if(x<getNumIndividual())return m_individual[x];return NULL;} 00109 00110 /** 00111 * registered a GenPrototype in the engine. 00112 * @param prototype (GenPrototype*) the prototype which should be registered. 00113 */ 00114 inline void addGenPrototype(GenPrototype* prototype) {m_prototype.push_back(prototype);} 00115 00116 /** 00117 * registered a Gen in the engine. Normal only used by the alg. self. 00118 * @param gen (Gen*) the Gen which should be registered. 00119 */ 00120 inline void addGen(Gen* gen) {m_gen.push_back(gen);} 00121 00122 /** 00123 * returns one gene 00124 * @param x (int) index of the gene which is searched 00125 * @return (Gen*) the searched gene 00126 */ 00127 inline Gen* getGen(int x)const {if((unsigned int)x<m_gen.size())return m_gen[x];return NULL;} 00128 00129 /** 00130 * registered a individual in the engine. Normal only used by the alg. self. 00131 * @param individual (Individual*) the individual 00132 */ 00133 inline void addIndividual(Individual* individual) {m_individual.push_back(individual);} 00134 00135 /** 00136 * add a Generation to the alg. Normal only used by the alg. self. 00137 * @param generation (Generation*) the generation 00138 */ 00139 inline void addGeneration(Generation* generation) {m_generation.push_back(generation);} 00140 00141 /** 00142 * prepare the alg. and create his fisrt generation. 00143 * @param startSize (int) Number of individual with which the alg. will be start. 00144 * @param numChildren (int) Number of individual which will be created by crossover. 00145 * @param random (RandGen*) A random generator 00146 * @param withUpdate (bool) if true, than makes this function on the end a update. 00147 */ 00148 void generateFirstGeneration(int startSize, int numChildren, RandGen* random, bool withUpdate = true); 00149 00150 /** 00151 * prepare the next generation. Mean create the GenContext for every GenPrototype. 00152 * @param size (int) size of the next generation 00153 * @param numChildren (int) Number of individual which will be created by crossover 00154 */ 00155 void prepareNextGeneration(int size, int numChildren); 00156 00157 /** 00158 * prepare the first generation with "generateFirstGeneration" and init the measures. 00159 * @param startSize (int) Number of individual with which the alg. will be start. 00160 * @param numChildren (int) Number of individual which will be created by crossover 00161 * @param proxyGeneration (InspectableProxy*&) the generation which is controlled by measures 00162 * @param proxyGene (InspectableProxy*&) the proxy for control measure 00163 * @param random (RandGen*) A random generator 00164 * @param plotEngine (PlotOptionEngine*) logging the data for later control 00165 * @param plotEngineGenContext (PlotOptionEngine*) logging the data of the GenContext for later control 00166 * @param withUpdate (bool) is needed for the function "generateFirstGeneration" 00167 */ 00168 void prepare(int startSize, int numChildren, InspectableProxy*& proxyGeneration, InspectableProxy*& proxyGene, RandGen* random, PlotOptionEngine* plotEngine = 0, PlotOptionEngine* plotEngineGenContext = 0, bool withUpdate = true); 00169 00170 /** 00171 * return the size of the next generation. 00172 * @return (int) the size 00173 */ 00174 int getNextGenerationSize(); 00175 00176 /** 00177 * makes a step in the measure 00178 * @param time (double) the time stamp in the measure 00179 * @param proxyGeneration (InspectableProxy*&) the generation which is controlled by measures 00180 * @param proxyGene (InspectableProxy*&) the proxy for control measure 00181 */ 00182 void measureStep(double time,InspectableProxy*& proxyGeneration, InspectableProxy*& proxyGene, PlotOptionEngine* plotEngine = 0, PlotOptionEngine* plotEngineGenContext = 0); 00183 00184 /** 00185 * this function is for a automatically run of the gen. alg. 00186 * @param startSize (int) Number of individual with which the alg. will be start. 00187 * @param numChildren (int) Number of individual which will be created by crossover. 00188 * @param numGeneration (int) Number of generation after this the alg. will end. 00189 * @param random (RandGen*) a random generator 00190 * @param plotEngine (PlotOptionEngine*) logging the data for later control 00191 * @param plotEngineGenContext (PlotOptionEngine*) logging the data of the GenContext for later control 00192 */ 00193 void runGenAlg(int startSize, int numChildren, int numGeneration, RandGen* random, PlotOptionEngine* plotEngine = 0, PlotOptionEngine* plotEngineGenContext = 0); 00194 00195 /** 00196 * make the select of the actual generation and transfer it to the next generation 00197 * @param createNextGeneration (bool) normal=true. should be the next generation prepare 00198 */ 00199 void select(bool createNextGeneration=true); 00200 00201 /** 00202 * in the actual generation it will generate the children of the living individual 00203 * @param random (RanGen*) random generator 00204 */ 00205 void crossover(RandGen* random); 00206 00207 /** 00208 * this function makes a update on the statistical data of the gen. alg. 00209 * @param factor (double) the factor is for the whisker distance 00210 */ 00211 void update(double factor = 1.5); 00212 00213 /** 00214 * decid the select strategy 00215 * @param strategy (ISelectStrategy*) the select strategy of the alg. 00216 */ 00217 inline void setSelectStrategy(ISelectStrategy* strategy) {m_selectStrategy = strategy;} 00218 00219 /** 00220 * decide the generation size strategy. 00221 * @param strategy (IGenerationSizeStrategy*) the generation size strategy of the alg. 00222 */ 00223 inline void setGenerationSizeStrategy(IGenerationSizeStrategy* strategy) {m_generationSizeStrategy = strategy;} 00224 00225 /** 00226 * decide the fitness strategy. 00227 * @param strategy (IFitnessStrategy*) the fitness strategy of the alg. 00228 */ 00229 inline void setFitnessStrategy(IFitnessStrategy* strategy) {m_fitnessStrategy = strategy;} 00230 00231 /** 00232 * calculate for a individual the fitness value. 00233 * @param individual (Individual*) the individual for which the fitness should be calculated 00234 * @return (double) the fitness value. 00235 */ 00236 double getFitness(const Individual* individual); 00237 00238 /** 00239 * returns the best individual (where the fitness is next to zero) which the alg. have found. 00240 * @return (Individual*) the best. 00241 */ 00242 Individual* getBestIndividual(void); 00243 00244 /** 00245 * returns a complete list of the inheritance of all individual. 00246 * @param withMutation (bool) normal=true. if every individual should be marked if it mutated. 00247 * @return (string) the list 00248 */ 00249 std::string getIndividualRoot(bool withMutation=true)const; 00250 00251 /** 00252 * returns a list of all individual and there gens values. 00253 * @return (string) the list 00254 */ 00255 std::string getAllIndividualAsString(void)const; 00256 00257 /** stores the object to the given file stream (binary). 00258 */ 00259 virtual bool store(FILE* f) const; 00260 00261 /** loads the object from the given file stream (binary). 00262 */ 00263 virtual bool restore(FILE* f, InspectableProxy*& proxyGeneration, InspectableProxy*& proxyGene, PlotOptionEngine* plotEngine, PlotOptionEngine* plotEngineGenContext); 00264 00265 /** 00266 * returns the only existing engine. 00267 * @return (SingletonGenEngine*) the engine 00268 */ 00269 inline static SingletonGenEngine* getInstance(void) { if(m_engine==0) m_engine = new SingletonGenEngine();return m_engine; } 00270 00271 /** 00272 * destroy the only existing engine. 00273 */ 00274 inline static void destroyGenEngine(bool cleanStrategies=false) {getInstance()->m_cleanStrategies=cleanStrategies; if(m_engine!=0){delete m_engine;m_engine=0;}} 00275 00276 protected: 00277 /** 00278 * managment storage for all Genprototypes. 00279 */ 00280 std::vector<GenPrototype*> m_prototype; 00281 00282 /** 00283 * managment storage for all Generation 00284 */ 00285 std::vector<Generation*> m_generation; 00286 00287 /** 00288 * management storage for all Individual 00289 */ 00290 std::vector<Individual*> m_individual; 00291 00292 /** 00293 * management storage for all Gens 00294 */ 00295 std::vector<Gen*> m_gen; 00296 00297 /** 00298 * the number of the actual generation 00299 */ 00300 int m_actualGeneration; 00301 00302 /** 00303 * the select strategy of the alg. 00304 */ 00305 ISelectStrategy* m_selectStrategy; 00306 00307 /** 00308 * the fitness strategy of the alg. 00309 */ 00310 IFitnessStrategy* m_fitnessStrategy; 00311 00312 /** 00313 * the generation size strategy of the alg. 00314 */ 00315 IGenerationSizeStrategy* m_generationSizeStrategy; 00316 00317 /** 00318 * the one and only GenEngine. 00319 */ 00320 static SingletonGenEngine* m_engine; 00321 00322 /** 00323 * flag for clean the seted strategies 00324 */ 00325 bool m_cleanStrategies; 00326 00327 /** 00328 * Map for restoring the generations from a run before 00329 */ 00330 std::map<int,RESTORE_GA_GENERATION*> m_restoreGeneration; 00331 00332 /** 00333 * Map for restoring the individuals from a run before 00334 */ 00335 std::map<int,RESTORE_GA_INDIVIDUAL*> m_restoreIndividual; 00336 00337 /** 00338 * Map for restoring the individual generation link from a run before 00339 */ 00340 std::map<int,std::vector<int> > m_restoreIndividualInGeneration; 00341 00342 /** 00343 * Map for restoring the genes individual link from a run before 00344 */ 00345 std::map<int,std::vector<int> > m_restoreGeneInIndividual; 00346 00347 /** 00348 * Map for restoring the names of the individuals 00349 */ 00350 std::map<int,std::string> m_restoreNameOfIndividuals; 00351 00352 private: 00353 /** 00354 * disable the default constructor 00355 */ 00356 SingletonGenEngine(); 00357 00358 /** 00359 * disable the default destructor 00360 * @return 00361 */ 00362 virtual ~SingletonGenEngine(); 00363 }; 00364 00365 #endif /* SINGLETONGENENGINE_H_ */