GENEIAL  0.2=/
 All Classes Pages
MultiValueChromosomeFactory.h
1 #pragma once
2 
3 #include <geneial/namespaces.h>
4 #include <geneial/core/population/builder/BaseChromosomeFactory.h>
5 #include <geneial/core/population/builder/MultiValueBuilderSettings.h>
6 #include <geneial/utility/mixins/EnableMakeShared.h>
7 
8 
9 #include <memory>
10 
11 geneial_private_namespace(geneial)
12 {
13 geneial_private_namespace(population)
14 {
15 geneial_private_namespace(chromosome)
16 {
17 
18 using ::geneial::utility::EnableMakeShared;
19 
20 geneial_export_namespace
21 {
22 
23 
24 template<typename VALUE_TYPE, typename FITNESS_TYPE>
25 class MultiValueChromosomeFactory: public BaseChromosomeFactory<FITNESS_TYPE>,
26  public virtual EnableMakeShared<MultiValueChromosomeFactory<VALUE_TYPE, FITNESS_TYPE>>
27 {
28 protected:
29  struct ChromosomeDeleter
30  {
31  std::weak_ptr<ResourcePool<MultiValueChromosome<VALUE_TYPE, FITNESS_TYPE>>> _resourcePool;
32 
33  ChromosomeDeleter(const std::weak_ptr<ResourcePool<MultiValueChromosome<VALUE_TYPE, FITNESS_TYPE>>> &resourcePool):_resourcePool(resourcePool)
34  {
35  }
36 
37  inline void operator()(MultiValueChromosome<VALUE_TYPE,FITNESS_TYPE>* p) const
38  {
39  if (const auto resourcePool = _resourcePool.lock())
40  {
41  resourcePool->free(std::move(p));
42  }
43  else
44  {
45  //The resource pool is already gone, manual fallback resource cleanup.
46  delete p;
47  }
48  }
49  };
50 
51 
52  const MultiValueBuilderSettings<VALUE_TYPE, FITNESS_TYPE> &_settings;
53 
54  //This shared ptr is necessary if there are chromomsome references after the shutdown of the factory that reference the resource pool for cleanup.
55  //Those deleters, then are unable to check whether the resource pool is still valid or not.
56  std::shared_ptr<ResourcePool<MultiValueChromosome<VALUE_TYPE,FITNESS_TYPE>>> _chromosomeResourcePool;
57 
58 
59  typename BaseChromosome<FITNESS_TYPE>::ptr doCreateChromosome(
60  typename BaseChromosomeFactory<FITNESS_TYPE>::PopulateBehavior populateValues
61  ) override;
62 
63 
64 
65  typename MultiValueChromosome<VALUE_TYPE,FITNESS_TYPE>::ptr allocateNewChromsome()
66  {
67  MultiValueChromosome<VALUE_TYPE,FITNESS_TYPE> *rawChromosome ;
68 
69  if(this->_chromosomeResourcePool->retrieve(rawChromosome))
70  {
71  rawChromosome->invalidate();
72  rawChromosome->setFitnessEvaluator(_settings.getFitnessEvaluator());
73  }
74  else
75  {
76  rawChromosome = new MultiValueChromosome<VALUE_TYPE, FITNESS_TYPE>(_settings.getFitnessEvaluator());
77  }
78 
79 
80  //TODO(bewo): Is there a way to use a single Deleter instance? Is it faster?
81  typename MultiValueChromosome<VALUE_TYPE, FITNESS_TYPE>::ptr new_chromosome(
82  rawChromosome, ChromosomeDeleter(this->_chromosomeResourcePool));
83 
84  //Enforce alloc
85  new_chromosome->getContainer().resize(this->_settings.getNum());
86 
87  return std::move(new_chromosome);
88  }
89 
90  explicit MultiValueChromosomeFactory (const MultiValueBuilderSettings<VALUE_TYPE, FITNESS_TYPE> &settings) :
91  BaseChromosomeFactory<FITNESS_TYPE>(),
92  _settings(settings),
93  _chromosomeResourcePool(std::make_shared<ResourcePool<MultiValueChromosome<VALUE_TYPE,FITNESS_TYPE>>>())
94  {
95  }
96 
97 public:
98 
99  class Builder : public BaseChromosomeFactory<FITNESS_TYPE>::Builder
100  {
101  MultiValueBuilderSettings<VALUE_TYPE, FITNESS_TYPE> _settings;
102 
103  public:
104  MultiValueBuilderSettings<VALUE_TYPE,FITNESS_TYPE>& getSettings()
105  {
106  return _settings;
107  }
108 
109  Builder(const typename FitnessEvaluator<FITNESS_TYPE>::ptr &fitnessEvaluator):
110  _settings(fitnessEvaluator)
111  {
112  }
113 
114  virtual typename BaseChromosomeFactory<FITNESS_TYPE>::ptr create() override
115  {
116  return std::move(MultiValueChromosomeFactory<VALUE_TYPE,FITNESS_TYPE>::makeShared(_settings));
117  }
118 
119  };
120 
121  virtual ~MultiValueChromosomeFactory()
122  {
123  }
124 
125  inline const MultiValueBuilderSettings<VALUE_TYPE, FITNESS_TYPE> & getSettings() const
126  {
127  return _settings;
128  }
129 
130  void setSettings(const MultiValueBuilderSettings<VALUE_TYPE, FITNESS_TYPE>& settings)
131  {
132  _settings = settings;
133  }
134 
135 };
136 
137 } /* geneial_export_namespace */
138 } /* private namespace chromosome */
139 } /* private namespace population */
140 } /* private namespace geneial */
141 
142 #include <geneial/core/population/builder/MultiValueChromosomeFactory.hpp>