Google OR-Tools v9.11
a fast and portable software suite for combinatorial optimization
Loading...
Searching...
No Matches
running_stat.h
Go to the documentation of this file.
1// Copyright 2010-2024 Google LLC
2// Licensed under the Apache License, Version 2.0 (the "License");
3// you may not use this file except in compliance with the License.
4// You may obtain a copy of the License at
5//
6// http://www.apache.org/licenses/LICENSE-2.0
7//
8// Unless required by applicable law or agreed to in writing, software
9// distributed under the License is distributed on an "AS IS" BASIS,
10// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11// See the License for the specific language governing permissions and
12// limitations under the License.
13
14#ifndef OR_TOOLS_UTIL_RUNNING_STAT_H_
15#define OR_TOOLS_UTIL_RUNNING_STAT_H_
16
17#include <cstddef>
18#include <deque>
19#include <vector>
20
22
23namespace operations_research {
24
25// Simple class to compute the average over a fixed size window of an integer
26// stream.
28 public:
29 // Initialize the class with the maximum window size.
30 // It must be positive (this is CHECKed).
31 explicit RunningAverage(int window_size = 1);
32
33 // This type is neither copyable nor movable.
36
37 // Resets the class to the exact same state as if it was just constructed with
38 // the given window size.
39 void Reset(int window_size);
40
41 // Adds the next integer of the stream.
42 void Add(int value);
43
44 // Returns the average of all the values added so far or zero if no values
45 // where added.
46 double GlobalAverage() const;
47
48 // Returns the average of the values in the current window or zero if the
49 // current window is empty.
50 double WindowAverage() const;
51
52 // Returns true iff the current window size is equal to the one specified in
53 // the constructor.
54 bool IsWindowFull() const;
55
56 // Clears the current window.
57 void ClearWindow();
58
59 private:
60 int window_size_;
61 int num_adds_;
62 double global_sum_;
63 double local_sum_;
64 std::deque<int> values_;
65};
66
67// Simple class to efficiently compute the maximum over a fixed size window
68// of a numeric stream. This works in constant average amortized time.
69template <class Number = double>
71 public:
72 // Takes the size of the running window. The size must be positive.
73 explicit RunningMax(int window_size);
74
75 // This type is neither copyable nor movable.
76 RunningMax(const RunningMax&) = delete;
77 RunningMax& operator=(const RunningMax&) = delete;
78
79 // Processes a new element from the stream.
80 void Add(Number value);
81
82 // Returns the current maximum element in the window.
83 // An element must have been added before calling this function.
84 Number GetCurrentMax();
85
86 private:
87 const int window_size_;
88
89 // Values in the current window.
90 std::vector<Number> values_;
91
92 // Index of the last added element in the window.
93 int last_index_;
94
95 // Index of the current maximum element.
96 int max_index_;
97};
98
99// ################## Implementations below #####################
100
101inline RunningAverage::RunningAverage(int window_size)
102 : window_size_(window_size),
103 num_adds_(0),
104 global_sum_(0.0),
105 local_sum_(0.0) {
106 CHECK_GT(window_size_, 0);
107}
108
109inline void RunningAverage::Reset(int window_size) {
110 window_size_ = window_size;
111 num_adds_ = 0;
112 global_sum_ = 0.0;
113 ClearWindow();
114}
115
116inline void RunningAverage::Add(int value) {
117 ++num_adds_;
118 global_sum_ += value;
119 local_sum_ += value;
120 values_.push_back(value);
121 if (static_cast<int>(values_.size()) > window_size_) {
122 local_sum_ -= values_.front();
123 values_.pop_front();
124 }
125}
126
127inline double RunningAverage::GlobalAverage() const {
128 return num_adds_ == 0 ? 0.0 : global_sum_ / static_cast<double>(num_adds_);
129}
130
131inline double RunningAverage::WindowAverage() const {
132 return values_.empty() ? 0.0
133 : local_sum_ / static_cast<double>(values_.size());
134}
135
137 local_sum_ = 0.0;
138 values_.clear();
139}
140
141inline bool RunningAverage::IsWindowFull() const {
142 return static_cast<int>(values_.size()) == window_size_;
143}
144
145template <class Number>
147 : window_size_(window_size), values_(), last_index_(0), max_index_(0) {
148 DCHECK_GT(window_size, 0);
149}
150
151template <class Number>
153 if (static_cast<size_t>(values_.size()) < window_size_) {
154 // Starting phase until values_ reaches its final size.
155 // Note that last_index_ stays at 0 during this phase.
156 if (values_.empty() || value >= GetCurrentMax()) {
157 max_index_ = values_.size();
158 }
159 values_.push_back(value);
160 return;
161 }
162 // We are in the steady state.
163 DCHECK_EQ(values_.size(), window_size_);
164 // Note the use of >= instead of > to get the O(1) behavior in presence of
165 // many identical values.
166 if (value >= GetCurrentMax()) {
167 max_index_ = last_index_;
168 values_[last_index_] = value;
169 } else {
170 values_[last_index_] = value;
171 if (last_index_ == max_index_) {
172 // We need to recompute the max.
173 // Note that this happens only if value was strictly lower than
174 // GetCurrentMax() in the last window_size_ updates.
175 max_index_ = 0;
176 Number max_value = values_[max_index_];
177 for (int i = 1; i < static_cast<int>(values_.size()); ++i) {
178 if (values_[i] > max_value) {
179 max_value = values_[i];
180 max_index_ = i;
181 }
182 }
183 }
184 }
185 if (++last_index_ == window_size_) {
186 last_index_ = 0;
187 }
188}
189
190template <class Number>
192 DCHECK(!values_.empty());
193 return values_[max_index_];
194}
195
196} // namespace operations_research
197
198#endif // OR_TOOLS_UTIL_RUNNING_STAT_H_
RunningAverage & operator=(const RunningAverage &)=delete
void ClearWindow()
Clears the current window.
RunningAverage(const RunningAverage &)=delete
This type is neither copyable nor movable.
void Add(int value)
Adds the next integer of the stream.
RunningAverage(int window_size=1)
################## Implementations below #####################
RunningMax(int window_size)
Takes the size of the running window. The size must be positive.
void Add(Number value)
Processes a new element from the stream.
RunningMax & operator=(const RunningMax &)=delete
RunningMax(const RunningMax &)=delete
This type is neither copyable nor movable.
int64_t value
In SWIG mode, we don't want anything besides these top-level includes.