GENEIAL  0.2=/
 All Classes Pages
MultiValuePermutationCrossover.hpp
1 #pragma once
2 
3 #include <geneial/core/operations/crossover/MultiValuePermutationCrossover.h>
4 #include <geneial/utility/Random.h>
5 
6 geneial_private_namespace(geneial)
7 {
8 geneial_private_namespace(operation)
9 {
10 geneial_private_namespace(crossover)
11 {
12 using ::geneial::population::Population;
13 using ::geneial::population::chromosome::MultiValueChromosome;
14 using ::geneial::operation::coupling::BaseCouplingOperation;
15 using ::geneial::utility::Random;
16 
17 enum COPY_MODE
18 {
19  COPY_LEFT_PART,
20  COPY_RIGHT_PART
21 };
22 
23 template<typename VALUE_TYPE, typename FITNESS_TYPE>
24 void copyContainerPart(const typename MultiValueChromosome<VALUE_TYPE, FITNESS_TYPE>::value_container& source,
25  typename MultiValueChromosome<VALUE_TYPE, FITNESS_TYPE>::value_container& dest,
26  COPY_MODE mode,
27  const unsigned int separator
28 )
29 {
30  assert(separator < source.size());
31  assert(separator >= 0);
32  assert(separator < dest.size());
33 
34  if(mode == COPY_MODE::COPY_LEFT_PART)
35  {
36  std::copy(source.begin() , source.begin() + separator + 1, dest.begin());
37  }
38  else //RIGHT PART
39  {
40  std::copy(source.begin() + separator , source.end(), dest.begin() + separator);
41  }
42 }
43 
44 template<typename VALUE_TYPE, typename FITNESS_TYPE>
45 void copyRemainder(const typename MultiValueChromosome<VALUE_TYPE, FITNESS_TYPE>::value_container& source,
46  typename MultiValueChromosome<VALUE_TYPE, FITNESS_TYPE>::value_container& dest,
47  COPY_MODE alreadyCopied,
48  const unsigned int separator)
49 {
50  if(alreadyCopied == COPY_MODE::COPY_LEFT_PART)
51  {
52  //We need to copy everything to begin() --> end() from source
53  //Values already present are in begin() --> begin() + separator of dest
54  unsigned int nextSourcePos = 0;
55  for(unsigned int nextCopyPos = separator + 1; nextCopyPos < dest.size(); nextCopyPos ++)
56  {
57  //Find a value that we can copy.
58  for(; nextSourcePos < source.size();nextSourcePos++)
59  {
60  //Do we have this value already?
61  if(std::find( dest.begin(), dest.begin() + nextCopyPos, source[nextSourcePos]) != dest.begin() + nextCopyPos)
62  {
63  continue;
64  }
65  else
66  {
67  break;
68  }
69  }
70  dest[nextCopyPos] = source[nextSourcePos];
71  nextSourcePos++;
72  }
73  }
74  else // Right Part was copied
75  {
76  //We need to copy everything to begin() --> end() from source what is not contained in dest
77  //Values already present are in begin() + separator --> end() separator of dest
78  unsigned int nextSourcePos = 0;
79  for(int nextCopyPos = separator -1 ; nextCopyPos >= 0; nextCopyPos --)
80  {
81  //Find a value that we can copy.
82  for(; nextSourcePos < source.size();nextSourcePos++)
83  {
84  //Do we have this value already?
85  if(std::find( dest.begin()+nextCopyPos + 1, dest.end(), source[nextSourcePos]) != dest.end())
86  {
87  continue;
88  }
89  else
90  {
91  break;
92  }
93  }
94  dest[nextCopyPos] = source[nextSourcePos];
95  nextSourcePos++;
96  }
97  }
98 }
99 
100 geneial_export_namespace
101 {
102 
103 template<typename VALUE_TYPE, typename FITNESS_TYPE>
104 typename BaseCrossoverOperation<FITNESS_TYPE>::crossover_result_set MultiValuePermutationCrossover<VALUE_TYPE,
105  FITNESS_TYPE>::doMultiValueCrossover(
106  const typename MultiValueChromosome<VALUE_TYPE, FITNESS_TYPE>::const_ptr &mommy,
107  const typename MultiValueChromosome<VALUE_TYPE, FITNESS_TYPE>::const_ptr &daddy) const
108 {
109 
110  typename BaseCouplingOperation<FITNESS_TYPE>::offspring_result_set resultset;
111 
112  auto child_candidate = this->createChildCandidate();
113 
114  const auto &daddy_container = daddy->getContainer();
115  const auto &mommy_container = mommy->getContainer();
116 
117  auto &child_container = child_candidate->getContainer();
118 
119  assert(daddy_container.size() == mommy_container.size());
120 
121  COPY_MODE copyMode = Random::generateBit() ? COPY_MODE::COPY_LEFT_PART : COPY_MODE::COPY_RIGHT_PART;
122  auto startWithMommy = Random::generateBit();
123  const unsigned int where = Random::generate<int>(0, daddy_container.size() -1 );
124 
125  child_container.resize(daddy_container.size(),0);
126 
127 
128  copyContainerPart<VALUE_TYPE,FITNESS_TYPE>(startWithMommy?mommy_container:daddy_container, child_container, copyMode, where);
129  copyRemainder<VALUE_TYPE,FITNESS_TYPE>(startWithMommy?daddy_container:mommy_container, child_container, copyMode, where);
130 
131  //Now some parts of the container have elements of mommy/daddy.
132  //Next we need to fill up the gap with
133 
134 
135  resultset.emplace_back(std::move(child_candidate));
136  return std::move(resultset);
137 }
138 
139 } /* geneial_export_namespace */
140 } /* private namespace crossover */
141 } /* private namespace operation */
142 } /* private namespace geneial */