Astar
Bugsunknown
c_cpp
a year ago
3.6 kB
8
Indexable
Never
#include <iostream> #include <map> #include <string> #include <set> #include <queue> #include <stack> #include <vector> #include <algorithm> #include <unordered_map> using namespace std; int v, e; string base, goal; class Graph { public: map<string, map<string, int>> adj_list; map<string, int> heuristics; vector<string> vertices; map<string, int> rMap; Graph(); void input(); void AStar(string &, string &); void myProcess(); }; Graph::Graph() { } void Graph::input() { cin >> v >> e; cin >> base >> goal; for (int i = 0; i < v; i++) { string vertex; cin >> vertex; heuristics[vertex] = 0; vertices.push_back(vertex); rMap[vertex] = i; } for (int i = 0; i < v; i++) { int dist; cin >> dist; heuristics[vertices[i]] = dist; } for (int i = 0; i < e; i++) { string v1, v2; int x; cin >> v1 >> v2 >> x; adj_list[v1][v2] = x; } AStar(base, goal); } // this function is used to implement AStar search algorithm void Graph::AStar(string &base, string &goal) { auto cmp = [&](pair<string, int> a, pair<string, int> b) { if (a.second < b.second) { return false; } if (a.second == b.second) { return rMap[a.first] > rMap[b.first]; } return true; }; // Create a queue to store the nodes that are waiting to be explored priority_queue<pair<string, int>, vector<pair<string, int>>, decltype(cmp)> frontier(cmp); frontier.push(make_pair(base, heuristics[base])); // Create a set to store the nodes that have been expanded set<string> explored; // Create a map to store the parent nodes and distance from the base node unordered_map<string, string> parent; unordered_map<string, int> distance; bool goalFound = false; distance[base] = 0; int pass = 0; while (!frontier.empty()) { // Get the node with the smallest distance from the priority queue string current_node = frontier.top().first; frontier.pop(); // Skip this node if it has already been explored if (explored.find(current_node) != explored.end()) continue; pass++; // Add the current node to the set of explored nodes explored.insert(current_node); // Check if the current node is the goal node if (current_node == goal) { goalFound = true; break; } for (auto neighbor : adj_list[current_node]) { string next_node = neighbor.first; int edge_cost = neighbor.second; int new_distance = distance[current_node] + edge_cost; if ((distance.find(next_node) == distance.end()) || new_distance < distance[next_node]) { distance[next_node] = new_distance; int priority = new_distance + heuristics[next_node]; frontier.push(make_pair(next_node, priority)); parent[next_node] = current_node; } } } if (goalFound) { vector<string> path; path.push_back(goal); string current_node = path.back(); while (current_node != base) { current_node = parent[current_node]; path.push_back(current_node); } for (int i = path.size() - 1; i >= 0; i--) { cout << path[i] << " "; } cout << endl; cout << pass << " " << distance[goal] << endl; } else { cout << "-unreachable-" << endl; cout << pass << " " << distance[goal] << endl; } } int main() { Graph G; G.input(); return 0; }