TheAlgorithms/C++ 1.0.0
All the algorithms implemented in C++
Loading...
Searching...
No Matches
windowed_median.cpp
Go to the documentation of this file.
1
31#include <cassert>
32#include <cstdlib>
33#include <ctime>
34#include <list>
35#include <set>
36#include <vector>
37
42namespace probability {
47namespace windowed_median {
48using Window = std::list<int>;
49using size_type = Window::size_type;
50
57 const size_type _windowSize;
58 Window _window;
59 std::multiset<int> _sortedValues;
61 std::multiset<int>::const_iterator
64
69 void insertToSorted(int value) {
70 _sortedValues.insert(value);
71 const auto sz = _sortedValues.size();
72 if (sz == 1) {
73 _itMedian = _sortedValues.begin();
74 return;
75 }
76
80 if (value < *_itMedian && sz % 2 == 0) {
81 --_itMedian; // O(1) - traversing one step to the left child
82 }
83
86 else if (value >= *_itMedian && sz % 2 != 0) {
87 ++_itMedian;
88 }
89 }
90
95 void eraseFromSorted(int value) {
96 const auto sz = _sortedValues.size();
97
101 if (value <= *_itMedian && sz % 2 == 0) {
102 ++_itMedian;
103 }
104
108 else if (value >= *_itMedian && sz % 2 != 0) {
109 --_itMedian; // O(1) - traversing one step to the left child
110 }
111
114 const auto it = _sortedValues.find(value); // O(logN)
115 _sortedValues.erase(it); // O(logN)
116 }
117
118 public:
123 explicit WindowedMedian(size_type windowSize) : _windowSize(windowSize){};
124
129 void insert(int value) {
131 _window.push_back(value);
132 insertToSorted(value); // Insert value to the multi-value BST - O(logN)
133 if (_window.size() > _windowSize) {
136 _window.front());
138 _window.pop_front();
140 }
141 }
142
148 float getMedian() const {
149 if (_sortedValues.size() % 2 != 0) {
150 return *_itMedian; // O(1)
151 }
152 return 0.5f * *_itMedian + 0.5f * *next(_itMedian);
153 }
154
161 float getMedianNaive() const {
162 auto window = _window;
163 window.sort();
164 auto median =
165 *next(window.begin(),
166 window.size() / 2);
167 if (window.size() % 2 != 0) {
168 return median;
169 }
170 return 0.5f * median +
171 0.5f * *next(window.begin(), window.size() / 2 - 1);
172 }
173};
174} // namespace windowed_median
175} // namespace probability
176
182static void test(const std::vector<int> &vals, int windowSize) {
183 probability::windowed_median::WindowedMedian windowedMedian(windowSize);
184 for (const auto val : vals) {
185 windowedMedian.insert(val);
186
188 assert(windowedMedian.getMedian() == windowedMedian.getMedianNaive());
189 }
190}
191
198int main(int argc, const char *argv[]) {
200 test({1, 2, 3, 4, 5, 6, 7, 8, 9},
201 3);
202 test({9, 8, 7, 6, 5, 4, 3, 2, 1},
203 3);
204 test({9, 8, 7, 6, 5, 4, 5, 6}, 4);
205 test({3, 3, 3, 3, 3, 3, 3, 3, 3}, 3);
206 test({3, 3, 3, 3, 7, 3, 3, 3, 3}, 3);
207 test({4, 3, 3, -5, -5, 1, 3, 4, 5},
208 5);
209
213 test({470211272, 101027544, 1457850878, 1458777923, 2007237709, 823564440,
214 1115438165, 1784484492, 74243042, 114807987},
215 6);
216
218 std::srand(static_cast<unsigned int>(std::time(nullptr)));
219 std::vector<int> vals;
220 for (int i = 8; i < 100; i++) {
221 const auto n =
222 1 + std::rand() /
223 ((RAND_MAX + 5u) / 20);
224 auto windowSize =
225 1 + std::rand() / ((RAND_MAX + 3u) /
226 10);
227 vals.clear();
228 vals.reserve(n);
229 for (int i = 0; i < n; i++) {
230 vals.push_back(
231 rand() - RAND_MAX);
232 }
233 test(vals, windowSize);
234 }
235 return 0;
236}
A class to calculate the median of a leading sliding window at the back of a stream of integer values...
void insertToSorted(int value)
Inserts a value to a sorted multi-value BST.
std::multiset< int >::const_iterator _itMedian
float getMedianNaive() const
A naive and inefficient method to obtain the median of the sliding window. Used for testing!
void insert(int value)
Insert a new value to the stream.
Window _window
a sliding window of values along the stream
float getMedian() const
Gets the median of the values in the sliding window.
WindowedMedian(size_type windowSize)
Constructs a WindowedMedian object.
const size_type _windowSize
sliding window size
void eraseFromSorted(int value)
Erases a value from a sorted multi-value BST.
static void test()
Self-test implementations.
int main()
Main function.
Probability algorithms.
Functions for the Windowed Median algorithm implementation.