Created by Scott Robert Ladd at Coyote Gulch Productions.
00001 /* 00002 Evocosm is a C++ framework for implementing evolutionary algorithms. 00003 00004 Copyright 2011 Scott Robert Ladd. All rights reserved. 00005 00006 Evocosm is user-supported open source software. Its continued development is dependent 00007 on financial support from the community. You can provide funding by visiting the Evocosm 00008 website at: 00009 00010 http://www.coyotegulch.com 00011 00012 You may license Evocosm in one of two fashions: 00013 00014 1) Simplified BSD License (FreeBSD License) 00015 00016 Redistribution and use in source and binary forms, with or without modification, are 00017 permitted provided that the following conditions are met: 00018 00019 1. Redistributions of source code must retain the above copyright notice, this list of 00020 conditions and the following disclaimer. 00021 00022 2. Redistributions in binary form must reproduce the above copyright notice, this list 00023 of conditions and the following disclaimer in the documentation and/or other materials 00024 provided with the distribution. 00025 00026 THIS SOFTWARE IS PROVIDED BY SCOTT ROBERT LADD ``AS IS'' AND ANY EXPRESS OR IMPLIED 00027 WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 00028 FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SCOTT ROBERT LADD OR 00029 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 00030 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 00031 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 00032 ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 00033 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 00034 ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00035 00036 The views and conclusions contained in the software and documentation are those of the 00037 authors and should not be interpreted as representing official policies, either expressed 00038 or implied, of Scott Robert Ladd. 00039 00040 2) Closed-Source Proprietary License 00041 00042 If your project is a closed-source or proprietary project, the Simplified BSD License may 00043 not be appropriate or desirable. In such cases, contact the Evocosm copyright holder to 00044 arrange your purchase of an appropriate license. 00045 00046 The author can be contacted at: 00047 00048 scott.ladd@coyotegulch.com 00049 scott.ladd@gmail.com 00050 http:www.coyotegulch.com 00051 */ 00052 00053 #if !defined(EVOCOSM_FUNCTION_OPTIMIZER_H) 00054 #define EVOCOSM_FUNCTION_OPTIMIZER_H 00055 00056 #include <vector> 00057 #include <stdexcept> 00058 #include <limits> 00059 00060 // other elements of Evocosm 00061 #include "evocosm.h" 00062 #include "evoreal.h" 00063 00064 // OpenMP support, if requested 00065 #if defined(_OPENMP) 00066 #include <omp.h> 00067 #endif 00068 00069 namespace libevocosm 00070 { 00072 00077 class fopt_global 00078 { 00079 protected: 00081 00089 typedef vector<double> t_function(vector<double> a_args); 00090 00092 static evoreal g_evoreal; 00093 }; 00094 00096 00105 class function_solution : public organism< vector<double> >, protected fopt_global 00106 { 00107 public: 00114 double value; 00115 00116 protected: 00118 virtual void child_copy(const organism & a_source) 00119 { 00120 value = dynamic_cast<const function_solution &>(a_source).value; 00121 } 00122 00123 private: 00124 double m_minarg; 00125 double m_maxarg; 00126 double m_extent; 00127 00128 public: 00130 00133 function_solution() 00134 : organism< vector<double> >(), 00135 value(0.0), 00136 m_minarg(-1.0), 00137 m_maxarg(1.0), 00138 m_extent(2.0) 00139 { 00140 // nada 00141 } 00142 00144 00147 function_solution(int a_nargs, double a_minarg, double a_maxarg) 00148 : organism< vector<double> >(), value(0.0) 00149 { 00150 double base; 00151 double extent; 00152 00153 if (a_maxarg < a_minarg) 00154 { 00155 double temp = a_maxarg; 00156 a_maxarg = a_minarg; 00157 a_minarg = a_maxarg; 00158 } 00159 00160 m_minarg = a_minarg; 00161 m_maxarg = a_maxarg; 00162 m_extent = a_maxarg - a_minarg; 00163 00164 // values fall in the range [-1,1] 00165 for (size_t n = 0; n < a_nargs; ++n) 00166 genes.push_back(g_random.get_real() * m_extent + a_minarg); 00167 } 00168 00170 00173 function_solution(const vector<double> & a_source) 00174 : organism< vector<double> >(a_source), value(0.0) 00175 { 00176 // nada 00177 } 00178 00180 00184 function_solution(const organism< vector<double> > & a_source) 00185 : organism< vector<double> >(a_source), value(0.0) 00186 { 00187 // nada 00188 } 00189 00191 00195 function_solution(const function_solution & a_source) 00196 : organism< vector<double> >(a_source), 00197 value(a_source.value), 00198 m_minarg(a_source.m_minarg), 00199 m_maxarg(a_source.m_maxarg), 00200 m_extent(a_source.m_extent) 00201 { 00202 // nada 00203 } 00204 00206 00209 virtual ~function_solution() 00210 { 00211 // nada 00212 } 00213 00215 00220 function_solution & operator = (const function_solution & a_source) 00221 { 00222 organism< vector<double> >::operator = (a_source); 00223 value = a_source.value; 00224 m_minarg = a_source.m_minarg; 00225 m_maxarg = a_source.m_maxarg; 00226 m_extent = a_source.m_extent; 00227 return *this; 00228 } 00229 00231 00238 virtual bool operator < (const organism< vector<double> > & a_right) const 00239 { 00240 return (fitness > a_right.fitness); 00241 } 00242 }; 00243 00245 00248 class function_mutator : public mutator<function_solution>, protected fopt_global 00249 { 00250 public: 00252 00255 function_mutator(double a_mutation_rate) 00256 : m_mutation_rate(a_mutation_rate) 00257 { 00258 // adjust mutation rate if necessary 00259 if (m_mutation_rate > 1.0) 00260 m_mutation_rate = 1.0; 00261 else if (m_mutation_rate < 0.0) 00262 m_mutation_rate = 0.0; 00263 } 00264 00266 00270 function_mutator(const function_mutator & a_source) 00271 : m_mutation_rate(a_source.m_mutation_rate) 00272 { 00273 // nada 00274 } 00275 00277 00280 virtual ~function_mutator() 00281 { 00282 // nada 00283 } 00284 00286 00291 function_mutator & operator = (const function_mutator & a_source) 00292 { 00293 m_mutation_rate = a_source.m_mutation_rate; 00294 return *this; 00295 } 00296 00298 00302 double mutation_rate() const 00303 { 00304 return m_mutation_rate; 00305 } 00306 00308 00312 void mutate(vector<function_solution> & a_population); 00313 00314 private: 00315 // rate of mutation 00316 double m_mutation_rate; 00317 }; 00318 00320 00323 class function_reproducer : public reproducer<function_solution>, protected fopt_global 00324 { 00325 public: 00327 00330 function_reproducer(double p_crossover_rate = 1.0) 00331 : m_crossover_rate(p_crossover_rate) 00332 { 00333 // adjust crossover rate if necessary 00334 if (m_crossover_rate > 1.0) 00335 m_crossover_rate = 1.0; 00336 else if (m_crossover_rate < 0.0) 00337 m_crossover_rate = 0.0; 00338 } 00339 00341 00345 function_reproducer(const function_reproducer & a_source) 00346 : m_crossover_rate(a_source.m_crossover_rate) 00347 { 00348 // nada 00349 } 00350 00352 00355 virtual ~function_reproducer() 00356 { 00357 // nada 00358 } 00359 00361 00366 function_reproducer & operator = (const function_reproducer & a_source) 00367 { 00368 m_crossover_rate = a_source.m_crossover_rate; 00369 return *this; 00370 } 00371 00373 00377 double crossover_rate() const 00378 { 00379 return m_crossover_rate; 00380 } 00381 00383 00392 virtual vector<function_solution> breed(const vector<function_solution> & a_population, size_t p_limit); 00393 00394 private: 00395 // crossover chance 00396 double m_crossover_rate; 00397 }; 00398 00400 00405 class function_landscape : public landscape<function_solution>, protected fopt_global 00406 { 00407 public: 00409 00414 function_landscape(t_function * a_function, listener<function_solution> & a_listener) 00415 : landscape<function_solution>(a_listener), 00416 m_function(a_function) 00417 { 00418 // nada 00419 } 00420 00422 function_landscape(const function_landscape & a_source) 00423 : landscape<function_solution>(a_source), 00424 m_function(a_source.m_function) 00425 { 00426 // nada 00427 } 00428 00430 function_landscape & operator = (const function_landscape & a_source) 00431 { 00432 landscape<function_solution>::operator = (a_source); 00433 m_function = a_source.m_function; 00434 return *this; 00435 } 00436 00438 00441 ~function_landscape() 00442 { 00443 // nada 00444 } 00445 00447 00454 virtual double test(function_solution & a_organism, bool a_verbose = false) const 00455 { 00456 vector<double> z = m_function(a_organism.genes); 00457 a_organism.value = z[0]; 00458 a_organism.fitness = z[1]; 00459 return a_organism.fitness; 00460 } 00461 00462 private: 00463 // fitness function pointer 00464 t_function * m_function; 00465 }; 00466 00468 00472 class function_analyzer : public analyzer<function_solution> 00473 { 00474 private: 00475 function_solution m_prev_best; 00476 size_t m_count; 00477 00478 public: 00480 00484 function_analyzer(listener<function_solution> & a_listener, size_t max_iterations) 00485 : analyzer<function_solution>(a_listener, max_iterations), 00486 m_prev_best(function_solution()), 00487 m_count(0) 00488 { 00489 // nada 00490 } 00491 00493 00503 virtual bool analyze(const vector<function_solution> & a_population, 00504 size_t a_iteration, 00505 double & a_fitness); 00506 }; 00507 00509 00513 class function_listener : public null_listener<function_solution> 00514 { 00515 public: 00517 00521 virtual void ping_generation_begin(size_t a_iteration); 00522 00524 00529 virtual void ping_generation_end(const vector<function_solution> & a_population, size_t a_iteration); 00530 }; 00531 00533 00538 class function_optimizer : protected fopt_global, protected function_listener 00539 { 00540 private: 00541 // objects that define the characteristics of the genetic algorithm 00542 vector<function_solution> m_population; 00543 function_landscape m_landscape; 00544 function_mutator m_mutator; 00545 function_reproducer m_reproducer; 00546 linear_norm_scaler<function_solution> m_scaler; 00547 elitism_selector<function_solution> m_selector; 00548 function_analyzer m_analyzer; 00549 00550 // the evocosm binds it all together 00551 evocosm<function_solution> * m_evocosm; 00552 00553 // number of iterations to run 00554 const size_t m_iterations; 00555 00556 public: 00558 00568 function_optimizer(t_function * a_function, 00569 size_t a_nargs, 00570 double a_minarg, 00571 double a_maxarg, 00572 size_t a_norgs, 00573 double a_mutation_rate, 00574 size_t a_iterations); 00575 00577 00580 virtual ~function_optimizer(); 00581 00583 00588 void run(); 00589 }; 00590 00591 }; 00592 00593 #endif
© 1996-2005 Scott Robert Ladd. All rights reserved.
HTML documentation generated by Dimitri van Heesch's excellent Doxygen tool.