AlgoPlus v0.1.0
Loading...
Searching...
No Matches
astar.h
1#include <queue>
2#ifndef ASTAR_H
3#define ASTAR_H
4
5#ifdef __cplusplus
6#include <algorithm>
7#include <climits>
8#include <iostream>
9#include <queue>
10#include <unordered_map>
11#include <vector>
12#endif
13
17template <typename T> class AStar {
18 private:
19 std::unordered_map<T, std::vector<std::pair<T, double>>> adj;
20 std::unordered_map<T, double> nodes;
21
22 public:
30 explicit AStar(std::unordered_map<T, std::vector<std::pair<T, double>>> v = {},
31 std::unordered_map<T, double> nodes = {}) {
32 try {
33 if ((!v.empty() && nodes.empty()) || (!nodes.empty() && v.empty())) {
34 throw std::logic_error("you have to provide two non empty maps");
35 }
36 if (!v.empty() && !nodes.empty()) {
37 this->adj = v;
38 this->nodes = nodes;
39 }
40 } catch (std::logic_error& e) {
41 std::cerr << e.what() << '\n';
42 }
43 }
44
50 inline void insert_node(T u, double val) { nodes[u] = val; }
51
59 inline bool has_edge(T u, T v) {
60 if (adj.find(u) != adj.end()) {
61 for (std::pair<T, double>& x : adj[u]) {
62 if (x.first == v) {
63 return true;
64 }
65 }
66 }
67 return false;
68 }
69
76 inline void add_edge(T u, T v, double dist) {
77 try {
78 if (nodes.find(u) != nodes.end() && nodes.find(v) != nodes.end()) {
79 adj[u].push_back(std::make_pair(v, dist));
80 } else {
81 throw std::logic_error("One of the two nodes that passed to the "
82 "function do not exist in the graph");
83 }
84 } catch (std::logic_error& e) {
85 std::cerr << e.what() << '\n';
86 }
87 }
88
95 inline std::vector<T> shortest_path(T start, T end) {
96 auto reconstruct_path = [&](std::unordered_map<T, T> cameFrom, T curr) {
97 std::vector<T> path = {curr};
98 while (cameFrom.find(curr) != cameFrom.end()) {
99 curr = cameFrom[curr];
100 path.push_back(curr);
101 }
102 std::reverse(path.begin(), path.end());
103 return path;
104 };
105 std::priority_queue<std::pair<double, T>, std::vector<std::pair<double, T>>,
106 std::greater<std::pair<double, T>>>
107 pq;
108 std::unordered_map<T, bool> visited;
109 std::unordered_map<T, T> cameFrom;
110 std::unordered_map<T, double> gScore;
111 std::unordered_map<T, double> fScore;
112 for (auto& x : nodes) {
113 gScore[x.first] = INT_MAX;
114 fScore[x.first] = INT_MAX;
115 }
116 gScore[start] = 0;
117 fScore[start] = nodes[start];
118 pq.push(std::make_pair(0, start));
119 visited[start] = true;
120 while (!pq.empty()) {
121 auto current = pq.top();
122 if (current.second == end) {
123 return reconstruct_path(cameFrom, current.second);
124 }
125 pq.pop();
126 for (auto& x : adj[current.second]) {
127 double tentative_gscore = gScore[current.second] + x.second;
128 if (tentative_gscore < gScore[x.first]) {
129 cameFrom[x.first] = current.second;
130 gScore[x.first] = tentative_gscore;
131 fScore[x.first] = tentative_gscore + nodes[x.first];
132 if (visited.find(x.first) == visited.end()) {
133 pq.push(std::make_pair(tentative_gscore + nodes[x.first], x.first));
134 }
135 }
136 }
137 }
138 return {};
139 }
140};
141
142#endif
void insert_node(T u, double val)
insert_node function
Definition astar.h:50
AStar(std::unordered_map< T, std::vector< std::pair< T, double > > > v={}, std::unordered_map< T, double > nodes={})
A* constructor.
Definition astar.h:30
void add_edge(T u, T v, double dist)
add_edge function
Definition astar.h:76
std::vector< T > shortest_path(T start, T end)
shortest_path function
Definition astar.h:95
bool has_edge(T u, T v)
has_edge function
Definition astar.h:59