Aleph-w 3.0
A C++ Library for Data Structures and Algorithms
Loading...
Searching...
No Matches
heap_example.C
Go to the documentation of this file.
1
2/*
3 Aleph_w
4
5 Data structures & Algorithms
6 version 2.0.0b
7 https://github.com/lrleon/Aleph-w
8
9 This file is part of Aleph-w library
10
11 Copyright (c) 2002-2026 Leandro Rabindranath Leon
12
13 Permission is hereby granted, free of charge, to any person obtaining a copy
14 of this software and associated documentation files (the "Software"), to deal
15 in the Software without restriction, including without limitation the rights
16 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
17 copies of the Software, and to permit persons to whom the Software is
18 furnished to do so, subject to the following conditions:
19
20 The above copyright notice and this permission notice shall be included in all
21 copies or substantial portions of the Software.
22
23 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
24 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
26 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
27 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
28 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
29 SOFTWARE.
30*/
31
32
204#include <iostream>
205#include <iomanip>
206#include <string>
207#include <vector>
208#include <chrono>
209#include <random>
210#include <tpl_dynBinHeap.H>
211#include <tpl_fibonacci_heap.H>
212#include <tclap/CmdLine.h>
213
214using namespace std;
215using namespace Aleph;
216
220struct Task
221{
222 string name;
223 int priority; // Lower = higher priority
225
226 Task() : name(""), priority(0), duration_ms(0) {}
227 Task(const string& n, int p, int d) : name(n), priority(p), duration_ms(d) {}
228
229 bool operator<(const Task& other) const { return priority < other.priority; }
230 bool operator>(const Task& other) const { return priority > other.priority; }
231};
232
233ostream& operator<<(ostream& os, const Task& t)
234{
235 return os << t.name << " (priority=" << t.priority << ", " << t.duration_ms << "ms)";
236}
237
242{
243 cout << "\n" << string(60, '=') << endl;
244 cout << "Binary Heap: Basic Operations" << endl;
245 cout << string(60, '=') << endl;
246
247 cout << "\n--- Integer Min-Heap ---" << endl;
248
249 DynBinHeap<int> heap;
250
251 // Insert elements
252 vector<int> values = {5, 3, 8, 1, 9, 2, 7, 4, 6};
253 cout << "Inserting: ";
254 for (int v : values)
255 {
256 cout << v << " ";
257 heap.insert(v);
258 }
259 cout << endl;
260
261 cout << "Heap size: " << heap.size() << endl;
262 cout << "Minimum: " << heap.top() << endl;
263
264 // Extract all in sorted order
265 cout << "\nExtracting in order: ";
266 while (not heap.is_empty())
267 {
268 cout << heap.get() << " "; // get() removes and returns
269 }
270 cout << endl;
271
272 cout << "\n--- Task Priority Queue ---" << endl;
273
275
276 // Add tasks with different priorities
277 task_queue.insert(Task("Background sync", 5, 1000));
278 task_queue.insert(Task("User input", 1, 10));
279 task_queue.insert(Task("Network request", 3, 200));
280 task_queue.insert(Task("Logging", 4, 50));
281 task_queue.insert(Task("Critical alert", 0, 5));
282 task_queue.insert(Task("Data processing", 2, 500));
283
284 cout << "Processing tasks by priority:" << endl;
285 int order = 1;
286 while (not task_queue.is_empty())
287 {
288 Task t = task_queue.get();
289 cout << " " << order++ << ". " << t << endl;
290 }
291}
292
297{
298 cout << "\n" << string(60, '=') << endl;
299 cout << "Fibonacci Heap: Advanced Operations" << endl;
300 cout << string(60, '=') << endl;
301
303
304 // Insert elements and keep handles for decrease-key
305 cout << "\n--- Insert and Decrease-Key ---" << endl;
306
308
309 cout << "Inserting: ";
310 for (int v : {50, 30, 80, 10, 90, 20, 70})
311 {
312 cout << v << " ";
313 handles.push_back(fib_heap.insert(v));
314 }
315 cout << endl;
316
317 cout << "Current minimum: " << fib_heap.get_min() << endl;
318
319 // Decrease key of 80 to 5
320 cout << "\nDecreasing 80 to 5..." << endl;
321 fib_heap.decrease_key(handles[2], 5); // Handle for 80
322 cout << "New minimum: " << fib_heap.get_min() << endl;
323
324 // Decrease key of 90 to 3
325 cout << "Decreasing 90 to 3..." << endl;
326 fib_heap.decrease_key(handles[4], 3); // Handle for 90
327 cout << "New minimum: " << fib_heap.get_min() << endl;
328
329 cout << "\nExtracting all: ";
330 while (not fib_heap.is_empty())
331 cout << fib_heap.extract_min() << " ";
332 cout << endl;
333
334 // Demonstrate merge operation
335 cout << "\n--- Heap Merge (O(1) in Fibonacci Heap) ---" << endl;
336
338
339 cout << "Heap 1: ";
340 for (int v : {10, 30, 50})
341 {
342 cout << v << " ";
343 (void) heap1.insert(v);
344 }
345 cout << endl;
346
347 cout << "Heap 2: ";
348 for (int v : {20, 40, 60})
349 {
350 cout << v << " ";
351 (void) heap2.insert(v);
352 }
353 cout << endl;
354
355 heap1.merge(heap2);
356 cout << "After merge (heap1 absorbs heap2):" << endl;
357 cout << " Heap 1 size: " << heap1.size() << endl;
358 cout << " Heap 1 min: " << heap1.get_min() << endl;
359 cout << " Heap 2 size: " << heap2.size() << " (empty)" << endl;
360
361 cout << "\nExtracting merged heap: ";
362 while (not heap1.is_empty())
363 cout << heap1.extract_min() << " ";
364 cout << endl;
365}
366
371{
372 cout << "\n" << string(60, '=') << endl;
373 cout << "Practical Example: Event-Driven Simulation" << endl;
374 cout << string(60, '=') << endl;
375
376 struct Event
377 {
378 double time;
379 string description;
380
381 Event() : time(0), description("") {}
382 Event(double t, const string& d) : time(t), description(d) {}
383
384 bool operator<(const Event& other) const { return time < other.time; }
385 };
386
388
389 // Schedule events in random order
390 event_queue.insert(Event(1.5, "Customer arrives"));
391 event_queue.insert(Event(0.5, "Open store"));
392 event_queue.insert(Event(3.0, "Customer leaves"));
393 event_queue.insert(Event(2.0, "Process payment"));
394 event_queue.insert(Event(4.5, "Delivery arrives"));
395 event_queue.insert(Event(2.5, "Answer phone"));
396 event_queue.insert(Event(5.0, "Close store"));
397
398 cout << "\nSimulation timeline:" << endl;
399 cout << string(40, '-') << endl;
400
401 while (not event_queue.is_empty())
402 {
403 Event e = event_queue.get();
404 cout << fixed << setprecision(1);
405 cout << " t=" << setw(4) << e.time << ": " << e.description << endl;
406 }
407}
408
413{
414 cout << "\n" << string(60, '=') << endl;
415 cout << "Performance Comparison (n = " << n << ")" << endl;
416 cout << string(60, '=') << endl;
417
418 random_device rd;
419 mt19937 gen(rd());
421
422 vector<int> values(n);
423 for (int i = 0; i < n; ++i)
424 values[i] = dis(gen);
425
426 // Binary Heap
427 {
428 DynBinHeap<int> heap;
429
430 auto start = chrono::high_resolution_clock::now();
431
432 for (int v : values)
433 heap.insert(v);
434
435 auto mid = chrono::high_resolution_clock::now();
436
437 while (not heap.is_empty())
438 (void)heap.get();
439
440 auto end = chrono::high_resolution_clock::now();
441
442 auto insert_time = chrono::duration_cast<chrono::microseconds>(mid - start).count();
443 auto extract_time = chrono::duration_cast<chrono::microseconds>(end - mid).count();
444
445 cout << "\nBinary Heap (DynBinHeap):" << endl;
446 cout << " Insert " << n << " elements: " << insert_time << " us" << endl;
447 cout << " Extract all elements: " << extract_time << " us" << endl;
448 cout << " Total: " << (insert_time + extract_time) << " us" << endl;
449 }
450
451 // Fibonacci Heap
452 {
454
455 auto start = chrono::high_resolution_clock::now();
456
457 for (int v : values)
458 (void) heap.insert(v);
459
460 auto mid = chrono::high_resolution_clock::now();
461
462 while (not heap.is_empty())
463 (void)heap.extract_min();
464
465 auto end = chrono::high_resolution_clock::now();
466
467 auto insert_time = chrono::duration_cast<chrono::microseconds>(mid - start).count();
468 auto extract_time = chrono::duration_cast<chrono::microseconds>(end - mid).count();
469
470 cout << "\nFibonacci Heap:" << endl;
471 cout << " Insert " << n << " elements: " << insert_time << " us" << endl;
472 cout << " Extract all elements: " << extract_time << " us" << endl;
473 cout << " Total: " << (insert_time + extract_time) << " us" << endl;
474 }
475
476 // Decrease-key comparison
477 cout << "\n--- Decrease-Key Performance ---" << endl;
478
479 int decreases = n / 2;
480 vector<int> decrease_amounts(decreases);
481 for (int i = 0; i < decreases; ++i)
483
484 // Fibonacci Heap with decrease-key
485 {
488
489 for (int i = 0; i < n; ++i)
490 handles[i] = heap.insert(values[i] + n * 10); // Start with large values
491
492 auto start = chrono::high_resolution_clock::now();
493
494 for (int i = 0; i < decreases; ++i)
495 {
496 // Decrease key to a smaller value
498 }
499
500 auto end = chrono::high_resolution_clock::now();
501 auto time = chrono::duration_cast<chrono::microseconds>(end - start).count();
502
503 cout << "\nFibonacci Heap decrease-key (" << decreases << " operations): " << time << " us" << endl;
504 cout << " Average per decrease-key: " << (time * 1000.0 / decreases) << " ns" << endl;
505 }
506
507 cout << "\n--- Analysis ---" << endl;
508 cout << "Binary Heap: Better cache locality, simpler, good for general use" << endl;
509 cout << "Fibonacci Heap: Better for algorithms with many decrease-key ops" << endl;
510 cout << " (e.g., Dijkstra, Prim where decrease-key dominates)" << endl;
511}
512
517{
518 cout << "\n" << string(60, '=') << endl;
519 cout << "Max-Heap: Largest Element First" << endl;
520 cout << string(60, '=') << endl;
521
522 // Use greater<int> for max-heap behavior
524
525 cout << "\nInserting: ";
526 for (int v : {5, 3, 8, 1, 9, 2, 7})
527 {
528 cout << v << " ";
529 max_heap.insert(v);
530 }
531 cout << endl;
532
533 cout << "Maximum: " << max_heap.top() << endl;
534
535 cout << "Extracting in descending order: ";
536 while (not max_heap.is_empty())
537 cout << max_heap.get() << " ";
538 cout << endl;
539
540 // Fibonacci max-heap
542
543 cout << "\nFibonacci Max-Heap: ";
544 for (int v : {15, 13, 18, 11, 19, 12, 17})
545 {
546 cout << v << " ";
547 (void) fib_max.insert(v);
548 }
549 cout << endl;
550
551 cout << "Maximum: " << fib_max.get_min() << endl; // "min" is max in max-heap
552 cout << "Extracting: ";
553 while (not fib_max.is_empty())
554 cout << fib_max.extract_min() << " ";
555 cout << endl;
556}
557
558int main(int argc, char* argv[])
559{
560 try
561 {
562 TCLAP::CmdLine cmd("Heap Data Structures Example", ' ', "1.0");
563
564 TCLAP::ValueArg<int> nArg("n", "count",
565 "Number of elements for performance test", false, 10000, "int");
566 TCLAP::SwitchArg basicArg("b", "basic",
567 "Show basic binary heap operations", false);
568 TCLAP::SwitchArg fibArg("f", "fibonacci",
569 "Show Fibonacci heap operations", false);
570 TCLAP::SwitchArg simArg("s", "simulation",
571 "Show event simulation example", false);
572 TCLAP::SwitchArg perfArg("p", "performance",
573 "Run performance comparison", false);
574 TCLAP::SwitchArg maxArg("m", "max",
575 "Show max-heap examples", false);
576 TCLAP::SwitchArg allArg("a", "all",
577 "Run all demos", false);
578
579 cmd.add(nArg);
580 cmd.add(basicArg);
581 cmd.add(fibArg);
582 cmd.add(simArg);
583 cmd.add(perfArg);
584 cmd.add(maxArg);
585 cmd.add(allArg);
586
587 cmd.parse(argc, argv);
588
589 int n = nArg.getValue();
590 bool runBasic = basicArg.getValue();
591 bool runFib = fibArg.getValue();
592 bool runSim = simArg.getValue();
593 bool runPerf = perfArg.getValue();
594 bool runMax = maxArg.getValue();
595 bool runAll = allArg.getValue();
596
598 runAll = true;
599
600 cout << "=== Priority Queues: Binary Heap vs Fibonacci Heap ===" << endl;
601
602 if (runAll or runBasic)
604
605 if (runAll or runFib)
607
608 if (runAll or runSim)
610
611 if (runAll or runMax)
613
614 if (runAll or runPerf)
616
617 cout << "\n=== Summary ===" << endl;
618 cout << "DynBinHeap: General-purpose, simple, cache-friendly" << endl;
619 cout << "Fibonacci_Heap: O(1) amortized decrease-key, best for graph algorithms" << endl;
620 cout << "Use DynBinHeap for most cases; Fibonacci for Dijkstra/Prim with many updates" << endl;
621
622 return 0;
623 }
624 catch (TCLAP::ArgException& e)
625 {
626 cerr << "Error: " << e.error() << " for arg " << e.argId() << endl;
627 return 1;
628 }
629}
630
bool operator<(const Time &l, const Time &r)
Definition ah-time.H:142
int main()
Dynamic heap of elements of type T ordered by a comparison functor.
T & top() const
Return a reference to the smallest element.
T get()
Alias for getMin().
T & insert(const T &item)
Insert a copy of item into the heap.
T & top() const
Definition htlist.H:1683
T & insert(const T &item)
Insert a new item by copy.
Definition htlist.H:1502
Implementation of a Fibonacci Heap priority queue.
Node * insert(const T &val)
Inserts a new element (copy).
T extract_min()
Extracts and returns the minimum element.
void decrease_key(Node *x, const T &k)
Decreases the key of a node.
bool is_empty() const noexcept
Checks if the heap is empty.
bool is_empty() const noexcept
const size_t & size() const noexcept
constexpr bool is_empty() const noexcept
Return true if list is empty.
Definition htlist.H:523
size_t size() const noexcept
Count the number of elements of the list.
Definition htlist.H:1319
void demo_max_heap()
Demonstrate max-heap usage.
void demo_event_simulation()
Practical example: Event-driven simulation.
void demo_binary_heap()
Demonstrate basic binary heap operations.
void demo_fibonacci_heap()
Demonstrate Fibonacci heap operations.
void demo_performance_comparison(int n)
Performance comparison between heap types.
Main namespace for Aleph-w library functions.
Definition ah-arena.H:89
std::ostream & operator<<(std::ostream &osObject, const Field< T > &rightOp)
Definition ahField.H:121
DynList< T > maps(const C &c, Op op)
Classic map operation.
STL namespace.
Task with priority for job scheduling.
int duration_ms
bool operator>(const Task &other) const
string name
int priority
Task(const string &n, int p, int d)
bool operator<(const Task &other) const
Dynamic binary heap with node-based storage.
Fibonacci Heap implementation.