Advertisement
maxim_shlyahtin

A*_2

Aug 7th, 2024
73
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.71 KB | None | 0 0
  1. #include <iostream>
  2. #include <vector>
  3. #include <map>
  4. #include <queue>
  5. #include <cmath>
  6. #include <climits>
  7. #include <sstream>
  8.  
  9.  
  10. // Структура для хранения информации о вершине
  11. template<typename T>
  12. struct Vertex {
  13.     double g = 0; // Стоимость пути от начальной вершины до данной
  14.     double f = 0; // Общая стоимость пути (g + h)
  15.     double visited = false;
  16.     T parent; // Родительская вершина в пути
  17. };
  18.  
  19. // Структура для сравнения вершин в очереди
  20. template<typename T>
  21. struct Compare {
  22.     bool operator()(const std::pair<T, Vertex<T>>& a, const std::pair<T, Vertex<T>>& b) {
  23.         return a.second.f > b.second.f;
  24.     }
  25. };
  26.  
  27. // Функция для вычисления эвристической оценки
  28.  
  29. //int heuristic(char a, char b) {
  30. //    return abs(a - b);
  31. //}
  32.  
  33. int heuristic(int a, int b) {
  34.     return abs(a - b);
  35. }
  36.  
  37. template<typename T>
  38. std::vector<T> aStar(std::map<T, std::vector<std::pair<T, double>>>& graph, T start, T goal) {
  39.     std::map<T, Vertex<T>> vertices;
  40.     std::priority_queue<std::pair<T, Vertex<T>>, std::vector<std::pair<T, Vertex<T>>>, Compare<T>> openset;
  41.     //std::vector<T> closedset;
  42.     // Инициализация начальной вершины
  43.     vertices[start].g = 0;
  44.     vertices[start].f = vertices[start].g + heuristic(start, goal);
  45.     vertices[start].parent = T();
  46.     openset.push({ start, vertices[start] });
  47.  
  48.     while (!openset.empty()) {
  49.         char current = openset.top().first;
  50.         openset.pop();
  51.         //closedset.push_back(current);
  52.         vertices[current].visited = true;
  53.         //std::cout << current << '\n';
  54.        
  55.         if (current == goal) {
  56.             std::vector<T> path;
  57.             while (current != T()) {
  58.                 path.push_back(current);
  59.                 current = vertices[current].parent;
  60.             }
  61.             return path;
  62.         }
  63.  
  64.         //vertices[current].visited = true;
  65.         //std::cout << "Current vertice: " << current << '\n';
  66.         //std::string ssd_str = "Reachable vertices:";
  67.         //std::stringstream ssd;
  68.         for (auto& neighbor : graph[current]) {
  69.            
  70.             /*
  71.             double tentative_g = vertices[current].g + neighbor.second;
  72.  
  73.  
  74.             if (tentative_g < vertices[next].g) {
  75.                 vertices[next].g = tentative_g;
  76.                 vertices[next].f = vertices[next].g + heuristic(next, goal);
  77.                 vertices[next].parent = current;
  78.                 openset.push({ next, vertices[next] });
  79.                 ssd << " | " << next << " -> " << "g: " << vertices[next].g << " h: " << heuristic(next, goal) << " f: " << vertices[next].f << " | ";
  80.             }*/
  81.             T next = neighbor.first;
  82.             double tentative_g_score = vertices[current].g + neighbor.second;
  83.            
  84.             if (vertices[next].visited == true && tentative_g_score >= vertices[next].g) {
  85.                 continue;
  86.             }
  87.             if (vertices[next].visited == false || tentative_g_score < vertices[next].g) {
  88.                 //std::cout << next << '\n';
  89.                 vertices[next].parent = current;
  90.                 vertices[next].g = tentative_g_score;
  91.                 vertices[next].f = vertices[next].g + heuristic(next, goal);
  92.                 if (!vertices[next].visited) {
  93.                     vertices[next].visited = true;
  94.                     openset.push({ next, vertices[next] });
  95.                 }
  96.             }
  97.         }
  98.         //ssd_str = (ssd_str + ssd.str()).length() > ssd_str.length() ? ssd_str + ssd.str() + '\n' : ssd_str + " None\n";
  99.         //std::cout << ssd_str;
  100.  
  101.         //std::priority_queue<std::pair<T, Vertex<T>>, std::vector<std::pair<T, Vertex<T>>>, Compare<T>> tmp_pq = pq;
  102.         //std::vector<std::pair<T, Vertex<T>>> vec;
  103.         //while (!tmp_pq.empty()) {
  104.         //    vec.push_back(tmp_pq.top());
  105.         //    tmp_pq.pop();
  106.         //}
  107.  
  108.         //for (const auto& pair : vec) {
  109.         //    std::cout << "(" << pair.first << ", " << pair.second.f << ")" << std::endl;
  110.         //}
  111.     }
  112. }
  113.  
  114. template<typename T>
  115. void exec() {
  116.     std::map<T, std::vector<std::pair<T, double>>> graph;
  117.     T start, goal;
  118.     std::cin >> start >> goal;
  119.  
  120.     T from, to;
  121.     double weight;
  122.     while (std::cin >> from >> to >> weight) {
  123.         graph[from].insert(graph[from].end(), { std::make_pair(to, weight) });
  124.     }
  125.  
  126.     std::vector<T> path = aStar(graph, start, goal);
  127.     for (int i = path.size() - 1; i >= 0; --i) {
  128.         std::cout << path[i];
  129.     }
  130.     std::cout << '\n';
  131. }
  132.  
  133. int main() {
  134.     exec<char>();
  135.     return 0;
  136. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement