Evocosm - A C++ Framework for Evolutionary Computing

Main Index

Created by Scott Robert Ladd at Coyote Gulch Productions.


scaler.h
1 //---------------------------------------------------------------------
2 // Algorithmic Conjurings @ http://www.coyotegulch.com
3 // Evocosm -- An Object-Oriented Framework for Evolutionary Algorithms
4 //
5 // scaler.h
6 //---------------------------------------------------------------------
7 //
8 // Copyright 1996, 1999, 2002, 2003, 2004, 2005, 2007 Scott Robert Ladd
9 //
10 // This program is free software; you can redistribute it and/or modify
11 // it under the terms of the GNU General Public License as published by
12 // the Free Software Foundation; either version 2 of the License, or
13 // (at your option) any later version.
14 //
15 // This program is distributed in the hope that it will be useful,
16 // but WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 // GNU General Public License for more details.
19 //
20 // You should have received a copy of the GNU General Public License
21 // along with this program; if not, write to the
22 // Free Software Foundation, Inc.
23 // 59 Temple Place - Suite 330
24 // Boston, MA 02111-1307, USA.
25 //
26 //-----------------------------------------------------------------------
27 //
28 // For more information on this software package, please visit
29 // Scott's web site, Coyote Gulch Productions, at:
30 //
31 // http://www.coyotegulch.com
32 //
33 //-----------------------------------------------------------------------
34 
35 #if !defined(LIBEVOCOSM_SCALER_H)
36 #define LIBEVOCOSM_SCALER_H
37 
38 // Standard C Library
39 #include <cmath>
40 
41 // Standard C++
42 #include <limits>
43 #include <algorithm>
44 
45 // libevocosm
46 #include "organism.h"
47 
48 namespace libevocosm
49 {
51 
59  template <class OrganismType>
60  class scaler : protected globals
61  {
62  public:
64 
71  virtual ~scaler()
72  {
73  // nada
74  }
75 
77 
83  virtual void scale_fitness(vector<OrganismType> & a_population) = 0;
84 
86 
89  void invert(vector<OrganismType> & a_population)
90  {
91  double base = min_element(a_population.begin(), a_population.end())->fitness()
92  + max_element(a_population.begin(), a_population.end())->fitness();
93 
94  for (typename vector<OrganismType>::iterator organism = a_population.begin(); organism != a_population.end(); ++organism)
95  organism->fitness() = base - organism->fitness();
96  }
97  };
98 
100 
105  template <class OrganismType>
106  class null_scaler : public scaler<OrganismType>
107  {
108  public:
110 
114  virtual void scale_fitness(vector<OrganismType> & a_population)
115  {
116  // nada
117  }
118  };
119 
121 
126  template <class OrganismType>
127  class linear_norm_scaler : public scaler<OrganismType>
128  {
129  public:
131 
134  linear_norm_scaler(double a_fitness_multiple = 2.0)
135  : m_fitness_multiple(a_fitness_multiple)
136  {
137  // nada
138  }
139 
141 
145  virtual void scale_fitness(vector<OrganismType> & a_population)
146  {
147  // calculate max, average, and minimum fitness for the population
148  double max_fitness = std::numeric_limits<double>::min();
149  double min_fitness = std::numeric_limits<double>::max();
150  double avg_fitness = 0.0;
151 
152  for (typename vector<OrganismType>::iterator org = a_population.begin(); org != a_population.end(); ++org)
153  {
154  // do we have a new maximum?
155  if (org->fitness() > max_fitness)
156  max_fitness = org->fitness();
157 
158  // do we have a new minimum?
159  if (org->fitness() < min_fitness)
160  min_fitness = org->fitness();
161 
162  // accumulate for average
163  avg_fitness += org->fitness();
164  }
165 
166  avg_fitness /= double(a_population.size());
167 
168  // calculate coefficients for fitness scaling
169  double slope;
170  double intercept;
171  double delta;
172 
173  if (min_fitness > ((m_fitness_multiple * avg_fitness - max_fitness) / (m_fitness_multiple - 1.0)))
174  {
175  // normal scaling
176  delta = max_fitness - avg_fitness;
177  slope = (m_fitness_multiple - 1.0) * avg_fitness / delta;
178  intercept = avg_fitness * (max_fitness - m_fitness_multiple * avg_fitness) / delta;
179  }
180  else
181  {
182  // extreme scaling
183  delta = avg_fitness - min_fitness;
184  slope = avg_fitness / delta;
185  intercept = -min_fitness * avg_fitness / delta;
186  }
187 
188  // adjust fitness values
189  for (typename vector<OrganismType>::iterator org = a_population.begin(); org != a_population.end(); ++org)
190  org->fitness() = slope * org->fitness() + intercept;
191  }
192 
193  private:
194  double m_fitness_multiple;
195  };
196 
198 
203  template <class OrganismType>
204  class windowed_scaler : public scaler<OrganismType>
205  {
206  public:
208 
212  {
213  // nada
214  }
215 
217 
221  virtual void scale_fitness(vector<OrganismType> & a_population)
222  {
223  // Find minimum fitness
224  // Note that organisms sort in reverse order of fitness, such that
225  // the "maximum" value has the smallest fitness.
226  double min_fitness = min_element(a_population.begin(), a_population.end())->fitness();
227 
228  // assign new fitness values
229  for (typename vector<OrganismType>::iterator org = a_population.begin(); org != a_population.end(); ++org)
230  org->fitness() -= min_fitness;
231  }
232  };
233 
235 
240  template <class OrganismType>
241  class exponential_scaler : public scaler<OrganismType>
242  {
243  public:
245 
252  exponential_scaler(double a_a = 1.0, double a_b = 1.0, double a_power = 2.0)
253  : m_a(a_a),
254  m_b(a_b),
255  m_power(a_power)
256  {
257  // nada
258  }
259 
261 
265  virtual void scale_fitness(vector<OrganismType> & a_population)
266  {
267  // assign new fitness values
268  for (typename vector<OrganismType>::iterator org = a_population.begin(); org != a_population.end(); ++org)
269  org->fitness() = pow((m_a * org->fitness() + m_b),m_power);
270  }
271 
272  private:
273  double m_a;
274  double m_b;
275  double m_power;
276  };
277 
279 
283  template <class OrganismType>
284  class quadratic_scaler : public scaler<OrganismType>
285  {
286  public:
288 
291  quadratic_scaler(double a_a, double a_b, double a_c)
292  : m_a(a_a), m_b(a_b), m_c(a_c)
293  {
294  // nada
295  }
296 
298 
302  virtual void scale_fitness(vector<OrganismType> & a_population)
303  {
304  // adjust fitness values
305  for (typename vector<OrganismType>::iterator org = a_population.begin(); org != a_population.end(); ++org)
306  {
307  double f = org->fitness();
308  org->fitness() = m_a * pow(f,2.0) + m_b * f + m_c;
309  }
310  }
311 
312  private:
313  double m_a;
314  double m_b;
315  double m_c;
316  };
317 
319 
323  template <class OrganismType>
324  class sigma_scaler : public scaler<OrganismType>
325  {
326  public:
328 
332  {
333  }
334 
336 
343  virtual void scale_fitness(vector<OrganismType> & a_population)
344  {
345  // calculate the mean
346  double mean = 0.0;
347  for (typename vector<OrganismType>::iterator org = a_population.begin(); org != a_population.end(); ++org)
348  mean += org->fitness();
349 
350  mean /= static_cast<double>(a_population.size());
351 
352  // calculate variance
353  double variance = 0.0;
354  for (typename vector<OrganismType>::iterator org = a_population.begin(); org != a_population.end(); ++org)
355  {
356  double diff = org->fitness() - mean;
357  variance += (diff * diff);
358  }
359 
360  variance /= static_cast<double>(a_population.size() - 1);
361 
362  // calculate 2 times the std. deviation (sigma)
363  double sigma2 = 2.0 * sqrt(variance);
364 
365  // now assign new fitness values
366  if (sigma2 == 0.0)
367  {
368  for (typename vector<OrganismType>::iterator org = a_population.begin(); org != a_population.end(); ++org)
369  org->fitness() = 1.0;
370  }
371  else
372  {
373  for (typename vector<OrganismType>::iterator org = a_population.begin(); org != a_population.end(); ++org)
374  {
375  // change fitness
376  org->fitness() = (1.0 + org->fitness() / mean) / sigma2;
377 
378  // avoid tiny or zero fitness value; everyone gets to reproduce
379  if (org->fitness() < 0.1)
380  org->fitness() = 0.1;
381  }
382  }
383  }
384  };
385 
386 };
387 
388 #endif
A quadratic scaler.
Definition: scaler.h:284
virtual void scale_fitness(vector< OrganismType > &a_population)
Scaling function.
Definition: scaler.h:343
virtual ~scaler()
Virtual destructor.
Definition: scaler.h:71
An evolving organism.
Definition: organism.h:60
double & fitness()
Get fitness (read-write)
Definition: organism.h:179
virtual void scale_fitness(vector< OrganismType > &a_population)
Scaling function.
Definition: scaler.h:265
windowed_scaler()
Constructor.
Definition: scaler.h:211
linear_norm_scaler(double a_fitness_multiple=2.0)
Constructor.
Definition: scaler.h:134
quadratic_scaler(double a_a, double a_b, double a_c)
Constructor.
Definition: scaler.h:291
exponential_scaler(double a_a=1.0, double a_b=1.0, double a_power=2.0)
Constructor.
Definition: scaler.h:252
virtual void scale_fitness(vector< OrganismType > &a_population)
Scaling function.
Definition: scaler.h:302
Fitness scaling for a population.
Definition: scaler.h:60
virtual void scale_fitness(vector< OrganismType > &a_population)=0
Scale a population's fitness values.
sigma_scaler()
Constructor.
Definition: scaler.h:331
A toolkit and framework for implementing evolutionary algorithms.
Definition: evocommon.h:60
A linear normalization scaler.
Definition: scaler.h:127
virtual void scale_fitness(vector< OrganismType > &a_population)
Do-nothing scaling function.
Definition: scaler.h:114
virtual void scale_fitness(vector< OrganismType > &a_population)
Scaling function.
Definition: scaler.h:145
Elements shared by all classes in Evocosm.
Definition: evocommon.h:115
A sigma scaler.
Definition: scaler.h:324
An exponential fitness scaler.
Definition: scaler.h:241
virtual void scale_fitness(vector< OrganismType > &a_population)
Scaling function.
Definition: scaler.h:221
A do-nothing scaler.
Definition: scaler.h:106
void invert(vector< OrganismType > &a_population)
Invert a population's fitness values.
Definition: scaler.h:89
A windowed fitness scaler.
Definition: scaler.h:204

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