33 template <
typename Val,
typename Priority,
typename Cmp,
typename Alloc >
35 Cmp compare,
Size capacity) :
36 __indices(capacity >> 1, true, false),
38 __heap.reserve(capacity);
45 template <
typename Val,
typename Priority,
typename Cmp,
typename Alloc >
47 std::initializer_list< std::pair< Val, Priority > > list) :
48 __indices(
Size(list.size()) / 2, true, false) {
50 __heap.reserve(list.size());
51 for (
const auto& elt : list) {
52 insert(elt.first, elt.second);
60 template <
typename Val,
typename Priority,
typename Cmp,
typename Alloc >
64 __indices(from.__indices), __nb_elements(from.__nb_elements),
70 for (
const auto& val_and_index : __indices) {
71 const Val* val = &(val_and_index.first);
72 const std::vector< Size >& vect = val_and_index.second;
73 for (
auto index : vect) {
74 __heap[index].second = val;
80 template <
typename Val,
typename Priority,
typename Cmp,
typename Alloc >
81 template <
typename OtherAlloc >
84 __indices(from.__indices),
85 __nb_elements(from.__nb_elements), __cmp(from.__cmp) {
91 __heap.reserve(from.
__heap.size());
92 for (
const auto& elt : from.
__heap) {
93 __heap.push_back(elt);
95 for (
const auto& val_and_index : __indices) {
96 const Val* val = &(val_and_index.first);
97 const std::vector< Size >& vect = val_and_index.second;
98 for (
auto index : vect) {
99 __heap[index].second = val;
106 template <
typename Val,
typename Priority,
typename Cmp,
typename Alloc >
109 __heap(
std::move(from.__heap)),
110 __indices(
std::move(from.__indices)),
111 __nb_elements(
std::move(from.__nb_elements)), __cmp(
std::move(from.__cmp)) {
117 template <
typename Val,
typename Priority,
typename Cmp,
typename Alloc >
124 template <
typename Val,
typename Priority,
typename Cmp,
typename Alloc >
141 for (
const auto& val_and_index : __indices) {
142 const Val* val = &(val_and_index.first);
143 const std::vector< Size >& vect = val_and_index.second;
144 for (
auto index : vect) {
145 __heap[index].second = val;
160 template <
typename Val,
typename Priority,
typename Cmp,
typename Alloc >
161 template <
typename OtherAlloc >
178 __heap.reserve(from.
__heap.size());
179 for (
const auto& elt : from.
__heap) {
180 __heap.push_back(elt);
182 for (
const auto& val_and_index : __indices) {
183 const Val* val = &(val_and_index.first);
184 const std::vector< Size >& vect = val_and_index.second;
185 for (
auto index : vect) {
186 __heap[index].second = val;
201 template <
typename Val,
typename Priority,
typename Cmp,
typename Alloc >
210 __cmp = std::move(from.__cmp);
211 __indices = std::move(from.__indices);
212 __heap = std::move(from.__heap);
213 __nb_elements = std::move(from.__nb_elements);
220 template <
typename Val,
typename Priority,
typename Cmp,
typename Alloc >
224 return *(__heap[0].second);
228 template <
typename Val,
typename Priority,
typename Cmp,
typename Alloc >
229 INLINE
const Priority&
233 return __heap[0].first;
237 template <
typename Val,
typename Priority,
typename Cmp,
typename Alloc >
240 return __nb_elements;
244 template <
typename Val,
typename Priority,
typename Cmp,
typename Alloc >
247 return Size(__heap.capacity());
251 template <
typename Val,
typename Priority,
typename Cmp,
typename Alloc >
254 if (new_size < __nb_elements)
return;
256 __heap.reserve(new_size);
257 __indices.
resize(new_size / 2);
261 template <
typename Val,
typename Priority,
typename Cmp,
typename Alloc >
269 template <
typename Val,
typename Priority,
typename Cmp,
typename Alloc >
271 if (index >= __nb_elements)
return;
274 const Val& del_val = *(__heap[index].second);
275 std::vector< Size >& vect_index = __indices[del_val];
276 if (vect_index.size() == 1)
277 __indices.
erase(del_val);
279 for (
auto& v_index : vect_index) {
280 if (v_index == index) {
281 v_index = vect_index.back();
282 vect_index.pop_back();
289 std::pair< Priority, const Val* > last = std::move(__heap.back());
293 if (!__nb_elements || (index == __nb_elements))
return;
298 for (
Size j = (index << 1) + 1; j < __nb_elements; i = j, j = (j << 1) + 1) {
300 if ((j + 1 < __nb_elements) && __cmp(__heap[j + 1].first, __heap[j].first))
304 if (__cmp(last.first, __heap[j].first))
break;
307 __heap[i] = std::move(__heap[j]);
308 std::vector< Size >& vect_index = __indices[*(__heap[i].second)];
309 for (
auto& v_index : vect_index) {
318 __heap[i] = std::move(last);
319 std::vector< Size >& last_indices = __indices[*(__heap[i].second)];
320 for (
auto& v_index : last_indices) {
321 if (v_index == __nb_elements) {
329 template <
typename Val,
typename Priority,
typename Cmp,
typename Alloc >
333 eraseByPos(__indices[val][0]);
338 template <
typename Val,
typename Priority,
typename Cmp,
typename Alloc >
344 template <
typename Val,
typename Priority,
typename Cmp,
typename Alloc >
348 Val v = *(__heap[0].second);
355 template <
typename Val,
typename Priority,
typename Cmp,
typename Alloc >
363 template <
typename Val,
typename Priority,
typename Cmp,
typename Alloc >
365 const Val& val,
const Priority& priority) {
368 std::vector< Size >* new_vect;
369 if (!__indices.exists(val)) {
370 auto& new_elt = __indices.
insert(val, std::vector< Size >());
371 new_val = &(new_elt.first);
372 new_vect = &(new_elt.second);
374 new_val = &(__indices.key(val));
375 new_vect = &(__indices[val]);
379 new_vect->push_back(0);
381 if (new_vect->empty()) { __indices.erase(val); }
386 __heap.push_back(std::pair< Priority, const Val* >(priority, new_val));
388 if (new_vect->size() == 1) { __indices.erase(val); }
392 std::pair< Priority, const Val* > new_heap_val =
393 std::move(__heap[__nb_elements]);
397 Size i = __nb_elements - 1;
399 for (
Size j = (i - 1) >> 1; i && __cmp(new_heap_val.first, __heap[j].first);
400 i = j, j = (j - 1) >> 1) {
401 __heap[i] = std::move(__heap[j]);
402 std::vector< Size >& vect_index = __indices[*(__heap[i].second)];
403 for (
auto& index : vect_index) {
412 __heap[i].first = std::move(new_heap_val.first);
413 __heap[i].second = new_val;
414 new_vect->back() = i;
420 template <
typename Val,
typename Priority,
typename Cmp,
typename Alloc >
423 Priority&& priority) {
426 std::vector< Size >* new_vect;
427 if (!__indices.exists(val)) {
428 auto& new_elt = __indices.
insert(std::move(val), std::vector< Size >());
429 new_val = &(new_elt.first);
430 new_vect = &(new_elt.second);
432 new_val = &(__indices.key(val));
433 new_vect = &(__indices[val]);
437 new_vect->push_back(0);
439 if (new_vect->empty()) { __indices.erase(*new_val); }
445 std::pair< Priority, const Val* >(std::move(priority), new_val));
447 if (new_vect->size() == 1) { __indices.erase(*new_val); }
451 std::pair< Priority, const Val* > new_heap_val =
452 std::move(__heap[__nb_elements]);
456 Size i = __nb_elements - 1;
458 for (
Size j = (i - 1) >> 1; i && __cmp(new_heap_val.first, __heap[j].first);
459 i = j, j = (j - 1) >> 1) {
460 __heap[i] = std::move(__heap[j]);
461 std::vector< Size >& vect_index = __indices[*(__heap[i].second)];
462 for (
auto& index : vect_index) {
471 __heap[i].first = std::move(new_heap_val.first);
472 __heap[i].second = new_val;
473 new_vect->back() = i;
479 template <
typename Val,
typename Priority,
typename Cmp,
typename Alloc >
480 template <
typename... Args >
483 std::pair< Val, Priority > new_elt =
484 std::make_pair< Val, Priority >(std::forward< Args >(args)...);
485 return insert(std::move(new_elt.first), std::move(new_elt.second));
489 template <
typename Val,
typename Priority,
typename Cmp,
typename Alloc >
492 return (__nb_elements == 0);
496 template <
typename Val,
typename Priority,
typename Cmp,
typename Alloc >
498 const Val& val)
const {
499 return __indices.exists(val);
503 template <
typename Val,
typename Priority,
typename Cmp,
typename Alloc >
506 if (index >= __nb_elements) {
510 return *(__heap[index].second);
514 template <
typename Val,
typename Priority,
typename Cmp,
typename Alloc >
517 std::stringstream stream;
520 for (
Size i = 0; i != __nb_elements; ++i, deja =
true) {
521 if (deja) stream <<
" , ";
523 stream <<
"(" << __heap[i].first <<
" , " << *(__heap[i].second) <<
")";
532 template <
typename Val,
typename Priority,
typename Cmp,
typename Alloc >
534 Size index,
const Priority& new_priority) {
536 if (index >= __nb_elements) {
541 const Val* val = __heap[index].second;
547 for (
Size j = (i - 1) >> 1; i && __cmp(new_priority, __heap[j].first);
548 i = j, j = (j - 1) >> 1) {
549 __heap[i] = std::move(__heap[j]);
550 std::vector< Size >& vect_index = __indices[*(__heap[i].second)];
551 for (
auto& idx : vect_index) {
560 for (
Size j = (i << 1) + 1; j < __nb_elements; i = j, j = (j << 1) + 1) {
562 if ((j + 1 < __nb_elements) && __cmp(__heap[j + 1].first, __heap[j].first))
566 if (__cmp(new_priority, __heap[j].first))
break;
569 __heap[i] = std::move(__heap[j]);
570 std::vector< Size >& vect_index = __indices[*(__heap[i].second)];
571 for (
auto& idx : vect_index) {
580 __heap[i].first = new_priority;
581 __heap[i].second = val;
582 std::vector< Size >& vect_index = __indices[*(__heap[i].second)];
583 for (
auto& idx : vect_index) {
594 template <
typename Val,
typename Priority,
typename Cmp,
typename Alloc >
596 Size index, Priority&& new_priority) {
598 if (index >= __nb_elements) {
603 const Val* val = __heap[index].second;
609 for (
Size j = (i - 1) >> 1; i && __cmp(new_priority, __heap[j].first);
610 i = j, j = (j - 1) >> 1) {
611 __heap[i] = std::move(__heap[j]);
612 std::vector< Size >& vect_index = __indices[*(__heap[i].second)];
613 for (
auto& idx : vect_index) {
622 for (
Size j = (i << 1) + 1; j < __nb_elements; i = j, j = (j << 1) + 1) {
624 if ((j + 1 < __nb_elements) && __cmp(__heap[j + 1].first, __heap[j].first))
628 if (__cmp(new_priority, __heap[j].first))
break;
631 __heap[i] = std::move(__heap[j]);
632 std::vector< Size >& vect_index = __indices[*(__heap[i].second)];
633 for (
auto& idx : vect_index) {
642 __heap[i].first = std::move(new_priority);
643 __heap[i].second = val;
644 std::vector< Size >& vect_index = __indices[*(__heap[i].second)];
645 for (
auto& idx : vect_index) {
656 template <
typename Val,
typename Priority,
typename Cmp,
typename Alloc >
658 const Val& elt,
const Priority& new_priority) {
659 std::vector< Size >& vect_index = __indices[elt];
661 for (
auto index : vect_index) {
662 setPriorityByPos(index, new_priority);
667 template <
typename Val,
typename Priority,
typename Cmp,
typename Alloc >
669 const Val& elt)
const {
670 return __heap[__indices[elt][0]].first;
674 template <
typename Val,
typename Priority,
typename Cmp,
typename Alloc >
Priority queues in which the same element can appear several times.
INLINE std::ostream & operator<<(std::ostream &stream, const MultiPriorityQueue< Val, Priority, Cmp, Alloc > &queue)
std::vector< std::pair< Priority, const Val *>, HeapAlloc > __heap
An array storing all the elements of the heap as well as their score.
friend class MultiPriorityQueue
Making all MultiPriorityQueue friend with themselves.
Size __nb_elements
The number of elements in the heap.
std::string toString() const
Displays the content of the queue.
Cmp __cmp
Comparison function.
void clear()
Removes all the elements from the queue.
void erase(const Val &val)
Removes a given element from the priority queue (but does not return it).
gum is the global namespace for all aGrUM entities
The class for generic Hash Tables.
Size insert(const Val &val, const Priority &priority)
Inserts a new (a copy) element in the priority queue.
void resize(Size new_size)
Changes the size of the internal structure storing the priority queue.
std::size_t Size
In aGrUM, hashed values are unsigned long int.
A MultiPriorityQueue is a heap in which each element has a mutable priority and duplicates are allowe...
HashTable< Val, std::vector< Size >, IndexAlloc > __indices
A hashtable for quickly finding the elements by their value.
#define GUM_ERROR(type, msg)