GENEIAL  0.2=/
 All Classes Pages
CombinedCriterion.h
1 #pragma once
2 
3 #include <geneial/algorithm/criteria/BaseStoppingCriterion.h>
4 
5 #include <vector>
6 #include <utility>
7 
8 geneial_private_namespace(geneial)
9 {
10 geneial_private_namespace(algorithm)
11 {
12 geneial_private_namespace(stopping_criteria)
13 {
14 using ::geneial::population::management::BaseManager;
15 
16 geneial_export_namespace
17 {
18 
19 //Container that holds other Criteria which are connected by a logical condition (and/or), which propagate the condition by visitor pattern or sth.
20 //Composite Pattern for hierarchies of criteria
21 //Associativity: left
22 template<typename FITNESS_TYPE>
23 class CombinedCriterion: public BaseStoppingCriterion<FITNESS_TYPE>
24 {
25 public:
26  enum glue
27  {
28  INIT, AND, OR, XOR
29  };
30 
31  typedef typename BaseStoppingCriterion<FITNESS_TYPE>::ptr criterion;
32 
33  typedef std::pair<glue, criterion> glue_criterion_pair;
34 
35  typedef std::vector<glue_criterion_pair> container;
36 
37  virtual ~CombinedCriterion()
38  {
39  }
40 
41 
42  //TODO (bewo): Constructor and initializer list
43 
47  virtual bool wasReached(BaseManager<FITNESS_TYPE> &manager)
48  {
49  bool accumulatedResult = true;
50 
51  assert(std::count_if(_criteria.begin(), _criteria.end(), [](glue_criterion_pair const &b)
52  {
53  return b.first == INIT;
54  }) == 1 && "INIT type not found or there are more than one INIT glue for combined criterion!");
55 
56  for (const auto &criterionPair : _criteria)
57  {
58  if (criterionPair.first == INIT)
59  {
60  accumulatedResult = criterionPair.second->wasReached(manager);
61  }
62  else if (criterionPair.first == AND)
63  {
64  accumulatedResult &= criterionPair.second->wasReached(manager);
65  }
66  else if (criterionPair.first == XOR)
67  {
68  accumulatedResult &= !criterionPair.second->wasReached(manager);
69  }
70  else
71  {
72  accumulatedResult |= criterionPair.second->wasReached(manager);
73  }
74  }
75  return accumulatedResult;
76  }
77 
78  virtual void print(std::ostream& os) const
79  {
80  os << "Combined (";
81  for (const auto &criterionPair : _criteria)
82  {
83  if (criterionPair.first == AND)
84  {
85  os << "(&&) ";
86  }
87  else if (criterionPair.first == XOR)
88  {
89  os << "(^^) ";
90  }
91  else
92  {
93  os << "(||) ";
94  }
95  os << criterionPair.second;
96  }
97  os << ")";
98  }
99 
100  void add(const glue_criterion_pair newCriterion)
101  {
102  _criteria.emplace_back(newCriterion);
103  }
104 
105  void add(const glue glue, const criterion criterion)
106  {
107  add(glue_criterion_pair(glue, criterion));
108  }
109 
110  const container& getCriteria() const
111  {
112  return _criteria;
113  }
114 
115  void setCriteria(const container& criteria)
116  {
117  _criteria = criteria;
118  }
119 
120 private:
121  container _criteria;
122 
123 };
124 
125 } /* geneial_export_namespace */
126 } /* private namespace stopping_criteria */
127 } /* private namespace algorithm */
128 } /* private namespace geneial */
129