GENEIAL  0.2=/
 All Classes Pages
BaseGeneticAlgorithm.h
1 #pragma once
2 
3 #include <geneial/namespaces.h>
4 #include <geneial/config.h>
5 
6 #include <geneial/core/population/Population.h>
7 #include <geneial/core/population/PopulationSettings.h>
8 
9 #include <geneial/core/population/management/BaseManager.h>
10 
11 #include <geneial/algorithm/criteria/BaseStoppingCriterion.h>
12 #include <geneial/core/operations/selection/BaseSelectionOperation.h>
13 #include <geneial/core/operations/coupling/BaseCouplingOperation.h>
14 #include <geneial/core/operations/crossover/BaseCrossoverOperation.h>
15 #include <geneial/core/operations/mutation/BaseMutationOperation.h>
16 #include <geneial/core/operations/replacement/BaseReplacementOperation.h>
17 #include <geneial/algorithm/observer/AlgorithmObserver.h>
18 #include <geneial/utility/mixins/Buildable.h>
19 
20 #include <geneial/utility/ExecutionManager.h>
21 
22 #include <boost/optional.hpp>
23 
24 #include <memory>
25 #include <map>
26 #include <list>
27 #include <type_traits>
28 
29 
30 geneial_private_namespace(geneial)
31 {
32 geneial_private_namespace(algorithm)
33 {
34 using ::geneial::algorithm::stopping_criteria::BaseStoppingCriterion;
35 using ::geneial::operation::selection::BaseSelectionOperation;
36 using ::geneial::operation::coupling::BaseCouplingOperation;
37 using ::geneial::operation::crossover::BaseCrossoverOperation;
38 using ::geneial::operation::replacement::BaseReplacementOperation;
39 using ::geneial::operation::mutation::BaseMutationOperation;
40 using ::geneial::utility::BaseExecutionManager;
41 using ::geneial::population::Population;
42 using ::geneial::population::PopulationSettings;
43 using ::geneial::population::chromosome::BaseChromosome;
44 using ::geneial::population::chromosome::BaseChromosomeFactory;
45 using ::geneial::population::management::BaseBookkeeper;
46 using ::geneial::population::management::BaseManager;
47 
48 using ::geneial::utility::Buildable;
49 
50 geneial_export_namespace
51 {
52 
53 
54 template<typename FITNESS_TYPE>
55 class BaseGeneticAlgorithm : public virtual Buildable<BaseGeneticAlgorithm<FITNESS_TYPE>>
56 {
57 protected:
58  typedef typename std::map<typename AlgorithmObserver<FITNESS_TYPE>::ObserveableEvent,
59  std::vector<std::shared_ptr<AlgorithmObserver<FITNESS_TYPE>>>> observers_map;
60 
61  observers_map _observers;
62 
63  std::shared_ptr<BaseManager<FITNESS_TYPE>> _manager;
64 
65  bool _wasSolved;
66 
67  bool _wasStarted;
68 
69  std::shared_ptr<BaseStoppingCriterion<FITNESS_TYPE>> _stoppingCriterion;
70 
71  std::shared_ptr<BaseSelectionOperation<FITNESS_TYPE>> _selectionOperation;
72 
73  std::shared_ptr<BaseCouplingOperation<FITNESS_TYPE>> _couplingOperation;
74 
75  std::shared_ptr<BaseCrossoverOperation<FITNESS_TYPE>> _crossoverOperation;
76 
77  std::shared_ptr<BaseReplacementOperation<FITNESS_TYPE>> _replacementOperation;
78 
79  std::shared_ptr<BaseMutationOperation<FITNESS_TYPE>> _mutationOperation;
80 
81  //The client should use the builder instead of instacing the algorithm herself
82  BaseGeneticAlgorithm(
83  std::shared_ptr<BaseStoppingCriterion<FITNESS_TYPE>> stoppingCriterion,
84  std::shared_ptr<BaseSelectionOperation<FITNESS_TYPE>> selectionOperation,
85  std::shared_ptr<BaseCouplingOperation<FITNESS_TYPE>> couplingOperation,
86  std::shared_ptr<BaseCrossoverOperation<FITNESS_TYPE>> crossoverOperation,
87  std::shared_ptr<BaseReplacementOperation<FITNESS_TYPE>> replacementOperation,
88  std::shared_ptr<BaseMutationOperation<FITNESS_TYPE>> mutationOperation,
89  std::shared_ptr<BaseChromosomeFactory<FITNESS_TYPE>> chromosomeFactory):
90 
91  _manager(BaseManager<FITNESS_TYPE>::create(chromosomeFactory)),
92  _wasSolved(false),
93  _wasStarted(false),
94  _stoppingCriterion(stoppingCriterion),
95  _selectionOperation(selectionOperation),
96  _couplingOperation(couplingOperation),
97  _crossoverOperation(crossoverOperation),
98  _replacementOperation(replacementOperation),
99  _mutationOperation(mutationOperation)
100  {
101  static_assert(std::is_arithmetic<FITNESS_TYPE>::value,"FITNESS_TYPE is expected to be an arithmetic data type!");
102  }
103 
104 public:
105  // use this class to construct an Algorithm
106  class Builder;
107 
108 
109  virtual ~BaseGeneticAlgorithm()
110  {
111  }
112 
113  virtual void solve() = 0;
114 
115  virtual void setInitialPopulation(typename Population<FITNESS_TYPE>::chromosome_container &container)
116  {
117  assert(!_wasStarted);
118  _manager->getPopulation().replacePopulation(container);
119  }
120 
121  //Delegates to manager,
122  //*caution*: the user should never directly interact with the manager, rather use this class as facade
123  inline typename BaseChromosome<FITNESS_TYPE>::ptr getHighestFitnessChromosome() const
124  {
125  assert(_wasStarted);
126  return _manager->getHighestFitnessChromosome();
127  }
128 
129  inline FITNESS_TYPE getHighestFitness() const
130  {
131  assert(_wasStarted);
132  return _manager->getHighestFitness();
133  }
134 
135  virtual Population<FITNESS_TYPE>& getPopulation()
136  {
137  return _manager->getPopulation();
138  }
139 
140  inline typename BaseChromosome<FITNESS_TYPE>::ptr getLowestFitnessChromosome() const
141  {
142  assert(_wasStarted);
143  return _manager->getLowestFitnessChromosome();
144  }
145 
146  inline FITNESS_TYPE getLowestFitness() const
147  {
148  assert(_wasStarted);
149  return _manager->getLowestFitness();
150  }
151 
152  inline virtual bool hasBeenSolved() const
153  {
154  return _wasSolved;
155  }
156 
157  inline virtual bool hasBeenStarted() const
158  {
159  return _wasStarted;
160  }
161 
162  inline virtual PopulationSettings& getPopulationSettings()
163  {
164  return _manager->getPopulationSettings();
165  }
166 
167  inline void setPopulationSettings(PopulationSettings& populationSettings)
168  {
169  _manager->setPopulationSettings(populationSettings);
170  }
171 
172  inline virtual bool wasCriteriaReached();
173 
174  inline virtual void notifyObservers(typename AlgorithmObserver<FITNESS_TYPE>::ObserveableEvent event);
175 
176  inline virtual void registerObserver(const std::shared_ptr<AlgorithmObserver<FITNESS_TYPE>>& observer);
177 
178 
179  BaseExecutionManager& getExecutionManager() const
180  {
181  return _manager->getExecutionManager();
182  }
183 
184  void setExecutionManager(std::unique_ptr<BaseExecutionManager>&& executionManager)
185  {
186  _manager->setExecutionManager(std::move(executionManager));
187  }
188 
189  void setBookkeeper(const std::shared_ptr<BaseBookkeeper>& bookkeeper)
190  {
191  _manager->setBookkeeper(bookkeeper);
192  }
193 
194  const std::shared_ptr<BaseBookkeeper> getBookkeeper() const
195  {
196  return _manager->getBookkeeper();
197  }
198 };
199 
200 template<typename FITNESS_TYPE>
201 class BaseGeneticAlgorithm<FITNESS_TYPE>::Builder : public Buildable<BaseGeneticAlgorithm<FITNESS_TYPE>>::Builder
202 {
203 protected:
204  boost::optional<std::shared_ptr<BaseStoppingCriterion<FITNESS_TYPE>>> _stoppingCriterion;
205 
206  boost::optional<std::shared_ptr<BaseSelectionOperation<FITNESS_TYPE>>> _selectionOperation;
207 
208  boost::optional<std::shared_ptr<BaseCouplingOperation<FITNESS_TYPE>>> _couplingOperation;
209 
210  boost::optional<std::shared_ptr<BaseCrossoverOperation<FITNESS_TYPE>>> _crossoverOperation;
211 
212  boost::optional<std::shared_ptr<BaseReplacementOperation<FITNESS_TYPE>>> _replacementOperation;
213 
214  boost::optional<std::shared_ptr<BaseMutationOperation<FITNESS_TYPE>>> _mutationOperation;
215 
216  boost::optional<std::shared_ptr<BaseChromosomeFactory<FITNESS_TYPE>>> _chromosomeFactory;
217 
218 public:
219  Builder()
220  {
221  }
222 
223  virtual ~Builder()
224  {
225  }
226 
227  Builder& setStoppingCriterion( const std::shared_ptr<stopping_criteria::BaseStoppingCriterion<FITNESS_TYPE>> &stoppingCriterion )
228  {
229  this->_stoppingCriterion = stoppingCriterion;
230  return *this;
231  }
232 
233  Builder& setSelectionOperation( const std::shared_ptr<BaseSelectionOperation<FITNESS_TYPE>> &selectionOperation )
234  {
235  this->_selectionOperation = selectionOperation;
236  return *this;
237  }
238 
239  Builder& setCouplingOperation( const std::shared_ptr<BaseCouplingOperation<FITNESS_TYPE>> &couplingOperation )
240  {
241  this->_couplingOperation = couplingOperation;
242  return *this;
243  }
244 
245  Builder& setCrossoverOperation( const std::shared_ptr<BaseCrossoverOperation<FITNESS_TYPE>> &crossoverOperation )
246  {
247  this->_crossoverOperation = crossoverOperation;
248  return *this;
249  }
250 
251  Builder& setReplacementOperation( const std::shared_ptr<BaseReplacementOperation<FITNESS_TYPE>> &replacementOperation )
252  {
253  this->_replacementOperation = replacementOperation;
254  return *this;
255  }
256 
257  Builder& setMutationOperation( const std::shared_ptr<BaseMutationOperation<FITNESS_TYPE>> &mutationOperation )
258  {
259  this->_mutationOperation = mutationOperation;
260  return *this;
261  }
262 
263  Builder& setChromosomeFactory (const std::shared_ptr<BaseChromosomeFactory<FITNESS_TYPE>> chromosomeFactory )
264  {
265  _chromosomeFactory = chromosomeFactory;
266  return *this;
267  }
268 };
269 
270 } /* geneial_export_namespace */
271 } /* private namespace algorithm */
272 } /* private namespace geneial */
273 
274 
275 #include <geneial/algorithm/BaseGeneticAlgorithm.hpp>
276