GENEIAL  0.2=/
 All Classes Pages
MultiValueChromosomeNPointCrossover.h
1 #pragma once
2 
3 #include <geneial/namespaces.h>
4 #include <geneial/core/operations/crossover/MultiValueChromosomeCrossoverOperation.h>
5 #include <geneial/core/operations/crossover/MultiValueChromosomeNPointCrossoverSettings.h>
6 #include <geneial/utility/mixins/EnableMakeShared.h>
7 
8 #include <cassert>
9 
10 geneial_private_namespace(geneial)
11 {
12 geneial_private_namespace(operation)
13 {
14 geneial_private_namespace(crossover)
15 {
16 using ::geneial::population::Population;
17 using ::geneial::population::chromosome::MultiValueChromosome;
18 using ::geneial::operation::coupling::BaseCouplingOperation;
19 using ::geneial::utility::EnableMakeShared;
20 
21 
22 geneial_export_namespace
23 {
24 //TODO (bewo) allow random crossover width per settings
25 
26 template<typename VALUE_TYPE, typename FITNESS_TYPE>
27 class MultiValueChromosomeNPointCrossover: public MultiValueChromosomeCrossoverOperation<VALUE_TYPE,FITNESS_TYPE>,
28  public virtual EnableMakeShared<MultiValueChromosomeNPointCrossover<VALUE_TYPE,FITNESS_TYPE>>
29 {
30 private:
31  std::shared_ptr<const MultiValueChromosomeNPointCrossoverSettings> _crossoverSettings;
32 
33 protected:
34  MultiValueChromosomeNPointCrossover(
35  const std::shared_ptr<const MultiValueChromosomeNPointCrossoverSettings> &crossoverSettings,
36  const std::shared_ptr<MultiValueChromosomeFactory<VALUE_TYPE, FITNESS_TYPE>> &builderFactory):
37  MultiValueChromosomeCrossoverOperation<VALUE_TYPE,FITNESS_TYPE>(builderFactory),
38  _crossoverSettings(crossoverSettings)
39  {
40  //ensure the crossoverpoints does not exceed the number of values.
41  assert(getCrossoverSettings().getCrossOverPoints() <= this->getBuilderFactory().getSettings().getNum());
42 
43  //ensure when min width is selected that the min width does not exceed the amount of spaces we have.
44  assert(
45  getCrossoverSettings().getWidthSetting()
46  != MultiValueChromosomeNPointCrossoverSettings::RANDOM_MIN_WIDTH
47  || getCrossoverSettings().getMinWidth() * getCrossoverSettings().getCrossOverPoints()
48  <= this->getBuilderFactory().getSettings().getNum());
49 
50  }
51 
52 public:
53 
54  virtual ~MultiValueChromosomeNPointCrossover()
55  {
56  }
57 
58  virtual bool isSymmetric() const override
59  {
60  return false;
61  }
62 
63  /****
64  * Computes the N-Point crossover of two multi value chromosomes.
65  *
66  * Example:
67  * Say, A and B are Chromosomes with
68  *
69  * A (mommy)
70  * ===========================
71  * |A1|A2|A3|A4|A5|A6|A7|A8|A9
72  * ===========================
73  *
74  * B (daddy)
75  * ===========================
76  * |B1|B2|B3|B4|B5|B6|B7|B8|B9
77  * ===========================
78  *
79  * With a 2-Point-Crossover the resulting chromosome is
80  *
81  * Child | |
82  * ===========================
83  * |A1|A2|A3|B4|B5|B6|A7|A8|A9
84  * ===========================
85  *
86  */
87  virtual typename BaseCrossoverOperation<FITNESS_TYPE>::crossover_result_set doMultiValueCrossover(
88  const typename MultiValueChromosome<VALUE_TYPE, FITNESS_TYPE>::const_ptr &mommy,
89  const typename MultiValueChromosome<VALUE_TYPE, FITNESS_TYPE>::const_ptr &daddy) const override;
90 
91  inline const MultiValueChromosomeNPointCrossoverSettings & getCrossoverSettings() const
92  {
93  return *_crossoverSettings;
94  }
95 
96  void setCrossoverSettings(std::shared_ptr<const MultiValueChromosomeNPointCrossoverSettings>& crossoverSettings)
97  {
98  _crossoverSettings = crossoverSettings;
99  }
100 
101 
102 
103  class Builder : public MultiValueChromosomeCrossoverOperation<VALUE_TYPE,FITNESS_TYPE>::Builder
104  {
105  protected:
106  std::shared_ptr<MultiValueChromosomeNPointCrossoverSettings> _crossoverSettings;
107 
108  public:
109  Builder(const std::shared_ptr<MultiValueChromosomeFactory<VALUE_TYPE, FITNESS_TYPE>> & builderFactory) :
110  MultiValueChromosomeCrossoverOperation<VALUE_TYPE, FITNESS_TYPE>::Builder(builderFactory), _crossoverSettings(
111  new MultiValueChromosomeNPointCrossoverSettings(DEFAULT_CROSSOVERPOINTS, DEFAULT_WIDTH_MODE))
112  {
113  }
114 
115  const static unsigned int DEFAULT_CROSSOVERPOINTS = 1;
116 
117  const static MultiValueChromosomeNPointCrossoverSettings::width_settings DEFAULT_WIDTH_MODE = MultiValueChromosomeNPointCrossoverSettings::RANDOM_WIDTH;
118 
119  inline MultiValueChromosomeNPointCrossoverSettings & getCrossoverSettings()
120  {
121  return *_crossoverSettings;
122  }
123 
124  virtual typename BaseCrossoverOperation<FITNESS_TYPE>::ptr create() override
125  {
126  if(! this->_builderFactory )
127  {
128  throw new std::runtime_error("Must set a Chromosome Factory to build MultiValueCrossover");
129  }
130 
131  return MultiValueChromosomeNPointCrossover::makeShared(
132  _crossoverSettings,
133  this->_builderFactory);
134  }
135  };
136 };
137 
138 } /* geneial_export_namespace */
139 } /* private namespace crossover */
140 } /* private namespace operation */
141 } /* private namespace geneial */
142 
143 #include <geneial/core/operations/crossover/MultiValueChromosomeNPointCrossover.hpp>
144