Evocosm - A C++ Framework for Evolutionary Computing

Main Index

Created by Scott Robert Ladd at Coyote Gulch Productions.


scaler.h

00001 /*
00002     Evocosm is a heterogenous collection of mathematical tools,  written in Standard C.
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

© 2011 Scott Robert Ladd. All rights reserved.
HTML documentation generated by Dimitri van Heesch's excellent Doxygen tool.