GENEIAL  0.2=/
 All Classes Pages
ReplaceWorstOperation.hpp
1 #pragma once
2 
3 #include <geneial/core/operations/replacement/ReplaceWorstOperation.h>
4 #include <geneial/core/population/management/Bookkeeper.h>
5 
6 #include <algorithm>
7 #include <iterator>
8 #include <functional>
9 #include <tuple>
10 #include <utility>
11 
12 geneial_private_namespace(geneial)
13 {
14 geneial_private_namespace(operation)
15 {
16 geneial_private_namespace(replacement)
17 {
18 using ::geneial::population::Population;
19 using ::geneial::operation::coupling::BaseCouplingOperation;
20 using ::geneial::operation::selection::BaseSelectionOperation;
21 using ::geneial::population::management::EventValueData;
22 
23 geneial_export_namespace
24 {
25 
26 template<typename FITNESS_TYPE>
27 unsigned int ReplaceWorstOperation<FITNESS_TYPE>::getAmountToReplace(const Population<FITNESS_TYPE> &population,
28  const typename BaseCouplingOperation<FITNESS_TYPE>::offspring_result_set &offspring) const
29 {
30  switch (this->getSettings().getMode())
31  {
32 
33  case BaseReplacementSettings::REPLACE_ALL_OFFSPRING:
34  {
35  return std::min(population.getFitnessMap().size() - this->getSettings().getAmountElitism() - 1,
36  offspring.size());
37  }
38  break;
39 
40  case BaseReplacementSettings::REPLACE_FIXED_NUMBER: /*FALLTHROUGH*/
41  default:
42  {
43  return std::min(population.getFitnessMap().size() - 1,
44  (typename Population<FITNESS_TYPE>::fitness_map::size_type) this->getSettings().getAmountToReplace());
45  }
46  break;
47  }
48 }
49 
50 template<typename FITNESS_TYPE>
51 void ReplaceWorstOperation<FITNESS_TYPE>::doReplace(Population<FITNESS_TYPE> &population,
52  const typename BaseSelectionOperation<FITNESS_TYPE>::selection_result_set &parents,
53  typename BaseCouplingOperation<FITNESS_TYPE>::offspring_result_set &offspring,
54  BaseManager<FITNESS_TYPE> &manager) const
55 {
56  unsigned int numberToReplace = getAmountToReplace(population, offspring); //this also takes care of elitism!
57 
58  //Insert all the offspring, parents are ignored here (since they are assumed to be already in the population)
59 
60  //We'd rather insert the chromsomes all at one, so we can use multithreading for determining the fitness.
61  //However, first we need to check whehter we will have duplicates
62 
63  typename Population<FITNESS_TYPE>::chromosome_container newChildren;
64  newChildren.reserve(offspring.size());
65 
66  //std::cout << "Population"<< population.getSize() << " Amount To Replace: " << numberToReplace <<" Offspring:"<< offspring.size()<<std::endl;
67 
68  unsigned int childrenCandidates = 0;
69  for(const auto& newOffspring: offspring)
70  {
71  if(childrenCandidates <= numberToReplace)
72  {
73  if(!population.hashExists(newOffspring->getHash()))
74  {
75  newChildren.emplace_back(newOffspring);
76  childrenCandidates++;
77  }
78  }
79  else
80  {
81  break;
82  }
83  }
84 
85  const unsigned int failed_inserts = childrenCandidates - population.insertChromosomeContainer(newChildren);
86 
87  EventValueData<unsigned int>::create(*manager.getBookkeeper(),"REPLACEMENT_FAILED_INSERTS",failed_inserts);
88 
89  //we might have a deficit at this point if offsprings were already contained.
90 
91  //remove the worst chromosomes to replace (assuming worst is at the very beginning)
92  typename Population<FITNESS_TYPE>::fitnessmap_const_it advanced = population.getFitnessMap().cbegin();
93 
94  const unsigned int worstChromosomesToRemove = population.getSize() - manager.getPopulationSettings().getMaxChromosomes();
95  if(worstChromosomesToRemove != 0)
96  {
97  std::advance(advanced, worstChromosomesToRemove);
98 
99  typename Population<FITNESS_TYPE>::chromosome_container toRemove;
100  toRemove.reserve(numberToReplace);
101 
102  //insert the second component of the fitness map (the chromosome ptr) into toRemove
103  std::transform(
104  population.getFitnessMap().cbegin(),
105  advanced, std::back_inserter(toRemove),
106  [](decltype(*advanced)& p){ return p.second; }
107  );
108  population.removeChromosomeContainer(toRemove);
109  }
110  else
111  {
112  manager.getBookkeeper()->traceEvent("REPLACEMENT_NO_WORST_DELETED");
113  }
114 
115 }
116 
117 } /* geneial_export_namespace */
118 } /* private namespace replacement */
119 } /* private namespace operation */
120 } /* private namespace geneial */
121