aGrUM 2.3.2
a C++ library for (probabilistic) graphical models
heap_tpl.h
Go to the documentation of this file.
1/****************************************************************************
2 * This file is part of the aGrUM/pyAgrum library. *
3 * *
4 * Copyright (c) 2005-2025 by *
5 * - Pierre-Henri WUILLEMIN(_at_LIP6) *
6 * - Christophe GONZALES(_at_AMU) *
7 * *
8 * The aGrUM/pyAgrum library is free software; you can redistribute it *
9 * and/or modify it under the terms of either : *
10 * *
11 * - the GNU Lesser General Public License as published by *
12 * the Free Software Foundation, either version 3 of the License, *
13 * or (at your option) any later version, *
14 * - the MIT license (MIT), *
15 * - or both in dual license, as here. *
16 * *
17 * (see https://agrum.gitlab.io/articles/dual-licenses-lgplv3mit.html) *
18 * *
19 * This aGrUM/pyAgrum library is distributed in the hope that it will be *
20 * useful, but WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
21 * INCLUDING BUT NOT LIMITED TO THE WARRANTIES MERCHANTABILITY or FITNESS *
22 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE *
23 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER *
24 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, *
25 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR *
26 * OTHER DEALINGS IN THE SOFTWARE. *
27 * *
28 * See LICENCES for more details. *
29 * *
30 * SPDX-FileCopyrightText: Copyright 2005-2025 *
31 * - Pierre-Henri WUILLEMIN(_at_LIP6) *
32 * - Christophe GONZALES(_at_AMU) *
33 * SPDX-License-Identifier: LGPL-3.0-or-later OR MIT *
34 * *
35 * Contact : info_at_agrum_dot_org *
36 * homepage : http://agrum.gitlab.io *
37 * gitlab : https://gitlab.com/agrumery/agrum *
38 * *
39 ****************************************************************************/
40#pragma once
41
42
49#include <sstream>
50#include <string>
51
52// to ease IDE parser
54
55namespace gum {
56
57 // basic constructor. Creates an empty heap
58 template < typename Val, typename Cmp >
60 _heap_.reserve(capacity);
61
62 GUM_CONSTRUCTOR(Heap);
63 }
64
65 // initializer list constructor
66 template < typename Val, typename Cmp >
67 Heap< Val, Cmp >::Heap(std::initializer_list< Val > list) {
68 _heap_.reserve(list.size());
69 for (const auto& elt: list) {
70 insert(elt);
71 }
72
73 GUM_CONSTRUCTOR(Heap);
74 }
75
76 // copy constructor
77 template < typename Val, typename Cmp >
80 // for debugging purposes
81 GUM_CONS_CPY(Heap);
82 }
83
84 // move constructor
85 template < typename Val, typename Cmp >
87 _heap_(std::move(from._heap_)), _nb_elements_(std::move(from._nb_elements_)),
88 _cmp_(std::move(from._cmp_)) {
89 // for debugging purposes
90 GUM_CONS_MOV(Heap);
91 }
92
93 // destructor
94 template < typename Val, typename Cmp >
96 // for debugging purposes
97 GUM_DESTRUCTOR(Heap);
98 }
99
100 // copy operator
101 template < typename Val, typename Cmp >
103 // avoid self assignment
104 if (this != &from) {
105 try {
106 _heap_ = from._heap_;
107 } catch (...) {
108 _heap_.clear();
109 _nb_elements_ = 0;
110
111 throw;
112 }
113
114 // set the comparison function
115 _cmp_ = from._cmp_;
117
118 // for debugging purposes
119 GUM_OP_CPY(Heap);
120 }
121
122 return *this;
123 }
124
125 // move operator
126 template < typename Val, typename Cmp >
128 // avoid self assignment
129 if (this != &from) {
130 _heap_ = std::move(from._heap_);
131 _nb_elements_ = std::move(from._nb_elements_);
132 _cmp_ = std::move(from._cmp_);
133 }
134
135 return *this;
136 }
137
138 // returns the element at the top of the heap
139 template < typename Val, typename Cmp >
140 INLINE const Val& Heap< Val, Cmp >::top() const {
141 if (!_nb_elements_) { GUM_ERROR(NotFound, "empty heap") }
142
143 return _heap_[0];
144 }
145
146 // returns the number of elements in the heap
147 template < typename Val, typename Cmp >
148 INLINE Size Heap< Val, Cmp >::size() const noexcept {
149 return _nb_elements_;
150 }
151
152 // return the size of the array storing the heap
153 template < typename Val, typename Cmp >
154 INLINE Size Heap< Val, Cmp >::capacity() const noexcept {
155 return Size(_heap_.size());
156 }
157
158 // changes the size of the array storing the heap
159 template < typename Val, typename Cmp >
160 INLINE void Heap< Val, Cmp >::resize(Size new_size) {
161 if (new_size > _nb_elements_) _heap_.reserve(new_size);
162 }
163
164 // removes the element at position 'index' from the heap
165 template < typename Val, typename Cmp >
167 if (index >= _nb_elements_) return;
168
169 // remove the element and put the last element in its place
170 Val last = std::move(_heap_[_nb_elements_ - 1]);
171 _heap_.pop_back();
173
174 if (!_nb_elements_ || (index == _nb_elements_)) return;
175
176 // restore the heap property
177 Size i = index;
178
179 for (Size j = (index << 1) + 1; j < _nb_elements_; i = j, j = (j << 1) + 1) {
180 // let j be the max child
181 if ((j + 1 < _nb_elements_) && _cmp_(_heap_[j + 1], _heap_[j])) ++j;
182
183 // if "last" is smaller than _heap_[j], "last" must be stored at index i
184 if (_cmp_(last, _heap_[j])) break;
185
186 _heap_[i] = std::move(_heap_[j]);
187 }
188
189 _heap_[i] = std::move(last);
190 }
191
192 // removes a given element from the heap (but does not return it)
193 template < typename Val, typename Cmp >
194 INLINE void Heap< Val, Cmp >::erase(const Val& val) {
195 // find val in the heap
196 for (Size i = 0; i < _nb_elements_; ++i)
197 if (_heap_[i] == val) {
198 eraseByPos(i);
199 break;
200 }
201 }
202
203 // removes the top of the heap (but does not return it)
204 template < typename Val, typename Cmp >
206 // if the heap is empty, do nothing
207 if (!_nb_elements_) return;
208 eraseByPos(0);
209 }
210
211 // removes the top element from the heap and return it
212 template < typename Val, typename Cmp >
214 if (!_nb_elements_) { GUM_ERROR(NotFound, "empty heap") }
215
216 Val v = _heap_[0];
217 eraseByPos(0);
218 return v;
219 }
220
221 // after inserting an element at the end of the heap, restore heap property
222 template < typename Val, typename Cmp >
224 // get the element at the end of the heap
225 Size i = _nb_elements_ - 1;
226 Val v = std::move(_heap_[i]);
227
228 // restore the heap property
229 for (Size j = (i - 1) >> 1; i && _cmp_(v, _heap_[j]); i = j, j = (j - 1) >> 1)
230 _heap_[i] = std::move(_heap_[j]);
231
232 _heap_[i] = std::move(v);
233
234 return i;
235 }
236
237 // inserts a new (a copy) element in the heap
238 template < typename Val, typename Cmp >
239 INLINE Size Heap< Val, Cmp >::insert(const Val& val) {
240 // create a new element at the end of the heap
241 _heap_.push_back(val);
243 return _restoreHeap_();
244 }
245
246 // inserts a new (a copy) element in the heap
247 template < typename Val, typename Cmp >
249 // create a new element at the end of the heap
250 _heap_.push_back(std::move(val));
252 return _restoreHeap_();
253 }
254
255 // emplace a new element in the heap
256 template < typename Val, typename Cmp >
257 template < typename... Args >
259 // create a new element at the end of the heap
260 _heap_.emplace_back(std::forward< Args >(args)...);
262 return _restoreHeap_();
263 }
264
265 // indicates whether the heap is empty
266 template < typename Val, typename Cmp >
267 INLINE bool Heap< Val, Cmp >::empty() const noexcept {
268 return (_nb_elements_ == 0);
269 }
270
271 // indicates whether the heap contains a given value
272 template < typename Val, typename Cmp >
273 INLINE bool Heap< Val, Cmp >::contains(const Val& val) const {
274 for (Size i = 0; i < _nb_elements_; ++i)
275 if (_heap_[i] == val) return true;
276
277 return false;
278 }
279
280 // returns the element at index elt from the heap
281 template < typename Val, typename Cmp >
282 INLINE const Val& Heap< Val, Cmp >::operator[](Size index) const {
283 // check if the element exists
284 if (index >= _nb_elements_) { GUM_ERROR(NotFound, "not enough elements in the heap") }
285
286 return _heap_[index];
287 }
288
289 // displays the content of the heap
290 template < typename Val, typename Cmp >
291 std::string Heap< Val, Cmp >::toString() const {
292 bool deja = false;
293 std::stringstream stream;
294 stream << "[";
295
296 for (Size i = 0; i != _nb_elements_; ++i, deja = true) {
297 if (deja) stream << " , ";
298
299 stream << _heap_[i];
300 }
301
302 stream << "]";
303
304 return stream.str();
305 }
306
307 // A \c << operator for Heap
308 template < typename Val, typename Cmp >
309 INLINE std::ostream& operator<<(std::ostream& stream, const Heap< Val, Cmp >& heap) {
310 stream << heap.toString();
311 return stream;
312 }
313
314} /* namespace gum */
Heap data structure.
Definition heap.h:141
Size size() const noexcept
Returns the number of elements in the heap.
Definition heap_tpl.h:148
void eraseTop()
Removes the top of the heap (but does not return it).
Definition heap_tpl.h:205
Val pop()
Removes the top element from the heap and return it.
Definition heap_tpl.h:213
bool contains(const Val &) const
Indicates whether the heap contains a given value.
Definition heap_tpl.h:273
Size _nb_elements_
The number of elements in the heap.
Definition heap.h:371
const Val & operator[](Size index_elt) const
Returns the element at index index_elt from the heap.
Definition heap_tpl.h:282
void resize(Size new_size)
Changes the size of the the internal structure storing the heap.
Definition heap_tpl.h:160
Size emplace(Args &&... args)
Emplace a new element in the heap and returns its index.
Definition heap_tpl.h:258
~Heap()
Class destructor.
Definition heap_tpl.h:95
Size insert(const Val &val)
inserts a new element (actually a copy) in the heap and returns its index
Definition heap_tpl.h:239
Heap< Val, Cmp > & operator=(const Heap< Val, Cmp > &from)
Copy operator.
Definition heap_tpl.h:102
Size capacity() const noexcept
Returns the size of the internal structure storing the heap.
Definition heap_tpl.h:154
Heap(Cmp compare=Cmp(), Size capacity=GUM_HEAP_DEFAULT_CAPACITY)
Basic constructor: creates an empty heap.
Definition heap_tpl.h:59
const Val & top() const
Returns the element at the top of the heap.
Definition heap_tpl.h:140
bool empty() const noexcept
Indicates whether the heap is empty.
Definition heap_tpl.h:267
std::string toString() const
Definition heap_tpl.h:291
void eraseByPos(Size index)
Removes the element positioned at "index" from the heap.
Definition heap_tpl.h:166
Cmp _cmp_
Comparison function.
Definition heap.h:374
void erase(const Val &val)
Removes a given element from the heap (but does not return it).
Definition heap_tpl.h:194
Size _restoreHeap_()
After inserting an element at the end of the heap, restore heap property.
Definition heap_tpl.h:223
std::vector< Val > _heap_
An array storing all the elements of the heap.
Definition heap.h:368
Exception : the element we looked for cannot be found.
#define GUM_ERROR(type, msg)
Definition exceptions.h:72
std::size_t Size
In aGrUM, hashed values are unsigned long int.
Definition types.h:74
Heaps definition.
gum is the global namespace for all aGrUM entities
Definition agrum.h:46
std::ostream & operator<<(std::ostream &stream, const AVLTree< Val, Cmp > &tree)
display the content of a tree
Definition AVLTree.h:913