3 #include <geneial/core/operations/crossover/MultiValueChromosomeBlendingCrossover.h>
4 #include <geneial/core/operations/crossover/BaseCrossoverOperation.h>
5 #include <geneial/utility/Random.h>
7 geneial_private_namespace(geneial)
9 geneial_private_namespace(operation)
11 geneial_private_namespace(crossover)
13 using ::geneial::population::Population;
14 using ::geneial::population::chromosome::MultiValueChromosome;
15 using ::geneial::operation::coupling::BaseCouplingOperation;
17 geneial_export_namespace
19 using namespace geneial::utility;
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
27 typename BaseCouplingOperation<FITNESS_TYPE>::offspring_result_set resultset;
30 unsigned int chromosomesToGenerate;
32 if (_offspringMode == FIXED_AMOUNT)
34 chromosomesToGenerate = _numChilds;
38 chromosomesToGenerate = Random::generate<int>(1, _numChilds);
41 for (
unsigned int i = 0; i < chromosomesToGenerate; i++)
43 InterpolateBeta interpolationMethod = _interpolationMethod;
45 if (_interpolationMethod == INTERPOLATE_RANDOM)
47 interpolationMethod = (InterpolateBeta) (INTERPOLATE_RANDOM + Random::generate(1, 3));
50 const double beta1 = Random::generate<double>(0.0, 1.0);
51 const double beta2 = Random::generate<double>(0.0, 1.0);
53 auto child_candidate = this->createChildCandidate();
55 assert(child_candidate);
57 const unsigned int containerSize = this->getBuilderFactory().getSettings().getNum();
59 const auto &daddy_container = mommy->getContainer();
60 const auto &mommy_container = daddy->getContainer();
61 auto &child_container = child_candidate->getContainer();
63 auto mommy_it = mommy_container.cbegin();
64 auto daddy_it = daddy_container.cbegin();
66 for (
unsigned int i = 0; mommy_it != mommy_container.end(); ++i)
69 switch (interpolationMethod)
72 case INTERPOLATE_COSINE:
74 targetBeta = Interpolators::cosineInterpolate<double>(beta1, beta2,
75 static_cast<double>(i) / (static_cast<double>(containerSize)));
79 case INTERPOLATE_LINEARLY:
81 targetBeta = Interpolators::linearInterpolate<double>(beta1, beta2,
82 static_cast<double>(i) / (static_cast<double>(containerSize)));
87 case INTERPOLATE_NONE:
95 assert(targetBeta <= 1.0);
96 assert(targetBeta >= 0);
98 child_container[i] = ((*mommy_it * (1 - targetBeta) + *daddy_it * (targetBeta)));
106 resultset.emplace_back(child_candidate);
109 return std::move(resultset);