GeneticAlgoithm
Implementation of the genetic algorithm
IPopulation.cxx
1 #include "IPopulation.h"
2 
3 #include "IModel.h"
4 #include "IFigureOfMerit.h"
5 
6 #include <stdexcept>
7 #include <sstream>
8 #include <iostream>
9 
11 {
12  m_sorted = false;
13  m_fom = 0;
14  m_random = new TRandom3(1234);
15  m_mutateRate = 0.01;
16  m_scoreMean = 0;
17  m_scoreRMS = 0;
18 }
19 
21 {
22  delete m_random;
23 }
24 
25 /**
26  * @param n Desired size of the population.
27  */
29 {
30  doInitialize(n);
31  m_sorted = false;
32 }
33 
35 {
36 
37  sort();
38 
39  m_parents.resize(size());
40  for(int i=0; i<size(); i++) {
41  if(i==0) {
42  m_parents[i].resize(1);
43  m_parents[i][0] = m_individuals[0];
44  }else{
45  int p1, p2;
46  selectParents(p1, p2);
47  m_parents[i].resize(2);
48  m_parents[i][0] = m_individuals[p1];
49  m_parents[i][1] = m_individuals[p2];
50  }
51  }
53  m_sorted = false;
54 }
55 
57 {
58  for(int i=0; i<size(); i++) {
59  double f = m_random->Uniform(0,1);
60  if(f < m_mutateRate) {
62  }
63  }
64  m_sorted = false;
65 }
66 
67 /**
68  * @param seed Random number generator seed.
69  */
71 {
72 
73  m_random->SetSeed(seed);
74 }
75 
76 /**
77  * @param rate Desired mutation rate.
78  */
79 void IPopulation::setMutateRate(double rate)
80 {
81 
82  if(rate<0 || rate > 1) {
83  std::ostringstream ostr;
84  ostr << "Specified rate (" << rate << ") is out of range [0,1]";
85  throw std::runtime_error(ostr.str().c_str());
86  }
87  m_mutateRate = rate;
88 }
89 
90 /**
91  * This function also calculates the mean and RMS for the scores of this population.
92  */
94 
96 
97  if(!size()) return;
98 
99  m_scoreMean = 0;
100  m_scoreRMS = 0;
101 
102  for(int i=0; i<size(); i++) {
103  double score = m_fom->evaluate(m_individuals[i]);
104  m_individuals[i]->setScore(score);
105  m_scoreMean += score;
106  m_scoreRMS += score*score;
107  }
108  m_scoreMean /= size();
109  m_scoreRMS /= size();
111  if(m_scoreRMS<0) m_scoreRMS = 0;
112  m_scoreRMS = sqrt(m_scoreRMS);
113 
114  sort();
115 }
116 
117 /**
118  * @param fom Pointer to a figure of merit object to be used to calculate scores and perform the ranking.
119  */
121 {
122  m_fom = fom;
123 }
124 
125 /**
126  * @return Pointer to the figure of merit object used to calculate scores and perform the ranking.
127  */
129 {
130  return m_fom;
131 }
132 
133 /**
134  * @param rank Rank.
135  * @return Model at the given rank.
136  */
138 {
139 
140  if(rank < 0 || rank >= size()) {
141  std::ostringstream ostr;
142  ostr << "Rank (" << rank << ") is out of range [" << 0 << ", " << size() << "[";
143  throw std::runtime_error(ostr.str().c_str());
144  }
145 
146  sort();
147 
148  return m_individuals[rank];
149 }
150 
151 /**
152  * @return Size of this population.
153  */
155 {
156  return m_individuals.size();
157 }
158 
159 /**
160  * @return Mean score for this population.
161  */
163 {
164  return m_scoreMean;
165 }
166 
167 /**
168  * @return RMS of the scores for this population.
169  */
171 {
172  return m_scoreRMS;
173 }
174 
176 {
177  for(int i=0; i<size(); i++) {
178  delete m_individuals[i];
179  }
180  m_individuals.clear();
181 }
182 
184 {
185  if(m_sorted) return;
186 
188 
189  m_sorted = true;
190 
191  if(size() <= 1) return;
192 
193  int n = size();
194  while (n > 0) {
195  int newn = 0;
196  for (int i = 1; i<=n-1; i++) {
197  if ( m_fom->isBetterThan(m_individuals[i], m_individuals[i-1]) ) {
198  IModel *temp = m_individuals[i];
199  m_individuals[i] = m_individuals[i-1];
200  m_individuals[i-1] = temp;
201  newn = i;
202  }
203  }
204  n = newn;
205  }
206 }
207 
208 
210 {
211 
212  if(!m_fom) {
213  throw std::runtime_error("Figure of merit not assigned for this population.");
214  }
215 }
216 
217 /**
218  * @param p1 Returns the index of the first parent.
219  * @param p2 Returns the index of the second parent.
220  */
221 void IPopulation::selectParents(int &p1, int &p2)
222 {
223 
224  int f1 = 0;
225  int f2 = 0;
226  do {
227  f1 = m_random->Integer(size());
228  p1 = m_random->Integer(size());
229  }while(p1 > f1);
230  do{
231  f2 = m_random->Integer(size());
232  p2 = m_random->Integer(size());
233  }
234  while(p1 == p2 || p2 > f2);
235 }
TRandom3 * m_random
Stores a random number generator.
Definition: IPopulation.h:100
double m_scoreMean
Stores the mean score for the population.
Definition: IPopulation.h:101
virtual double evaluate(IModel *model) const =0
Evaluate the fittness of a model.
IModel * getBestFitted(int rank=0)
virtual void selectParents(int &p1, int &p2)
virtual bool isBetterThan(IModel *scoreToTest, IModel *referenceModel) const
void initialize(int n)
Definition: IPopulation.cxx:28
void setMutateRate(double rate)
Definition: IPopulation.cxx:79
void setFigureOfMerit(IFigureOfMerit *fom)
double getScoreMean()
IFigureOfMerit * getFigureOfMerit()
void mutate()
Definition: IPopulation.cxx:56
bool m_sorted
Stores whether the ranking is valid or needs to be redone.
Definition: IPopulation.h:97
double m_mutateRate
Stores the mutate rate.
Definition: IPopulation.h:96
virtual ~IPopulation()
Definition: IPopulation.cxx:20
std::vector< std::vector< IModel * > > m_parents
Stores the list of parents about to be crossed-over.
Definition: IPopulation.h:103
Abstract class representing a figure of merit.
void checkFigureOfMerit()
void score()
Definition: IPopulation.cxx:93
void crossOver()
Definition: IPopulation.cxx:34
virtual void doMutate(IModel *model)=0
IFigureOfMerit * m_fom
Stores the figure of merit to be used to calculate scores and perform the ranking.
Definition: IPopulation.h:99
void setRandomSeed(int seed)
Definition: IPopulation.cxx:70
std::vector< IModel * > m_individuals
Stores the individuals of this population.
Definition: IPopulation.h:98
virtual void doInitialize(int n)=0
virtual void doCrossOver(const std::vector< std::vector< IModel *> > &parents)=0
Abstract class describing the interface for a model.
Definition: IModel.h:13
double getScoreRMS()
double m_scoreRMS
Stores the score RMS for the population.
Definition: IPopulation.h:102