NeuralEngine A Game Engine with embeded Machine Learning algorithms based on Gaussian Processes. |

NeMinHeap.inl
1
11 template <typename KeyType, typename ValueType>
12 MinHeap<KeyType, ValueType>::MinHeap(int maxElements)
13{
14 Reset(maxElements);
15}
16
17 template <typename KeyType, typename ValueType>
18 MinHeap<KeyType, ValueType>::MinHeap(MinHeap const& minHeap)
19{
20 *this = minHeap;
21}
22
23 template <typename KeyType, typename ValueType>
24 MinHeap<KeyType, ValueType>& MinHeap<KeyType, ValueType>::operator=(MinHeap const& minHeap)
25{
26 mNumElements = minHeap.mNumElements;
27 mRecords = minHeap.mRecords;
28 mPointers.resize(minHeap.mPointers.size());
29 for (auto& record : mRecords)
30 {
31 mPointers[record.index] = &record;
32 }
33 return *this;
34}
35
36 template <typename KeyType, typename ValueType>
37 void MinHeap<KeyType, ValueType>::Reset(int maxElements)
38{
39 mNumElements = 0;
40 if (maxElements > 0)
41 {
42 mRecords.resize(maxElements);
43 mPointers.resize(maxElements);
44 for (int i = 0; i < maxElements; ++i)
45 {
46 mPointers[i] = &mRecords[i];
47 mPointers[i]->index = i;
48 }
49 }
50 else
51 {
52 mRecords.clear();
53 mPointers.clear();
54 }
55}
56
57 template <typename KeyType, typename ValueType>
58 inline int MinHeap<KeyType, ValueType>::GetNumElements() const
59{
60 return mNumElements;
61}
62
63 template <typename KeyType, typename ValueType>
64 inline bool MinHeap<KeyType, ValueType>::GetMinimum(KeyType& key, ValueType& value) const
65{
66 if (mNumElements > 0)
67 {
68 key = mPointers[0]->key;
69 value = mPointers[0]->value;
70 return true;
71 }
72 else
73 {
74 return false;
75 }
76}
77
78 template <typename KeyType, typename ValueType>
79 typename MinHeap<KeyType, ValueType>::Record*
80 MinHeap<KeyType, ValueType>::Insert(KeyType const& key, ValueType const& value)
81{
82 // Return immediately when the heap is full.
83 if (mNumElements == static_cast<int>(mRecords.size()))
84 {
85 return nullptr;
86 }
87
88 // Store the input information in the last heap record, which is the last
89 // leaf in the tree.
90 int child = mNumElements++;
91 Record * record = mPointers[child];
92 record->key = key;
93 record->value = value;
94
95 // Propagate the information toward the root of the tree until it reaches
96 // its correct position, thus restoring the tree to a valid heap.
97 while (child > 0)
98 {
99 int parent = (child - 1) / 2;
100 if (mPointers[parent]->value <= value)
101 {
102 // The parent has a value smaller than or equal to the child's
103 // value, so we now have a valid heap.
104 break;
105 }
106
107 // The parent has a larger value than the child's value. Swap the
108 // parent and child:
109
110 // Move the parent into the child's slot.
111 mPointers[child] = mPointers[parent];
112 mPointers[child]->index = child;
113
114 // Move the child into the parent's slot.
115 mPointers[parent] = record;
116 mPointers[parent]->index = parent;
117
118 child = parent;
119 }
120
121 return mPointers[child];
122}
123
124 template <typename KeyType, typename ValueType>
125 bool MinHeap<KeyType, ValueType>::Remove(KeyType& key, ValueType& value)
126{
127 // Return immediately when the heap is empty.
128 if (mNumElements == 0)
129 {
130 return false;
131 }
132
133 // Get the information from the root of the heap.
134 Record* root = mPointers[0];
135 key = root->key;
136 value = root->value;
137
138 // Restore the tree to a heap. Abstractly, record is the new root of
139 // the heap. It is moved down the tree via parent-child swaps until it
140 // is in a location that restores the tree to a heap.
141 int last = --mNumElements;
142 Record* record = mPointers[last];
143 int parent = 0, child = 1;
144 while (child <= last)
145 {
146 if (child < last)
147 {
148 // Select the child with smallest value to be the one that is
149 // swapped with the parent, if necessary.
150 int childP1 = child + 1;
151 if (mPointers[childP1]->value < mPointers[child]->value)
152 {
153 child = childP1;
154 }
155 }
156
157 if (record->value <= mPointers[child]->value)
158 {
159 // The tree is now a heap.
160 break;
161 }
162
163 // Move the child into the parent's slot.
164 mPointers[parent] = mPointers[child];
165 mPointers[parent]->index = parent;
166
167 parent = child;
168 child = 2 * child + 1;
169 }
170
171 // The previous 'last' record was moved to the root and propagated down
172 // the tree to its final resting place, restoring the tree to a heap.
173 // The slot mPointers[parent] is that resting place.
174 mPointers[parent] = record;
175 mPointers[parent]->index = parent;
176
177 // The old root record must not be lost. Attach it to the slot that
178 // contained the old last record.
179 mPointers[last] = root;
180 mPointers[last]->index = last;
181 return true;
182}
183
184 template <typename KeyType, typename ValueType>
185 void MinHeap<KeyType, ValueType>::Update(Record* record, ValueType const& value)
186{
187 // Return immediately on invalid record.
188 if (!record)
189 {
190 return;
191 }
192
193 int parent, child, childP1, maxChild;
194
195 if (record->value < value)
196 {
197 record->value = value;
198
199 // The new value is larger than the old value. Propagate it toward
200 // the leaves.
201 parent = record->index;
202 child = 2 * parent + 1;
203 while (child < mNumElements)
204 {
205 // At least one child exists. Locate the one of maximum value.
206 childP1 = child + 1;
207 if (childP1 < mNumElements)
208 {
209 // Two children exist.
210 if (mPointers[child]->value <= mPointers[childP1]->value)
211 {
212 maxChild = child;
213 }
214 else
215 {
216 maxChild = childP1;
217 }
218 }
219 else
220 {
221 // One child exists.
222 maxChild = child;
223 }
224
225 if (value <= mPointers[maxChild]->value)
226 {
227 // The new value is in the correct place to restore the tree
228 // to a heap.
229 break;
230 }
231
232 // The child has a larger value than the parent's value. Swap
233 // the parent and child:
234
235 // Move the child into the parent's slot.
236 mPointers[parent] = mPointers[maxChild];
237 mPointers[parent]->index = parent;
238
239 // Move the parent into the child's slot.
240 mPointers[maxChild] = record;
241 mPointers[maxChild]->index = maxChild;
242
243 parent = maxChild;
244 child = 2 * parent + 1;
245 }
246 }
247 else if (value < record->value)
248 {
249 record->value = value;
250
251 // The new weight is smaller than the old weight. Propagate it
252 // toward the root.
253 child = record->index;
254 while (child > 0)
255 {
256 // A parent exists.
257 parent = (child - 1) / 2;
258
259 if (mPointers[parent]->value <= value)
260 {
261 // The new value is in the correct place to restore the tree
262 // to a heap.
263 break;
264 }
265
266 // The parent has a smaller value than the child's value. Swap
267 // the child and parent:
268
269 // Move the parent into the child's slot.
270 mPointers[child] = mPointers[parent];
271 mPointers[child]->index = child;
272
273 // Move the child into the parent's slot.
274 mPointers[parent] = record;
275 mPointers[parent]->index = parent;
276
277 child = parent;
278 }
279 }
280}
281
282 template <typename KeyType, typename ValueType>
283 bool MinHeap<KeyType, ValueType>::IsValid() const
284{
285 for (int child = 0; child < mNumElements; ++child)
286 {
287 int parent = (child - 1) / 2;
288 if (parent > 0)
289 {
290 if (mPointers[child]->value < mPointers[parent]->value)
291 {
292 return false;
293 }
294
295 if (mPointers[parent]->index != parent)
296 {
297 return false;
298 }
299 }
300 }
301
302 return true;
303}
NeuralEngine::MinHeap
Minimum heap binary tree.
Definition: NeMinHeap.h:90
NeuralEngine::MinHeap::Record
Definition: NeMinHeap.h:93