30 explicit AStar(std::unordered_map<T, std::vector<std::pair<T, double>>> v = {},
31 std::unordered_map<T, double> nodes = {}) {
33 if ((!v.empty() && nodes.empty()) || (!nodes.empty() && v.empty())) {
34 throw std::logic_error(
"you have to provide two non empty maps");
36 if (!v.empty() && !nodes.empty()) {
40 }
catch (std::logic_error& e) {
41 std::cerr << e.what() <<
'\n';
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);
102 std::reverse(path.begin(), path.end());
105 std::priority_queue<std::pair<double, T>, std::vector<std::pair<double, T>>,
106 std::greater<std::pair<double, T>>>
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;
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);
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));