GENEIAL  0.2=/
 All Classes Pages
ValueSwapMutationOperation.hpp
1 #pragma once
2 
3 #include <geneial/core/operations/mutation/ValueSwapMutationOperation.h>
4 #include <geneial/core/population/builder/BuilderSettings.h>
5 #include <geneial/core/operations/mutation/BaseMutationOperation.h>
6 #include <geneial/core/operations/choosing/BaseChoosingOperation.h>
7 #include <geneial/core/operations/mutation/MultiValueMutationSettings.h>
8 #include <geneial/core/population/Population.h>
9 
10 #include <geneial/utility/mixins/Hasher.h>
11 
12 #include <unordered_set>
13 #include <iterator>
14 #include <algorithm>
15 
16 geneial_private_namespace(geneial)
17 {
18 geneial_private_namespace(operation)
19 {
20 geneial_private_namespace(mutation)
21 {
22 using ::geneial::population::chromosome::BaseChromosomeFactory;
23 using ::geneial::utility::Random;
24 using ::geneial::utility::PairHasher;
25 
26 geneial_export_namespace
27 {
28 /*
29  * Returns a chromosome container with some new chromosomes which are partially mutated versions of the old ones.
30  *
31  * This mutation swaps elements at random and is intended for permutation chromosomes
32  *
33  * Old Chrom. New Chrom.
34  * (1) (1)
35  * (2) <---\ (5)
36  * (3) | (3)
37  * (4) | Swap those Values (4)
38  * (5) <---/ (2)
39  * (6) (6)
40  * (7) (7)
41  *
42  **/
43 template<typename VALUE_TYPE, typename FITNESS_TYPE>
44 typename Population<FITNESS_TYPE>::chromosome_container ValueSwapMutationOperation<VALUE_TYPE, FITNESS_TYPE>::doMutate(
45  const typename Population<FITNESS_TYPE>::chromosome_container &chromosomeInputContainer,
46  BaseManager<FITNESS_TYPE> &manager) const
47 {
48 
49  typename Population<FITNESS_TYPE>::chromosome_container resultset;
50  typename Population<FITNESS_TYPE>::chromosome_container choosenChromosomeContainer;
51  typename Population<FITNESS_TYPE>::chromosome_container notChoosenChromosomeContainer;
52 
53  choosenChromosomeContainer = this->getChoosingOperation().doChoose(chromosomeInputContainer);
54 
55  for(auto it: chromosomeInputContainer)
56  {
57  auto result = std::find(std::begin(choosenChromosomeContainer), std::end(choosenChromosomeContainer), it);
58  if (result == std::end(choosenChromosomeContainer))
59  {
60  notChoosenChromosomeContainer.emplace_back(it);
61  }
62  }
63 
64 
65 
66  const auto maxNumMvc = this->getBuilderFactory().getSettings().getNum();
67 
68 
69  //only mutate choosen chromosomes
70  for (const auto& chromosome : choosenChromosomeContainer)
71  {
72  const auto slotsToMutate = Random::generate<unsigned int>(this->getSettings().getMinimumPointsToMutate(),this->getSettings().getMaximumPointsToMutate());
73  //casting mutant as MVC
74  auto mvcMutant = std::dynamic_pointer_cast<MultiValueChromosome<VALUE_TYPE, FITNESS_TYPE> >(
75  chromosome);
76  assert(mvcMutant);
77 
78  //creating a new MVC (to keep things reversible)
79  auto mutatedChromosome = std::dynamic_pointer_cast<MultiValueChromosome<VALUE_TYPE, FITNESS_TYPE> >(
80  this->getBuilderFactory().createChromosome(BaseChromosomeFactory<FITNESS_TYPE>::LET_UNPOPULATED));
81  assert(mutatedChromosome);
82 
83  //getting values
84  const auto &mutantChromosomeContainer = mvcMutant->getContainer();
85  auto &result_container = mutatedChromosome->getContainer();
86 
87  //copy values:
88  std::copy(mutantChromosomeContainer.begin(),mutantChromosomeContainer.end(),result_container.begin());
89 
90  //Predetermine Positions for Mutation:
91  std::unordered_set<std::pair<unsigned int,unsigned int>,PairHasher> positionsToSwap;
92  while (positionsToSwap.size() < slotsToMutate)
93  {
94  unsigned int swapA = Random::generate<unsigned int>(0,maxNumMvc - 1);
95  unsigned int swapB;
96  do{
97  swapB = Random::generate<unsigned int>(0, maxNumMvc - 1);
98  }while(swapA == swapB);
99  positionsToSwap.emplace(std::make_pair(swapA,swapB));
100  }
101 
102  for(const auto posPair : positionsToSwap)
103  {
104  auto iterBegin = result_container.begin();
105  iter_swap(iterBegin + posPair.first, iterBegin + posPair.second);
106  }
107 
108  //Age reset
109  mutatedChromosome->setAge(0);
110  resultset.emplace_back(mutatedChromosome);
111  }
112 
113  //add not mutated chromosomes
114  resultset.insert(resultset.end(), notChoosenChromosomeContainer.begin(), notChoosenChromosomeContainer.end());
115 
116  return resultset;
117 
118 }
119 
120 } /* geneial_export_namespace */
121 } /* private namespace mutation */
122 } /* private namespace operation */
123 } /* private namespace geneial */
124