Samchon Framework for CPP  1.0.0
GeneticAlgorithm.hpp
1 #pragma once
2 
3 #include <samchon/library/GAPopulation.hpp>
4 
5 #include <set>
6 #include <random>
7 #include <samchon/library/Math.hpp>
8 
9 namespace samchon
10 {
11 namespace library
12 {
59  template <typename GeneArray, typename Compare = std::less<GeneArray>>
61  {
62  public:
64 
65  protected:
69  bool unique;
70 
82  double mutationRate;
83 
87  size_t tournament;
88 
89  public:
97  GeneticAlgorithm(bool unique, double mutationRate = 0.015, size_t tournament = 10)
98  {
99  this->unique = unique;
100  this->mutationRate = mutationRate;
101  this->tournament = tournament;
102  };
103 
114  inline auto evolveGeneArray(std::shared_ptr<GeneArray> individual, size_t population, size_t generation) const -> std::shared_ptr<GeneArray>
115  {
116  std::shared_ptr<Population> myPopulation(new Population(individual, population));
117 
118  for (size_t i = 0; i < generation; i++)
119  myPopulation = evolvePopulation(myPopulation);
120 
121  return myPopulation->fitTest();
122  };
123 
129  auto evolvePopulation(std::shared_ptr<Population> population) const -> std::shared_ptr<Population>
130  {
131  size_t size = population->children.size();
132  std::shared_ptr<Population> evolved(new Population(size));
133 
134  //ELITICISM
135  evolved->children[0] = population->fitTest();
136 
137  #pragma omp parallel for
138  for (int i = 1; i < size; i++)
139  {
140  std::shared_ptr<GeneArray> &gene1 = selection(population);
141  std::shared_ptr<GeneArray> &gene2 = selection(population);
142 
143  std::shared_ptr<GeneArray> &child = crossover(gene1, gene2);
144  mutate(child);
145 
146  evolved->children[i] = child;
147  }
148 
149  /*#pragma omp parallel for
150  for (int i = 1; i < size; i++)
151  mutate(evolved->children[i]);*/
152 
153  return evolved;
154  };
155 
156  private:
187  auto selection(std::shared_ptr<Population> population) const -> std::shared_ptr<GeneArray>
188  {
189  size_t size = population->children.size();
190  Population tornament(size);
191 
192  for (size_t i = 0; i < size; i++)
193  {
194  size_t randomIndex = (size_t)(Math::random() * size);
195  if (randomIndex == size)
196  randomIndex--;
197 
198  tornament.children[i] = population->children[randomIndex];
199  }
200  return tornament.fitTest();
201  };
202 
219  auto crossover(std::shared_ptr<GeneArray> &parent1, std::shared_ptr<GeneArray> &parent2) const -> std::shared_ptr<GeneArray>
220  {
221  std::shared_ptr<GeneArray> individual(new GeneArray(*parent1));
222  size_t size = parent1->size();
223 
224  if (unique == false)
225  {
226  for (size_t i = 0; i < size; i++)
227  if (Math::random() > .5)
228  individual->at(i) = parent2->at(i);
229  }
230  else
231  {
232  std::set<GeneArray::value_type> ptrSet;
233  std::set<size_t> indexSet;
234 
235  // RANGES
236  size_t start = (size_t)(Math::random() * size);
237  size_t end = (size_t)(Math::random() * size);
238 
239  if (start > end)
240  std::swap(start, end);
241 
242  //INDEXING
243  for (size_t i = 0; i < size; i++)
244  if (start <= i && i < end)
245  ptrSet.insert(parent1->at(i));
246  else
247  indexSet.insert(i);
248 
249  //INSERT PARENT_2
250  for (size_t i = 0; i < size; i++)
251  {
252  GeneArray::value_type &ptr = parent2->at(i);
253  if (ptrSet.find(ptr) != ptrSet.end())
254  continue;
255 
256  individual->at(*indexSet.begin()) = ptr;
257  indexSet.erase(indexSet.begin());
258  }
259  }
260  return individual;
261  };
262 
263  protected:
294  virtual void mutate(std::shared_ptr<GeneArray> individual) const
295  {
296  for (size_t i = 0; i < individual->size(); i++)
297  {
298  if (Math::random() > mutationRate)
299  continue;
300 
301  // JUST SHUFFLE SEQUENCE OF GENES
302  size_t j = (size_t)(Math::random() * individual->size());
303  std::swap(individual->at(i), individual->at(j));
304  }
305  };
306  };
307 };
308 };
GeneticAlgorithm(bool unique, double mutationRate=0.015, size_t tournament=10)
Construct from parameters of Genetic Algorithm.
auto selection(std::shared_ptr< Population > population) const -> std::shared_ptr< GeneArray >
Select the best GeneArray in population from tournament.
auto fitTest() const -> std::shared_ptr< GeneArray >
Test fitness of each GeneArray in the population.
size_t tournament
Size of tournament in selection.
A population in a generation in G.A.
auto evolvePopulation(std::shared_ptr< Population > population) const -> std::shared_ptr< Population >
Evolve population, a mass of GeneArray(es)
A genetic algorithm class.
auto crossover(std::shared_ptr< GeneArray > &parent1, std::shared_ptr< GeneArray > &parent2) const -> std::shared_ptr< GeneArray >
Create a new GeneArray by crossing over two GeneArray(s)
auto evolveGeneArray(std::shared_ptr< GeneArray > individual, size_t population, size_t generation) const -> std::shared_ptr< GeneArray >
Evolve a GeneArray.
double mutationRate
Rate of mutate ocurrence.
bool unique
Whether each element (Gene) is unique in their GeneArray.
virtual void mutate(std::shared_ptr< GeneArray > individual) const
Cause a mutation on the GeneArray.
std::vector< std::shared_ptr< GeneArray > > children
Genes representing the population.
static auto random() -> double
Get a random value.
Definition: Math.hpp:135