Modernized GAlib  3.0.0 current
GAPopulation.h
1 // $Header$
2 /* ----------------------------------------------------------------------------
3  population.h
4  mbwall 3aug94
5  Copyright (c) 1995 Massachusetts Institute of Technology
6  all rights reserved
7 
8  DESCRIPTION:
9  The population holds an array of pointers to genomes. It also keeps
10 track of the fitness statistics for the genomes in the population.
11 ---------------------------------------------------------------------------- */
12 #ifndef _ga_population_h_
13 #define _ga_population_h_
14 
15 #include <GAEvalData.h>
16 #include <GAGenome.h>
17 #include <GAScaling.h>
18 #include <GASelector.h>
19 #include <gaconfig.h>
20 #include <gaid.h>
21 
22 #ifdef max
23 #undef max
24 #endif
25 
26 #ifdef min
27 #undef min
28 #endif
29 
30 /* ----------------------------------------------------------------------------
31 size
32  Use the size member function to get and set the size of the population. The
33 population allocates space for genomes in chunks, so you can vary the
34 chunksize as well if you are really tight for space. The compact member
35 function will remove all extra pointers. If you shrink the population to 0
36 then you cannot use the 'size' method to make the population bigger. When
37 resizing to a larger size, we clone randomly individuals from the existing
38 population.
39 
40 sort
41  The sort member is defined so that it can work on a const population. It
42 does not change the logical state of the population, but it does change its
43 physical state. We sort from best (0th individual) to worst (n-1). The sort
44 figures out whether high is best or low is best.
45 
46 evaluate
47  If you want to force an evaluation, pass true to the evaluate member
48 function. Otherwise the population will use its internal state to determine
49 whether or not it needs to do the evaluation.
50 
51 initialize
52  This method determines how the population should be initialized. The
53 default is to call the initializer for each genome.
54 
55 statistics
56  Update the statistics. We do this only on-demand so that no unneeded
57 calculations take place.
58 
59 diversity
60  Like the statistics function, we call this one only on demand. This member
61 function can be particularly expensive, especially for large populations. So
62 we store the values and update them only as needed. The population diversity
63 measure is the average of the individual measures (less the diagonal scores).
64 ---------------------------------------------------------------------------- */
65 class GAPopulation : public GAID
66 {
67  public:
68  GADefineIdentity("GAPopulation", GAID::Population);
69 
70  using Initializer = void (*)(GAPopulation &);
71  using Evaluator = void (*)(GAPopulation &);
72 
73  static void DefaultInitializer(GAPopulation &);
74  static void DefaultEvaluator(GAPopulation &);
75 
76  public:
77  enum SortBasis
78  {
79  RAW,
80  SCALED
81  };
82  enum SortOrder
83  {
84  LOW_IS_BEST,
85  HIGH_IS_BEST
86  };
87  enum Replacement
88  {
89  BEST = -1,
90  WORST = -2,
91  RANDOM = -3
92  };
93 
94  public:
95  GAPopulation();
96  explicit GAPopulation(const GAGenome &c, unsigned int psize = 1);
97  GAPopulation(const GAPopulation &arg);
98  GAPopulation &operator=(const GAPopulation &arg)
99  {
100  copy(arg);
101  return (*this);
102  }
103  ~GAPopulation() override;
104  virtual GAPopulation *clone() const { return new GAPopulation(*this); }
105  virtual void copy(const GAPopulation &arg);
106 
107  int size() const { return n; }
108  int size(unsigned int popsize);
109  int chunksize() const { return csz; }
110  int chunksize(unsigned int csize) { return csz = csize; }
111  int compact();
112 
113  void touch()
114  {
115  rsorted = ssorted = selectready = divved = statted = scaled =
116  evaluated = false;
117  }
118  void statistics(bool flag = false) const;
119  void diversity(bool flag = false) const;
120  void scale(bool flag = false) const;
121  void prepselect(bool flag = false) const;
122  void sort(bool flag = false, SortBasis basis = RAW) const;
123 
124  float sum() const
125  {
126  if (!statted)
127  {
128  statistics();
129  }
130  return rawSum;
131  }
132  float ave() const
133  {
134  if (!statted)
135  {
136  statistics();
137  }
138  return rawAve;
139  }
140  float var() const
141  {
142  if (!statted)
143  {
144  statistics();
145  }
146  return rawVar;
147  }
148  float dev() const
149  {
150  if (!statted)
151  {
152  statistics();
153  }
154  return rawDev;
155  }
156  float max() const
157  {
158  if (!statted)
159  {
160  statistics();
161  }
162  return rawMax;
163  }
164  float min() const
165  {
166  if (!statted)
167  {
168  statistics();
169  }
170  return rawMin;
171  }
172  float div() const
173  {
174  if (!divved)
175  {
176  diversity();
177  }
178  return popDiv;
179  }
180  float div(unsigned int i, unsigned int j) const
181  {
182  if (!divved)
183  {
184  diversity();
185  }
186  return indDiv[i * n + j];
187  }
188  float fitsum() const
189  {
190  if (!scaled)
191  {
192  scale();
193  }
194  return fitSum;
195  }
196  float fitave() const
197  {
198  if (!scaled)
199  {
200  scale();
201  }
202  return fitAve;
203  }
204  float fitmax() const
205  {
206  if (!scaled)
207  {
208  scale();
209  }
210  return fitMax;
211  }
212  float fitmin() const
213  {
214  if (!scaled)
215  {
216  scale();
217  }
218  return fitMin;
219  }
220  float fitvar() const
221  {
222  if (!scaled)
223  {
224  scale();
225  }
226  return fitVar;
227  }
228  float fitdev() const
229  {
230  if (!scaled)
231  {
232  scale();
233  }
234  return fitDev;
235  }
236 
237  int nevals() const { return neval; }
238  void evaluate(bool flag = false)
239  {
240  if (evaluated == false || flag == true)
241  {
242  (*eval)(*this);
243  neval++;
244  scaled = statted = divved = rsorted = ssorted = false;
245  }
246  evaluated = true;
247  }
248  Evaluator evaluator() const { return eval; }
249  Evaluator evaluator(Evaluator e)
250  {
251  evaluated = false;
252  return eval = e;
253  }
254  void initialize()
255  {
256  neval = 0;
257  (*init)(*this);
258  touch();
259  }
260  Initializer initializer() const { return init; }
261  Initializer initializer(Initializer i) { return init = i; }
262  SortOrder order() const { return sortorder; }
263  SortOrder order(SortOrder flag);
264  GAGenome &select()
265  {
266  if (!selectready)
267  {
268  prepselect();
269  }
270  return slct->select();
271  }
272  GASelectionScheme &selector() const { return *slct; }
273  GASelectionScheme &selector(const GASelectionScheme &);
274  GAScalingScheme &scaling() const
275  {
276  auto *This = const_cast<GAPopulation *>(this);
277  This->scaled = false;
278  return *sclscm;
279  }
280  GAScalingScheme &scaling(const GAScalingScheme &);
281 
282  GAGeneticAlgorithm *geneticAlgorithm() const { return ga; }
283  GAGeneticAlgorithm *geneticAlgorithm(GAGeneticAlgorithm &);
284  void *userData() const { return ud; }
285  void *userData(void *u) { return (ud = u); }
286  GAEvalData *evalData() const { return evaldata; }
287  GAEvalData *evalData(const GAEvalData &o)
288  {
289  delete evaldata;
290  evaldata = o.clone();
291  return evaldata;
292  }
293 
294  GAGenome &best(unsigned int i = 0, SortBasis basis = RAW) const
295  {
296  if (basis == SCALED)
297  {
298  scale();
299  }
300  sort(false, basis);
301  return ((basis == RAW) ? *(rind[i]) : *(sind[i]));
302  }
303  GAGenome &worst(unsigned int i = 0, SortBasis basis = RAW) const
304  {
305  if (basis == SCALED)
306  {
307  scale();
308  }
309  sort(false, basis);
310  return ((basis == RAW) ? *(rind[n - 1 - i]) : *(sind[n - 1 - i]));
311  }
312  GAGenome &individual(unsigned int i, SortBasis basis = RAW) const
313  {
314  return ((basis == RAW) ? *(rind[i]) : *(sind[i]));
315  }
316 
317  GAGenome *add(GAGenome *);
318  GAGenome *add(const GAGenome &);
319  GAGenome *remove(int which = WORST, SortBasis basis = RAW);
320  GAGenome *remove(GAGenome *);
321  GAGenome *replace(GAGenome *, int which = RANDOM, SortBasis basis = RAW);
322  GAGenome *replace(GAGenome *newgenome, GAGenome *oldgenome);
323  void destroy(int w = WORST, SortBasis b = RAW) { delete remove(w, b); }
324 
325  virtual void read(std::istream &) {}
326  virtual void write(std::ostream &os, SortBasis basis = RAW) const;
327 
328  protected:
329  unsigned int neval; // number of evals since initialization
330  unsigned int csz; // how big are chunks we allocate?
331  unsigned int n, N; // how many are in the population, allocated
332  SortOrder sortorder; // is best a high score or a low score?
333  bool rsorted; // are the individuals sorted? (raw)
334  bool ssorted; // are the individuals sorted? (scaled)
335  bool scaled; // has the population been scaled?
336  bool statted; // are the stats valid?
337  bool evaluated; // has the population been evaluated?
338  bool divved; // has the population diversity been measured?
339  bool selectready; // has the selector been updated?
340  float rawSum, rawAve; // sum, ave of the population's objectives
341  float rawMax, rawMin; // max, min of the population's objectives
342  float rawVar, rawDev; // variance, standard deviation
343  float popDiv; // overall population diversity [0,)
344  float *indDiv; // table for genome similarities (diversity)
345  GAGenome **rind; // the individuals of the population (raw)
346  GAGenome **sind; // the individuals of the population (scaled)
347  float fitSum, fitAve; // sum, ave of the population's fitness scores
348  float fitMax, fitMin; // max, min of the population's fitness scores
349  float fitVar, fitDev; // variance, standard deviation of fitness
350  GAScalingScheme *sclscm; // scaling method
351  GASelectionScheme *slct; // selection method
352  Initializer init; // initialization method
353  Evaluator eval; // population evaluation method
354  void *ud; // pointer to user data
355  GAGeneticAlgorithm *ga; // the ga that is using this population
356  GAEvalData *evaldata; // data for evaluator to use (optional)
357 
358  int grow(unsigned int);
359 
360  static void QuickSortAscendingRaw(GAGenome **, int, int);
361  static void QuickSortDescendingRaw(GAGenome **, int, int);
362  static void QuickSortAscendingScaled(GAGenome **, int, int);
363  static void QuickSortDescendingScaled(GAGenome **, int, int);
364 };
365 
366 inline std::ostream &operator<<(std::ostream &os, const GAPopulation &arg)
367 {
368  arg.write(os);
369  return os;
370 }
371 inline std::istream &operator>>(std::istream &is, GAPopulation &arg)
372 {
373  arg.read(is);
374  return is;
375 }
376 
377 #endif
This is the basic interface for the object that contains evaluation data.
Definition: GAEvalData.h:15
The base GA class is virtual - it defines the core data elements and parts of the interface that are ...
Definition: GABaseGA.h:89
The base genome class just defines the genome interface - how to mutate, crossover,...
Definition: GAGenome.h:200
This defines the identifiers for polymorphic classes.
Definition: gaid.h:20
Definition: GAPopulation.h:66
Definition: GAScaling.h:46
Definition: GASelector.h:55