GENEIAL  0.2=/
 All Classes Pages
MultiValueChromosomeBlendingCrossover.hpp
1 #pragma once
2 
3 #include <geneial/core/operations/crossover/MultiValueChromosomeBlendingCrossover.h>
4 #include <geneial/core/operations/crossover/BaseCrossoverOperation.h>
5 #include <geneial/utility/Random.h>
6 
7 geneial_private_namespace(geneial)
8 {
9 geneial_private_namespace(operation)
10 {
11 geneial_private_namespace(crossover)
12 {
13 using ::geneial::population::Population;
14 using ::geneial::population::chromosome::MultiValueChromosome;
15 using ::geneial::operation::coupling::BaseCouplingOperation;
16 
17 geneial_export_namespace
18 {
19 using namespace geneial::utility;
20 
21 template<typename VALUE_TYPE, typename FITNESS_TYPE>
22 typename BaseCrossoverOperation<FITNESS_TYPE>::crossover_result_set MultiValueChromosomeBlendingCrossover<VALUE_TYPE,
23  FITNESS_TYPE>::doMultiValueCrossover(
24  const typename MultiValueChromosome<VALUE_TYPE, FITNESS_TYPE>::const_ptr &mommy,
25  const typename MultiValueChromosome<VALUE_TYPE, FITNESS_TYPE>::const_ptr &daddy) const
26 {
27  typename BaseCouplingOperation<FITNESS_TYPE>::offspring_result_set resultset;
28 
29  //Determine the amount of chromosomes to generate
30  unsigned int chromosomesToGenerate;
31 
32  if (_offspringMode == FIXED_AMOUNT)
33  {
34  chromosomesToGenerate = _numChilds;
35  }
36  else
37  {
38  chromosomesToGenerate = Random::generate<int>(1, _numChilds);
39  }
40 
41  for (unsigned int i = 0; i < chromosomesToGenerate; i++)
42  {
43  InterpolateBeta interpolationMethod = _interpolationMethod;
44 
45  if (_interpolationMethod == INTERPOLATE_RANDOM)
46  {
47  interpolationMethod = (InterpolateBeta) (INTERPOLATE_RANDOM + Random::generate(1, 3));
48  }
49 
50  const double beta1 = Random::generate<double>(0.0, 1.0);
51  const double beta2 = Random::generate<double>(0.0, 1.0);
52 
53  auto child_candidate = this->createChildCandidate();
54 
55  assert(child_candidate);
56 
57  const unsigned int containerSize = this->getBuilderFactory().getSettings().getNum();
58 
59  const auto &daddy_container = mommy->getContainer();
60  const auto &mommy_container = daddy->getContainer();
61  auto &child_container = child_candidate->getContainer();
62 
63  auto mommy_it = mommy_container.cbegin();
64  auto daddy_it = daddy_container.cbegin();
65 
66  for (unsigned int i = 0; mommy_it != mommy_container.end(); ++i)
67  {
68  double targetBeta;
69  switch (interpolationMethod)
70  {
71 
72  case INTERPOLATE_COSINE:
73  {
74  targetBeta = Interpolators::cosineInterpolate<double>(beta1, beta2,
75  static_cast<double>(i) / (static_cast<double>(containerSize)));
76  break;
77  }
78 
79  case INTERPOLATE_LINEARLY:
80  {
81  targetBeta = Interpolators::linearInterpolate<double>(beta1, beta2,
82  static_cast<double>(i) / (static_cast<double>(containerSize)));
83  break;
84  }
85 
86  default: //FALLTRHOUGH INTENDED
87  case INTERPOLATE_NONE:
88  {
89  targetBeta = beta1;
90  break;
91  }
92 
93  }
94 
95  assert(targetBeta <= 1.0);
96  assert(targetBeta >= 0);
97 
98  child_container[i] = ((*mommy_it * (1 - targetBeta) + *daddy_it * (targetBeta)));
99 
100  ++mommy_it;
101  ++daddy_it;
102  }
103 
104  //TODO(bewo): Restore Smoothness?
105 
106  resultset.emplace_back(child_candidate);
107  }
108 
109  return std::move(resultset);
110 }
111 
112 } /* geneial_export_namespace */
113 } /* private namespace crossover */
114 } /* private namespace operation */
115 } /* private namespace geneial */
116