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(LIBEVOCOSM_SCALER_H) 00054 #define LIBEVOCOSM_SCALER_H 00055 00056 // libevocosm 00057 #include "organism.h" 00058 #include "stats.h" 00059 00060 namespace libevocosm 00061 { 00063 00071 template <class OrganismType> 00072 class scaler : protected globals 00073 { 00074 public: 00076 00083 virtual ~scaler() 00084 { 00085 // nada 00086 } 00087 00089 00095 virtual void scale_fitness(vector<OrganismType> & a_population) = 0; 00096 }; 00097 00099 00104 template <class OrganismType> 00105 class null_scaler : public scaler<OrganismType> 00106 { 00107 public: 00109 00113 virtual void scale_fitness(vector<OrganismType> & a_population) 00114 { 00115 // nada 00116 } 00117 }; 00118 00120 00125 template <class OrganismType> 00126 class linear_norm_scaler : public scaler<OrganismType> 00127 { 00128 public: 00130 00133 linear_norm_scaler(double a_fitness_multiple = 2.0) 00134 : m_fitness_multiple(a_fitness_multiple) 00135 { 00136 // nada 00137 } 00138 00140 00144 virtual void scale_fitness(vector<OrganismType> & a_population) 00145 { 00146 // calculate max, average, and minimum fitness for the population 00147 fitness_stats<OrganismType> stats(a_population); 00148 00149 // calculate coefficients for fitness scaling 00150 double slope; 00151 double intercept; 00152 double delta; 00153 00154 if (stats.getMin() > ((m_fitness_multiple * stats.getMean() - stats.getMax()) / (m_fitness_multiple - 1.0))) 00155 { 00156 // normal scaling 00157 delta = stats.getMax() - stats.getMean(); 00158 slope = (m_fitness_multiple - 1.0) * stats.getMean() / delta; 00159 intercept = stats.getMean() * (stats.getMax() - m_fitness_multiple * stats.getMean()) / delta; 00160 } 00161 else 00162 { 00163 // extreme scaling 00164 delta = stats.getMean() - stats.getMin(); 00165 slope = stats.getMean() / delta; 00166 intercept = -stats.getMin() * stats.getMean() / delta; 00167 } 00168 00169 // adjust fitness values 00170 for (int n = 0; n < a_population.size(); ++n) 00171 a_population[n].fitness = slope * a_population[n].fitness + intercept; 00172 } 00173 00174 private: 00175 double m_fitness_multiple; 00176 }; 00177 00179 00184 template <class OrganismType> 00185 class windowed_scaler : public scaler<OrganismType> 00186 { 00187 public: 00189 00192 windowed_scaler() 00193 { 00194 // nada 00195 } 00196 00198 00202 virtual void scale_fitness(vector<OrganismType> & a_population) 00203 { 00204 fitness_stats<OrganismType> stats(a_population); 00205 00206 // assign new fitness values 00207 for (int n = 0; n < a_population.size(); ++n) 00208 a_population[n].fitness = stats.getMin(); 00209 } 00210 }; 00211 00213 00218 template <class OrganismType> 00219 class exponential_scaler : public scaler<OrganismType> 00220 { 00221 public: 00223 00230 exponential_scaler(double a_a = 1.0, double a_b = 1.0, double a_power = 2.0) 00231 : m_a(a_a), 00232 m_b(a_b), 00233 m_power(a_power) 00234 { 00235 // nada 00236 } 00237 00239 00243 virtual void scale_fitness(vector<OrganismType> & a_population) 00244 { 00245 // assign new fitness values 00246 for (int n = 0; n < a_population.size(); ++n) 00247 a_population[n].fitness = pow((m_a * a_population[n].fitness + m_b),m_power); 00248 } 00249 00250 private: 00251 double m_a; 00252 double m_b; 00253 double m_power; 00254 }; 00255 00257 00261 template <class OrganismType> 00262 class quadratic_scaler : public scaler<OrganismType> 00263 { 00264 public: 00266 00269 quadratic_scaler(double a_a, double a_b, double a_c) 00270 : m_a(a_a), m_b(a_b), m_c(a_c) 00271 { 00272 // nada 00273 } 00274 00276 00280 virtual void scale_fitness(vector<OrganismType> & a_population) 00281 { 00282 // adjust fitness values 00283 for (int n = 0; n < a_population.size(); ++n) 00284 { 00285 double f = a_population[n].fitness; 00286 a_population[n].fitness = m_a * pow(f,2.0) + m_b * f + m_c; 00287 } 00288 } 00289 00290 private: 00291 double m_a; 00292 double m_b; 00293 double m_c; 00294 }; 00295 00297 00301 template <class OrganismType> 00302 class sigma_scaler : public scaler<OrganismType> 00303 { 00304 public: 00306 00309 sigma_scaler() 00310 { 00311 } 00312 00314 00321 virtual void scale_fitness(vector<OrganismType> & a_population) 00322 { 00323 fitness_stats<OrganismType> stats(a_population); 00324 00325 // calculate 2 times the std. deviation (sigma) 00326 double sigma2 = 2.0 * stats.getSigma(); 00327 00328 // now assign new fitness values 00329 if (sigma2 == 0.0) 00330 { 00331 for (int n = 0; n < a_population.size(); ++n) 00332 a_population[n].fitness = 1.0; 00333 } 00334 else 00335 { 00336 for (int n = 0; n < a_population.size(); ++n) 00337 { 00338 // change fitness 00339 a_population[n].fitness = (1.0 + a_population[n].fitness / stats.mean) / sigma2; 00340 00341 // avoid tiny or zero fitness value; everyone gets to reproduce 00342 if (a_population[n].fitness < 0.1) 00343 a_population[n].fitness = 0.1; 00344 } 00345 } 00346 } 00347 }; 00348 00349 }; 00350 00351 #endif
© 1996-2005 Scott Robert Ladd. All rights reserved.
HTML documentation generated by Dimitri van Heesch's excellent Doxygen tool.