Aleph-w 3.0
A C++ Library for Data Structures and Algorithms
Loading...
Searching...
No Matches
astar_example.cc
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
104#include <iostream>
105#include <iomanip>
106#include <vector>
107#include <cmath>
108#include <chrono>
109#include <limits>
110
111#include <tpl_graph.H>
112#include <AStar.H>
113#include <Dijkstra.H>
114
115using namespace Aleph;
116using namespace std;
117
118// =============================================================================
119// Graph Node with 2D Coordinates
120// =============================================================================
121
128{
129 int x = 0;
130 int y = 0;
131 bool blocked = false; // Can be used to create obstacles
132
133 GridCell() = default;
134 GridCell(int _x, int _y, bool _blocked = false)
135 : x(_x), y(_y), blocked(_blocked) {}
136};
137
138// Graph types
142
143// =============================================================================
144// Distance Accessor
145// =============================================================================
146
151{
153
155 {
156 return arc->get_info();
157 }
158};
159
160// =============================================================================
161// Heuristic Functions
162// =============================================================================
163
172{
174
176 {
177 const auto& f = from->get_info();
178 const auto& t = to->get_info();
179 double dx = f.x - t.x;
180 double dy = f.y - t.y;
181 return sqrt(dx * dx + dy * dy);
182 }
183};
184
193{
195
197 {
198 const auto& f = from->get_info();
199 const auto& t = to->get_info();
200 return abs(f.x - t.x) + abs(f.y - t.y);
201 }
202};
203
204// =============================================================================
205// Grid Graph Builder
206// =============================================================================
207
217GridGraph create_grid_graph(int width, int height, bool diagonal,
218 vector<GridGraph::Node*>& nodes)
219{
220 GridGraph g;
221 nodes.resize(width * height);
222
223 // Create nodes
224 for (int y = 0; y < height; ++y)
225 for (int x = 0; x < width; ++x)
226 {
227 int idx = y * width + x;
228 nodes[idx] = g.insert_node(GridCell(x, y));
229 }
230
231 // Create edges
232 for (int y = 0; y < height; ++y)
233 for (int x = 0; x < width; ++x)
234 {
235 int idx = y * width + x;
236
237 // Right neighbor (weight 1.0)
238 if (x + 1 < width)
239 {
240 int right = y * width + (x + 1);
241 g.insert_arc(nodes[idx], nodes[right], 1.0);
242 g.insert_arc(nodes[right], nodes[idx], 1.0);
243 }
244
245 // Down neighbor (weight 1.0)
246 if (y + 1 < height)
247 {
248 int down = (y + 1) * width + x;
249 g.insert_arc(nodes[idx], nodes[down], 1.0);
250 g.insert_arc(nodes[down], nodes[idx], 1.0);
251 }
252
253 // Diagonal neighbors (weight sqrt(2) ≈ 1.414)
254 if (diagonal)
255 {
256 double diag_weight = sqrt(2.0);
257
258 // Down-right
259 if (x + 1 < width && y + 1 < height)
260 {
261 int dr = (y + 1) * width + (x + 1);
264 }
265
266 // Down-left
267 if (x - 1 >= 0 && y + 1 < height)
268 {
269 int dl = (y + 1) * width + (x - 1);
272 }
273 }
274 }
275
276 return g;
277}
278
279// =============================================================================
280// Path Visualization
281// =============================================================================
282
292void print_grid_with_path(int width, int height,
293 const vector<GridGraph::Node*>& nodes,
294 GridGraph::Node* start,
295 GridGraph::Node* end,
296 const Path<GridGraph>& path)
297{
298 (void)nodes;
299
300 // Create grid representation
301 vector<vector<char>> grid(height, vector<char>(width, '.'));
302
303 // Mark path
304 for (Path<GridGraph>::Iterator it(path); it.has_curr(); it.next())
305 {
306 auto node = it.get_current_node();
307 const auto& info = node->get_info();
308 grid[info.y][info.x] = '*';
309 }
310
311 // Mark start and end
312 grid[start->get_info().y][start->get_info().x] = 'S';
313 grid[end->get_info().y][end->get_info().x] = 'E';
314
315 // Print grid
316 cout << " ";
317 for (int x = 0; x < width; ++x)
318 cout << (x % 10);
319 cout << "\n";
320
321 for (int y = 0; y < height; ++y)
322 {
323 cout << setw(2) << y;
324 for (int x = 0; x < width; ++x)
325 cout << grid[y][x];
326 cout << "\n";
327 }
328}
329
330// =============================================================================
331// Benchmark Helper
332// =============================================================================
333
334template <typename Func>
336{
337 auto start = chrono::high_resolution_clock::now();
338 f();
339 auto end = chrono::high_resolution_clock::now();
340 return chrono::duration<double, milli>(end - start).count();
341}
342
343// =============================================================================
344// Main Program
345// =============================================================================
346
347int main()
348{
349 cout << "╔══════════════════════════════════════════════════════════════════╗\n";
350 cout << "║ A* Shortest Path Algorithm - Example ║\n";
351 cout << "╚══════════════════════════════════════════════════════════════════╝\n\n";
352
353 // =========================================================================
354 // Part 1: 4-Connected Grid (Manhattan heuristic optimal)
355 // =========================================================================
356
357 cout << "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n";
358 cout << "Part 1: 4-Connected Grid (no diagonal movement)\n";
359 cout << "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n\n";
360
361 const int WIDTH = 15;
362 const int HEIGHT = 10;
363
364 vector<GridGraph::Node*> nodes4;
366
367 cout << "Grid size: " << WIDTH << " x " << HEIGHT << "\n";
368 cout << "Nodes: " << g4.get_num_nodes() << "\n";
369 cout << "Edges: " << g4.get_num_arcs() << "\n\n";
370
371 // Define start and end
372 auto start4 = nodes4[0]; // Top-left (0,0)
373 auto end4 = nodes4[(HEIGHT-1) * WIDTH + (WIDTH-1)]; // Bottom-right
374
375 cout << "Start: (" << start4->get_info().x << ", " << start4->get_info().y << ")\n";
376 cout << "End: (" << end4->get_info().x << ", " << end4->get_info().y << ")\n\n";
377
378 // A* with Manhattan heuristic
379 cout << "▶ A* with Manhattan heuristic:\n";
380 {
382 Path<GridGraph> path(g4);
383
384 double cost = std::numeric_limits<double>::max();
385 double time = measure_time_ms([&]() {
386 cost = astar.find_path(g4, start4, end4, path);
387 });
388
389 if (cost == std::numeric_limits<double>::max())
390 {
391 cout << " No path found.\n";
392 }
393 else
394 {
395 cout << " Path cost: " << cost << "\n";
396 cout << " Path length: " << path.size() << " nodes\n";
397 }
398 cout << " Time: " << fixed << setprecision(3) << time << " ms\n\n";
399
400 if (cost != std::numeric_limits<double>::max())
401 {
403 cout << "\n";
404 }
405 }
406
407 // A* with Euclidean heuristic
408 cout << "▶ A* with Euclidean heuristic:\n";
409 {
411 Path<GridGraph> path(g4);
412
413 double cost = std::numeric_limits<double>::max();
414 double time = measure_time_ms([&]() {
415 cost = astar.find_path(g4, start4, end4, path);
416 });
417
418 if (cost == std::numeric_limits<double>::max())
419 {
420 cout << " No path found.\n";
421 }
422 else
423 {
424 cout << " Path cost: " << cost << "\n";
425 cout << " Path length: " << path.size() << " nodes\n";
426 }
427 cout << " Time: " << fixed << setprecision(3) << time << " ms\n";
428 cout << " Note: Euclidean underestimates in 4-connected grid,\n";
429 cout << " but still finds optimal path (admissible).\n\n";
430 }
431
432 // Dijkstra (zero heuristic)
433 cout << "▶ Dijkstra (A* with zero heuristic):\n";
434 {
435 AStar_Min_Path<GridGraph, GridDistance> astar; // Default: Zero_Heuristic
436 Path<GridGraph> path(g4);
437
438 double cost = std::numeric_limits<double>::max();
439 double time = measure_time_ms([&]() {
440 cost = astar.find_min_path(g4, start4, end4, path);
441 });
442
443 if (cost == std::numeric_limits<double>::max())
444 {
445 cout << " No path found.\n";
446 }
447 else
448 {
449 cout << " Path cost: " << cost << "\n";
450 cout << " Path length: " << path.size() << " nodes\n";
451 }
452 cout << " Time: " << fixed << setprecision(3) << time << " ms\n";
453 cout << " Note: Explores more nodes than A* with good heuristic.\n\n";
454 }
455
456 // =========================================================================
457 // Part 2: 8-Connected Grid (Euclidean heuristic optimal)
458 // =========================================================================
459
460 cout << "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n";
461 cout << "Part 2: 8-Connected Grid (with diagonal movement)\n";
462 cout << "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n\n";
463
464 vector<GridGraph::Node*> nodes8;
466
467 cout << "Grid size: " << WIDTH << " x " << HEIGHT << "\n";
468 cout << "Nodes: " << g8.get_num_nodes() << "\n";
469 cout << "Edges: " << g8.get_num_arcs() << " (includes diagonals)\n\n";
470
471 auto start8 = nodes8[0];
472 auto end8 = nodes8[(HEIGHT-1) * WIDTH + (WIDTH-1)];
473
474 // A* with Euclidean heuristic
475 cout << "▶ A* with Euclidean heuristic (optimal for 8-connected):\n";
476 {
478 Path<GridGraph> path(g8);
479
480 double cost = std::numeric_limits<double>::max();
481 double time = measure_time_ms([&]() {
482 cost = astar.find_path(g8, start8, end8, path);
483 });
484
485 if (cost == std::numeric_limits<double>::max())
486 {
487 cout << " No path found.\n";
488 }
489 else
490 {
491 cout << " Path cost: " << fixed << setprecision(3) << cost << "\n";
492 cout << " Path length: " << path.size() << " nodes\n";
493 }
494 cout << " Time: " << fixed << setprecision(3) << time << " ms\n\n";
495
496 if (cost != std::numeric_limits<double>::max())
497 {
499 cout << "\n";
500 }
501 }
502
503 // A* with Manhattan heuristic
504 cout << "▶ A* with Manhattan heuristic:\n";
505 {
507 Path<GridGraph> path(g8);
508
509 double cost = std::numeric_limits<double>::max();
510 double time = measure_time_ms([&]() {
511 cost = astar.find_path(g8, start8, end8, path);
512 });
513
514 if (cost == std::numeric_limits<double>::max())
515 {
516 cout << " No path found.\n";
517 }
518 else
519 {
520 cout << " Path cost: " << fixed << setprecision(3) << cost << "\n";
521 cout << " Path length: " << path.size() << " nodes\n";
522 }
523 cout << " Time: " << fixed << setprecision(3) << time << " ms\n";
524 cout << " Note: Manhattan overestimates for 8-connected (not admissible),\n";
525 cout << " may not find optimal path!\n\n";
526 }
527
528 // =========================================================================
529 // Part 3: Computing Full Shortest Paths Tree
530 // =========================================================================
531
532 cout << "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n";
533 cout << "Part 3: Computing Full Shortest Paths Tree\n";
534 cout << "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n\n";
535
536 cout << "When you need shortest paths from one source to ALL destinations,\n";
537 cout << "use compute_min_paths_tree() or paint_min_paths_tree().\n\n";
538
539 {
541 GridGraph tree;
542
543 double time = measure_time_ms([&]() {
544 astar.compute_min_paths_tree(g4, start4, tree);
545 });
546
547 cout << "▶ compute_min_paths_tree() from (0,0):\n";
548 cout << " Tree nodes: " << tree.get_num_nodes() << "\n";
549 cout << " Tree edges: " << tree.get_num_arcs() << "\n";
550 cout << " Time: " << fixed << setprecision(3) << time << " ms\n\n";
551
552 // Query multiple destinations efficiently
553 cout << " Distances from (0,0):\n";
554
555 vector<pair<int,int>> targets = {{5, 5}, {10, 5}, {14, 9}};
556 for (const auto& [tx, ty] : targets)
557 {
558 auto target = nodes4[ty * WIDTH + tx];
559 Path<GridGraph> path(g4);
560 double dist = astar.get_min_path(tree, target, path);
561 cout << " to (" << tx << ", " << ty << "): " << dist << "\n";
562 }
563 }
564
565 // =========================================================================
566 // Part 4: Using Fibonacci Heap for Large Graphs
567 // =========================================================================
568
569 cout << "\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n";
570 cout << "Part 4: Using Fibonacci Heap (for dense/large graphs)\n";
571 cout << "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n\n";
572
573 cout << "For very large or dense graphs, Fibonacci heap can be faster:\n\n";
574
575 // Create larger grid for comparison
576 const int BIG_WIDTH = 50;
577 const int BIG_HEIGHT = 50;
578
579 vector<GridGraph::Node*> big_nodes;
581
582 auto big_start = big_nodes[0];
583 auto big_end = big_nodes[(BIG_HEIGHT-1) * BIG_WIDTH + (BIG_WIDTH-1)];
584
585 cout << "Grid: " << BIG_WIDTH << " x " << BIG_HEIGHT;
586 cout << " (" << big_g.get_num_nodes() << " nodes)\n\n";
587
588 // Binary Heap (default)
589 {
592 ArcHeap>;
595
596 double cost = std::numeric_limits<double>::max();
597 double time = measure_time_ms([&]() {
598 cost = astar.find_path(big_g, big_start, big_end, path);
599 });
600
601 cout << "▶ A* with Binary Heap:\n";
602 cout << " Path cost: " << cost << "\n";
603 cout << " Time: " << fixed << setprecision(3) << time << " ms\n\n";
604 }
605
606 // Fibonacci Heap
607 {
613
614 double cost = std::numeric_limits<double>::max();
615 double time = measure_time_ms([&]() {
616 cost = astar.find_path(big_g, big_start, big_end, path);
617 });
618
619 cout << "▶ A* with Fibonacci Heap:\n";
620 cout << " Path cost: " << cost << "\n";
621 cout << " Time: " << fixed << setprecision(3) << time << " ms\n\n";
622 }
623
624 // =========================================================================
625 // Part 5: Demonstrating Inadmissible Heuristic (Educational)
626 // =========================================================================
627
628 cout << "\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n";
629 cout << "Part 5: Inadmissible Heuristic Demonstration (Educational)\n";
630 cout << "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n\n";
631
632 cout << "WARNING: This example demonstrates what happens when you use an\n";
633 cout << "inadmissible heuristic (one that overestimates). This is for\n";
634 cout << "educational purposes only. In production, always use admissible\n";
635 cout << "heuristics to guarantee optimal paths!\n\n";
636
637 // Create a simple 3-node graph with two paths
638 vector<GridGraph::Node*> demo_nodes;
640
641 demo_nodes.push_back(demo_g.insert_node(GridCell(0, 0))); // Start
642 demo_nodes.push_back(demo_g.insert_node(GridCell(5, 0))); // Middle
643 demo_nodes.push_back(demo_g.insert_node(GridCell(10, 0))); // End
644
645 // Two paths:
646 // 1. Direct: 0 -> 2 (cost 15.0) - suboptimal
647 // 2. Via middle: 0 -> 1 -> 2 (cost 8.0) - optimal
648 demo_g.insert_arc(demo_nodes[0], demo_nodes[2], 15.0); // Direct
649 demo_g.insert_arc(demo_nodes[0], demo_nodes[1], 3.0); // Via middle (better)
650 demo_g.insert_arc(demo_nodes[1], demo_nodes[2], 5.0);
651
652 cout << "Graph structure:\n";
653 cout << " Node 0 (0,0) -> Node 2 (10,0): cost 15.0\n";
654 cout << " Node 0 (0,0) -> Node 1 (5,0): cost 3.0\n";
655 cout << " Node 1 (5,0) -> Node 2 (10,0): cost 5.0\n";
656 cout << " Optimal path: 0 -> 1 -> 2 (total: 8.0)\n\n";
657
658 // Inadmissible heuristic that massively overestimates
659 struct BadHeuristic
660 {
661 using Distance_Type = double;
662 Distance_Type operator()(GridGraph::Node* from, GridGraph::Node* to) const
663 {
664 const auto& f = from->get_info();
665 const auto& t = to->get_info();
666 double dx = f.x - t.x;
667 double dy = f.y - t.y;
668 // Overestimate by 10x
669 return 10.0 * sqrt(dx * dx + dy * dy);
670 }
671 };
672
673 // Test with admissible heuristic first (Euclidean)
674 cout << "▶ With Euclidean heuristic (admissible):\n";
675 {
678
679 double cost = astar.find_path(demo_g, demo_nodes[0], demo_nodes[2], path);
680
681 cout << " Path cost: " << cost << "\n";
682 cout << " Path length: " << path.size() << " nodes\n";
683 cout << " Result: ";
684 if (cost == 8.0)
685 cout << "✓ Found optimal path (0 -> 1 -> 2)\n\n";
686 else
687 cout << "✗ Found suboptimal path\n\n";
688 }
689
690 // Test with inadmissible heuristic
691 cout << "▶ With inadmissible heuristic (10x overestimate):\n";
692 {
695
696 double cost = astar.find_path(demo_g, demo_nodes[0], demo_nodes[2], path);
697
698 cout << " Path cost: " << cost << "\n";
699 cout << " Path length: " << path.size() << " nodes\n";
700 cout << " Result: ";
701 if (cost == 8.0)
702 cout << "Found optimal path (by chance)\n";
703 else if (cost == 15.0)
704 cout << "✗ Found suboptimal direct path (0 -> 2)\n";
705 else
706 cout << "Found path with cost " << cost << "\n";
707
708 cout << "\n Explanation: The inadmissible heuristic made node 1 look\n";
709 cout << " too expensive (h(1) >> actual cost), so A* chose the direct\n";
710 cout << " path instead of exploring through node 1.\n\n";
711 }
712
713 // Compare with Dijkstra (always optimal)
714 cout << "▶ With Dijkstra (zero heuristic, always optimal):\n";
715 {
718
719 double cost = astar.find_min_path(demo_g, demo_nodes[0], demo_nodes[2], path);
720
721 cout << " Path cost: " << cost << "\n";
722 cout << " Path length: " << path.size() << " nodes\n";
723 cout << " Result: ✓ Always finds optimal path\n\n";
724 }
725
726 cout << "┌─────────────────────────────────────────────────────────────────┐\n";
727 cout << "│ Key Takeaway: │\n";
728 cout << "│ │\n";
729 cout << "│ An inadmissible heuristic CAN make A* return suboptimal paths! │\n";
730 cout << "│ │\n";
731 cout << "│ Always verify your heuristic never overestimates: │\n";
732 cout << "│ h(n) ≤ actual_cost(n, goal) for all nodes n │\n";
733 cout << "│ │\n";
734 cout << "│ When in doubt, use zero heuristic (Dijkstra) for correctness. │\n";
735 cout << "└─────────────────────────────────────────────────────────────────┘\n\n";
736
737 // =========================================================================
738 // Summary
739 // =========================================================================
740
741 cout << "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n";
742 cout << "Summary\n";
743 cout << "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n\n";
744
745 cout << "┌─────────────────────────────────────────────────────────────────┐\n";
746 cout << "│ Heuristic Choice: │\n";
747 cout << "│ • 4-connected grid → Manhattan heuristic (optimal) │\n";
748 cout << "│ • 8-connected grid → Euclidean heuristic (optimal) │\n";
749 cout << "│ • Unknown graph → Zero heuristic (Dijkstra, always works) │\n";
750 cout << "├─────────────────────────────────────────────────────────────────┤\n";
751 cout << "│ Key Methods: │\n";
752 cout << "│ • find_path() - Find single shortest path (recommended) │\n";
753 cout << "│ • find_min_path() - Same but without heuristic (Dijkstra) │\n";
754 cout << "│ • paint_min_paths_tree() - All paths from source (paint) │\n";
755 cout << "│ • compute_min_paths_tree() - All paths (build tree) │\n";
756 cout << "├─────────────────────────────────────────────────────────────────┤\n";
757 cout << "│ Heap Selection: │\n";
758 cout << "│ • ArcHeap (Binary) - Good for most cases │\n";
759 cout << "│ • ArcFibonacciHeap - Better for very large/dense graphs │\n";
760 cout << "└─────────────────────────────────────────────────────────────────┘\n\n";
761
762 return 0;
763}
A* shortest path algorithm.
Dijkstra's shortest path algorithm.
List_Graph< GridNode, GridArc > GridGraph
GridGraph create_grid_graph(int width, int height, bool diagonal, vector< GridGraph::Node * > &nodes)
Creates a 2D grid graph.
double measure_time_ms(Func &&f)
void print_grid_with_path(int width, int height, const vector< GridGraph::Node * > &nodes, GridGraph::Node *start, GridGraph::Node *end, const Path< GridGraph > &path)
Prints the grid with the path highlighted.
int main()
A* algorithm for finding the shortest path between two nodes.
Definition AStar.H:157
virtual Node * insert_node(Node *node) noexcept
Insertion of a node already allocated.
Definition tpl_graph.H:524
Arc * insert_arc(Node *src_node, Node *tgt_node, void *a)
Definition tpl_graph.H:604
Iterator on nodes and arcs of a path.
Definition tpl_graph.H:3201
Path on a graph.
Definition tpl_graph.H:2669
size_t size() const noexcept
Return the path length in nodes.
Definition tpl_graph.H:2807
ArcInfo & get_info() noexcept
Return a modifiable reference to the arc data.
Definition graph-dry.H:595
NodeInfo & get_info() noexcept
Return a modifiable reference to the data contained in the node.
Definition graph-dry.H:494
constexpr size_t get_num_nodes() const noexcept
Return the total of nodes of graph.
Definition graph-dry.H:695
constexpr size_t get_num_arcs() const noexcept
Definition graph-dry.H:778
__gmp_expr< T, __gmp_unary_expr< __gmp_expr< T, U >, __gmp_sqrt_function > > sqrt(const __gmp_expr< T, U > &expr)
Definition gmpfrxx.h:4058
__gmp_expr< T, __gmp_unary_expr< __gmp_expr< T, U >, __gmp_abs_function > > abs(const __gmp_expr< T, U > &expr)
Definition gmpfrxx.h:4051
DynArray< Graph::Node * > nodes
Definition graphpic.C:406
static mpfr_t y
Definition mpfr_mul_d.c:3
Main namespace for Aleph-w library functions.
Definition ah-arena.H:89
DynList< T > maps(const C &c, Op op)
Classic map operation.
STL namespace.
#define HEIGHT(p)
Definition ntreepic.C:362
#define WIDTH(p)
Definition ntreepic.C:361
Default filter for filtered iterators on arcs.
Definition tpl_graph.H:1000
Arc of graph implemented with double-linked adjacency lists.
Definition tpl_graph.H:222
Node belonging to a graph implemented with a double linked adjacency list.
Definition tpl_graph.H:121
Filtered iterator of adjacent arcs of a node.
Definition tpl_graph.H:1119
Euclidean distance heuristic.
Distance_Type operator()(GridGraph::Node *from, GridGraph::Node *to) const
Node info containing 2D coordinates.
GridCell()=default
GridCell(int _x, int _y, bool _blocked=false)
Distance functor that reads arc weights.
Distance_Type operator()(GridGraph::Arc *arc) const
Manhattan distance heuristic.
Distance_Type operator()(GridGraph::Node *from, GridGraph::Node *to) const
Generic graph and digraph implementations.