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 SINGLETONGENALGAPI_H_ 00028 #define SINGLETONGENALGAPI_H_ 00029 00030 //includes 00031 #include <string> 00032 #include <list> 00033 #include <selforg/randomgenerator.h> 00034 00035 //forward declaration 00036 class Gen; 00037 class GenPrototype; 00038 class GenContext; 00039 class Individual; 00040 class Generation; 00041 class IMutationStrategy; 00042 class IMutationFactorStrategy; 00043 class ISelectStrategy; 00044 class IGenerationSizeStrategy; 00045 class IRandomStrategy; 00046 class IValue; 00047 class IFitnessStrategy; 00048 00049 //forward declaration for LPZROBOTS 00050 class PlotOptionEngine; 00051 class PlotOption; 00052 00053 //ga_tools includes 00054 #include "SingletonGenEngine.h" 00055 00056 /** 00057 * This is a facade for the gen. alg. 00058 * 00059 * Over this is the class as singleton concepted. Only one API for a run. 00060 */ 00061 class SingletonGenAlgAPI{ 00062 public: 00063 // Action 00064 /** 00065 * starts the selection 00066 * @param createNextGeneration (bool) normal=true should be the next generation be prepare? 00067 */ 00068 void select(bool createNextGeneration=true); 00069 /** 00070 * create the children from to fill up the next generation 00071 * @param random (RandGen*) random generator 00072 */ 00073 void crossover(RandGen* random); 00074 /** 00075 * update the internal statistical data 00076 * @param factor (double) normal=1.5 is needed for the whisker distance 00077 */ 00078 void update(double factor = 1.5); 00079 /** 00080 * prepares the first generation and optional the enabled measure 00081 * @param startSize (int) Number of individual at begin of the gen. alg. 00082 * @param startChildren (int) Number of individual which will be created by crossover 00083 * @param random (RandGen*) A random generator 00084 * @param withUpdate (bool) is needed for "generateFirstGeneration" 00085 */ 00086 void prepare(int startSize, int numChildren, RandGen* random, bool withUpdate = true); 00087 /** 00088 * prepares the next generation and optional the enabled measure 00089 */ 00090 void prepare(); 00091 /** 00092 * makes a step in the measure 00093 * @param time (double) time stamp in the measure 00094 */ 00095 void measureStep(double time); 00096 /** 00097 * start the sequenz of select, crossover, update in a automatically loop 00098 * @param startSize (int) Number of individual at begin of the gen. alg. 00099 * @param numChildren (int) Number of individual which will be created by crossover 00100 * @param numGeneration (int) Number of generation which the alg. max. runs 00101 * @param random (RandGen*) random generator 00102 */ 00103 void runGenAlg(int startSize, int numChildren, int numGeneration, RandGen* random); 00104 00105 //measure 00106 /** 00107 * enables data measure with more than one plotOption. 00108 * @param plotOptions (list<PöotOption>&) the list 00109 */ 00110 void enableMeasure(std::list<PlotOption>& plotOptions); 00111 /** 00112 * enables da : public Storableta measure. 00113 * @param plotOption (PlotOption&) the plot option 00114 */ 00115 void enableMeasure(PlotOption& plotOption); 00116 /** 00117 * returns the active plotOptionEngine for data measure. 00118 * @return (PlotOptionEngine*) the plot option engine 00119 */ 00120 inline PlotOptionEngine* getPlotOptionEngine(void)const {return m_plotEngine;} 00121 /** 00122 * enable data measure inside the GenContexts with more than one plotOption 00123 * @param plotOptions (list<PlotOption>&) the list 00124 */ 00125 void enableGenContextMeasure(std::list<PlotOption>& plotOptions); 00126 /** 00127 * enable data measure inside the GenContexts. 00128 * @param plotOption (PlotOption&) the plot option 00129 */ 00130 void enableGenContextMeasure(PlotOption& plotOption); 00131 /** 00132 * returns the active plotOptionEngine for data measure inside the GenContexts. 00133 * @return (PlotOptionEngine*) the plot option engine. 00134 */ 00135 inline PlotOptionEngine* getPlotOptionEngineForGenContext(void)const {return m_plotEngineGenContext;} 00136 00137 // set static strategies 00138 /** 00139 * set the generation size strategy 00140 * @param strategy (IGenerationSizeStrategy*) the strategy 00141 */ 00142 inline void setGenerationSizeStrategy(IGenerationSizeStrategy* strategy) {SingletonGenEngine::getInstance()->setGenerationSizeStrategy(strategy);} 00143 /** 00144 * set the fitness strategy 00145 * @param strategy (IFitnessStrategy*) the strategy 00146 */ 00147 inline void setFitnessStrategy(IFitnessStrategy* strategy) {SingletonGenEngine::getInstance()->setFitnessStrategy(strategy);} 00148 /** 00149 * set the select strategy 00150 * @param strategy (ISelectStrategy*) the strategy 00151 */ 00152 inline void setSelectStrategy(ISelectStrategy* strategy) {SingletonGenEngine::getInstance()->setSelectStrategy(strategy);} 00153 00154 // gets 00155 /** 00156 * returns the GenAlgEngine 00157 * @return (SingletonGenEngine*) the engine 00158 */ 00159 SingletonGenEngine* getEngine(void)const; 00160 00161 // default interface creation 00162 /** 00163 * creates a SumFitnessStrategy. This strategy make the sum of all gens with a double value. 00164 * @return (IFitnessStrategy*) the strategy 00165 */ 00166 IFitnessStrategy* createSumFitnessStrategy()const; 00167 /** 00168 * creates a EuclidicFitnessStrategy. This strategy calculate the euclidic distance of all gens with a double value. 00169 * @return (IFitnessStrategy*) the strategy 00170 */ 00171 IFitnessStrategy* createEuclidicDistanceFitnessStrategy()const; 00172 /** 00173 * creates a TestFitnessStrategy which is the hardest test for a gen. alg. Only a smale area has a fitness. All other gives no information! 00174 * @param fitness (IFitnessStrategy*) a other fitness strat* Over this is the class as singleton concepted. Only one engine for a run.egy which define the smal area. 00175 * @return (IFitnessStrategy*) the strategy 00176 */ 00177 IFitnessStrategy* createExtreamTestFitnessStrategy(IFitnessStrategy* fitness)const; 00178 /** 00179 * creates the test function fitness strategy from the papper tp this alg. 00180 * f(x,y) = 10.0 * (x² + 2.5y² - y) * exp(1 - (x² + y²)) + 2.4 + 0.1x² + 0.1y² 00181 * @return (IFitnessStrategy*) the strategy 00182 */ 00183 IFitnessStrategy* createTestFitnessStrategy()const; 00184 /** 00185 * returns a fitness strategy which calculate the inverse value from a other strategy. 00186 * @param strategy (IFitnessStrategy*) the other strategy 00187 * @return (IFitnessStrategy*) the resulting strategy 00188 */ 00189 IFitnessStrategy* createInvertedFitnessStrategy(IFitnessStrategy* strategy)const; 00190 /** 00191 * creates a random strategy for double values. 00192 * The values will be generated in the intervals [base-epsilon:-epsilon] or [epsilon:factor+base+epsilon] 00193 * 00194 * This means a random value in the interval [0:1] will be mul. with factor => [0:factor] 00195 * After this it will be shifted by base => [base:factor+base] 00196 * And than divided at the point zero and moved away by epsilon from the point zero 00197 * => [base-epsilon:-epsilon], [epsilon:factor+base+epsilon] 00198 * 00199 * For example: 00200 * We want values in the intervals [-10:-5] and [5:10]. 00201 * ==> epsilon=5 00202 * ==> [-5:5] 00203 * ==> base=-5 00204 * ==> [0:10] 00205 * ==> factor=10 00206 * 00207 * @param random (RandGen*) random generator 00208 * @param base (double) normal=0.0 moves the ground interval 00209 * @param factor (double) normal=1.0 resize the interval 00210 * @param epsilon (double) normal=0.0 devided the interval at the point zero and move the 00211 * values by epsilon away from point zero 00212 * @return (IRandomStrategy*) the strategy 00213 */ 00214 IRandomStrategy* createDoubleRandomStrategy(RandGen* random, double base=0.0, double factor=1.0, double epsilon = 0.0)const; 00215 /** 00216 * creates mutation strategy which change the old values by add a other value 00217 * @param strategy (IMutationFactorStrategy*) this strategy define what the other value is. 00218 * @param mutationProbability (int) the probability of mutation in one per tausend (1/1000) 00219 * @return (IMutationStrategy*) the strategy 00220 */ 00221 IMutationStrategy* createValueMutationStrategy(IMutationFactorStrategy* strategy, int mutationProbability)const; 00222 /** 00223 * creates a mutation factor strategy with a fix value 00224 * @param value (IValue*) the fix value. 00225 * @return (IMutationFactorStrategy*) the strategy 00226 */ 00227 IMutationFactorStrategy* createFixMutationFactorStrategy(IValue* value)const; 00228 /** 00229 * creates a mutation factor strategy with a optimized value (varianz about all existing gens) 00230 * @return (IMutationFactorStrategy*) the strategy 00231 */ 00232 IMutationFactorStrategy* createStandartMutationFactorStrategy(void)const; 00233 /** 00234 * creates a generation size strategy with a fix value 00235 * @param value (int) the size of the generation 00236 * @return (IGenerationSizeStrategy*) the strategy 00237 */ 00238 IGenerationSizeStrategy* createFixGenerationSizeStrategy(int value)const; 00239 /** 00240 * creates a generation size strategy with a optimized size for the generation (changing by speed of development) 00241 * @param startSize (int) the size at the start time 00242 * @param numGeneration (int) number of generation. (needed for the speed calculation 00243 * @return (IGenerationSizeStrategy*) the strategy 00244 */ 00245 IGenerationSizeStrategy* createStandartGenerationSizeStrategy(int startSize, int numGeneration)const; 00246 /** 00247 * creates a elite select strategy 00248 * @return (ISelectStrategy*) the strategy 00249 */ 00250 ISelectStrategy* createEliteSelectStrategy(void)const; 00251 /** 00252 * creates a tournament SelctStrategy. By this strategy will two individual fight again 00253 * (the individual with the higher fitness lives longer). 00254 * @param random (RandGen*) random generator 00255 * @return (ISelectStrategy*) the strategy 00256 */ 00257 ISelectStrategy* createTournamentSelectStrategy(RandGen* random)const; 00258 /** 00259 * creates a random select strategy. By this strategy will a random selected individual fight again a random number. 00260 * If the random number higher than the fitness from the individual, than it will be die. 00261 * @param random (RandGen*) ranom generator 00262 * @return (ISelectStrategy*) the strategy 00263 */ 00264 ISelectStrategy* createRandomSelectStrategy(RandGen* random)const; 00265 /** 00266 * creates a IValue (TemplateValue<double) from type double. 00267 * @param value (double) the value 00268 * @return (IValue*) the new object 00269 */ 00270 IValue* createDoubleValue(double value)const; 00271 00272 //Storable 00273 /** stores the object to the given file stream (binary). 00274 */ 00275 bool storeGA(FILE* f) const; 00276 00277 /** loads the object from the given file stream (binary). 00278 */ 00279 bool restoreGA(FILE* f) const; 00280 00281 // inserts 00282 /** 00283 * add a GenPrototype to the alg. 00284 * @param prototype (GenPrototype*) the prototype 00285 */ 00286 void insertGenPrototype(GenPrototype* prototype); 00287 00288 // object creation 00289 /** 00290 * create a prototype. 00291 * @param name (STRING) THE NAME OF THE PROTOTYPE 00292 * @param randomStrategy (IRandomStrategy*) the random strategy to generate values of the type 00293 * which the prototype represent 00294 * @param mutationStrategy (IMutationStrategy*) the mutation strategy to change a value (Gen) 00295 * @return (GenPrototype*) the prototype 00296 */ 00297 GenPrototype* createPrototype(std::string name, IRandomStrategy* randomStrategy, IMutationStrategy* mutationStrategy)const; 00298 00299 // singleton 00300 /** 00301 * returns the one and only API to the alg. 00302 * @return (SingletonGenAlgAPI*) the api 00303 */ 00304 inline static SingletonGenAlgAPI* getInstance(void) {if(m_api==0)m_api = new SingletonGenAlgAPI();return m_api;} 00305 /** 00306 * destroy the api 00307 * @param cleanStrategies (bool) default = false set a flag to clean the strategies, which are seted. 00308 */ 00309 inline static void destroyAPI(bool cleanStrategies=false) {getInstance()->m_cleanStrategies=cleanStrategies; if(m_api!=0){delete m_api;m_api=0;}} 00310 00311 // data access 00312 /** 00313 * returns the best individual which the alg. have found 00314 * @return (Individual*) the best 00315 */ 00316 inline Individual* getBestIndividual(void)const {return SingletonGenEngine::getInstance()->getBestIndividual();} 00317 00318 protected: 00319 /** 00320 * the api 00321 */ 00322 static SingletonGenAlgAPI* m_api; 00323 00324 /** 00325 * plot option engine for data measure 00326 */ 00327 PlotOptionEngine* m_plotEngine; 00328 00329 /** 00330 * plot option engine for gen contexts 00331 */ 00332 PlotOptionEngine* m_plotEngineGenContext; 00333 00334 private: 00335 /** 00336 * disable the default contructor 00337 */ 00338 SingletonGenAlgAPI(); 00339 /** 00340 * disable the default destructor 00341 */ 00342 virtual ~SingletonGenAlgAPI(); 00343 00344 /** 00345 * help declaration for prepare 00346 */ 00347 void* m_generation; 00348 00349 /** 00350 * help declaration for prepare 00351 */ 00352 void* m_inspectable; 00353 00354 /** 00355 * Flag for clean the strategies 00356 */ 00357 bool m_cleanStrategies; 00358 }; 00359 00360 #endif /* SINGLETONGENALGAPI_H_ */