Storm
A Modern Probabilistic Model Checker
Loading...
Searching...
No Matches
ConsecutiveUint64DynamicPriorityQueue.h
Go to the documentation of this file.
1#pragma once
2
3#include <algorithm>
4#include <numeric>
5#include <vector>
6
7#include "storm-config.h"
8
10
11namespace storm {
12namespace storage {
13
14template<typename Compare = std::less<uint64_t>>
16 public:
17 typedef uint64_t T;
18 typedef std::vector<T> Container;
19
20 private:
21 Container container;
22 Compare compare;
23
24 std::vector<uint64_t> positions;
25
26 public:
27 explicit ConsecutiveUint64DynamicPriorityQueue(uint64_t numberOfIntegers, Compare const& compare)
28 : container(numberOfIntegers), compare(compare), positions(numberOfIntegers) {
29 std::iota(container.begin(), container.end(), 0);
30 std::make_heap(container.begin(), container.end(), compare);
31 updatePositions();
32 }
33
34 void increase(uint64_t element) {
35 uint64_t position = positions[element];
36 if (position >= container.size()) {
37 return;
38 }
39
40 uint64_t parentPosition = (position - 1) / 2;
41 while (position > 0 && compare(container[parentPosition], container[position])) {
42 std::swap(positions[container[parentPosition]], positions[container[position]]);
43 std::swap(container[parentPosition], container[position]);
44
45 position = parentPosition;
46 parentPosition = (position - 1) / 2;
47 }
48
49 STORM_LOG_ASSERT(std::is_heap(container.begin(), container.end(), compare), "Heap structure lost.");
50 }
51
52 bool contains(uint64_t element) const {
53 return positions[element] < container.size();
54 }
55
56 bool empty() const {
57 return container.empty();
58 }
59
60 std::size_t size() const {
61 return container.size();
62 }
63
64 const T& top() const {
65 return container.front();
66 }
67
68 void push(uint64_t const& item) {
69 container.emplace_back(item);
70 std::push_heap(container.begin(), container.end(), compare);
71 }
72
73 void pop() {
74 if (container.size() > 1) {
75 // Swap max element to back.
76 std::swap(positions[container.front()], positions[container.back()]);
77 std::swap(container.front(), container.back());
78 container.pop_back();
79
80 // Sift down the element from the top.
81 uint64_t positionToSift = 0;
82 uint64_t child = 2 * positionToSift + 1;
83
84 while (child < container.size()) {
85 if (child + 1 < container.size()) {
86 // Figure out larger child.
87 child = compare(container[child], container[child + 1]) ? child + 1 : child;
88
89 // Check if we need to sift down.
90 if (compare(container[positionToSift], container[child])) {
91 std::swap(positions[container[positionToSift]], positions[container[child]]);
92 std::swap(container[positionToSift], container[child]);
93
94 positionToSift = child;
95 child = 2 * positionToSift + 1;
96 } else {
97 break;
98 }
99 } else if (compare(container[positionToSift], container[child])) {
100 std::swap(positions[container[positionToSift]], positions[container[child]]);
101 std::swap(container[positionToSift], container[child]);
102
103 positionToSift = child;
104 child = 2 * positionToSift + 1;
105 } else {
106 break;
107 }
108 }
109
110 } else {
111 container.pop_back();
112 }
113
114 STORM_LOG_ASSERT(std::is_heap(container.begin(), container.end(), compare), "Heap structure lost.");
115 }
116
118 T item = top();
119 pop();
120 return item;
121 }
122
123 private:
124 bool checkPositions() const {
125 uint64_t position = 0;
126 for (auto const& e : container) {
127 if (positions[e] != position) {
128 return false;
129 }
130 ++position;
131 }
132 return true;
133 }
134
135 void updatePositions() {
136 uint64_t position = 0;
137 for (auto const& e : container) {
138 positions[e] = position;
139 ++position;
140 }
141 }
142};
143} // namespace storage
144} // namespace storm
ConsecutiveUint64DynamicPriorityQueue(uint64_t numberOfIntegers, Compare const &compare)
#define STORM_LOG_ASSERT(cond, message)
Definition macros.h:11
LabParser.cpp.
Definition cli.cpp:18