GENEIAL  0.2=/
 All Classes Pages
FixPointCriterion.h
1 #pragma once
2 
3 #include <geneial/algorithm/criteria/StatefulStoppingCriterion.h>
4 
5 #include <deque>
6 
7 geneial_private_namespace(geneial)
8 {
9 geneial_private_namespace(algorithm)
10 {
11 geneial_private_namespace(stopping_criteria)
12 {
13 using ::geneial::population::management::BaseManager;
14 
15 geneial_export_namespace
16 {
17 
18 //TODO (bewo) proper doc
19 //Idea to implemented here
20 //count the last best xx chromosomes, each iteration count the derivation in the best chromosome
21 //abort if derivation is below certain threshold (typically 0)
22 template <typename FITNESS_TYPE>
23 class FixPointCriterion : public StatefulStoppingCriterion<FITNESS_TYPE>
24 {
25 public:
26  virtual ~FixPointCriterion() {};
27 
28  FixPointCriterion(const FITNESS_TYPE threshold = 0, const FITNESS_TYPE windowSize = 10, const FITNESS_TYPE minDiff = 1):
29  _windowSize(windowSize),
30  _threshold(threshold),
31  _minDiff(minDiff)
32  {
33  assert(_minDiff <= _windowSize);
34  assert(_minDiff > 0);
35  }
36 
37  virtual void print(std::ostream& os) const
38  {
39  os << "FixPoint"
40  << "(thres:"
41  << _threshold
42  << ",min:"
43  << _minDiff
44  << "winsize:"
45  << _windowSize
46  << ")";
47  }
48 
49  virtual bool wasStatefullyReached(BaseManager<FITNESS_TYPE> &manager)
50  {
51  updateWindowValues(manager);
52 
53  bool result = false;
54 
55  if(_window.size() >= _minDiff)
56  {
57  const FITNESS_TYPE latest = _window.front();
58  const FITNESS_TYPE oldest = _window.back();
59  //Ignore if we became worse.
60  if(latest >= oldest)
61  {
62  result = (latest - oldest) <= _threshold;
63  }
64  }
65 
66  return result;
67  }
68 
69 protected:
70  void inline updateWindowValues(BaseManager<FITNESS_TYPE> &manager)
71  {
72  const FITNESS_TYPE bestFitness = manager.getHighestFitness();
73  assert(_window.size() <= _windowSize);
74 
75  _window.push_front(bestFitness);
76 
77  while(_window.size()>_windowSize)
78  {
79  _window.pop_back();
80  }
81 
82  assert(_window.size() <= _windowSize);
83  }
84 
85 private:
86  //Window to "look back"
87  const unsigned int _windowSize;
88 
89  //Difference threshold between first and last of window
90  FITNESS_TYPE _threshold;
91 
92  std::deque<FITNESS_TYPE> _window;
93 
94  //minimum window size for a compare
95  const unsigned int _minDiff;
96 
97 };
98 
99 } /* geneial_export_namespace */
100 } /* private namespace stopping_criteria */
101 } /* private namespace algorithm */
102 } /* private namespace geneial */