Advertisement
maxim_shlyahtin

1

May 20th, 2024
474
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.77 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 = std::numeric_limits<double>::max(); // Стоимость пути от начальной вершины до данной
  14.     bool deadend = false;
  15.     T parent = T(); // Родительская вершина в пути
  16. };
  17.  
  18. // Структура для сравнения вершин в очереди
  19. template<typename T>
  20. struct Compare {
  21.     bool operator()(const std::pair<T, Vertex<T>>& a, const std::pair<T, Vertex<T>>& b) {
  22.         /*if(a.second.g != b.second.g)
  23.             return a.second.g < b.second.g;
  24.         return a.second.edge < b.second.edge;*/
  25.         return a.second.g > b.second.g;
  26.     }
  27. };
  28.  
  29. // Функция для вычисления эвристической оценки
  30.  
  31. //int heuristic(char a, char b) {
  32. //    return abs(a - b);
  33. //}
  34.  
  35. int heuristic(int a, int b) {
  36.     return abs(a - b);
  37. }
  38.  
  39. template<typename T>
  40. std::vector<T> aStar(std::map<T, std::vector<std::pair<T, double>>>& graph, T start, T goal) {
  41.     std::map<T, Vertex<T>> vertices;
  42.     std::priority_queue<std::pair<T, Vertex<T>>, std::vector<std::pair<T, Vertex<T>>>, Compare<T>> openset;
  43.     //std::vector<T> closedset;
  44.     // Инициализация начальной вершины
  45.     vertices[start].g = 0;
  46.     openset.push({ start, vertices[start] });
  47.    
  48.     while (!openset.empty()) {
  49.         char current = openset.top().first;
  50.         openset.pop();
  51.         //std::cout << current << '\n';
  52.         //std::cout << current << '\n';
  53.  
  54.         if (current == goal) {
  55.             std::vector<T> path;
  56.             while (current != T()) {
  57.                 path.push_back(current);
  58.                 current = vertices[current].parent;
  59.             }
  60.             return path;
  61.         }
  62.  
  63.         //vertices[current].visited = true;
  64.         //std::cout << "Current vertice: " << current << '\n';
  65.         //std::string ssd_str = "Reachable vertices:";
  66.         //std::stringstream ssd;
  67.         for (auto& neighbor : graph[current]) {
  68.  
  69.             /*
  70.             double tentative_g = vertices[current].g + neighbor.second;
  71.  
  72.  
  73.             if (tentative_g < vertices[next].g) {
  74.                 vertices[next].g = tentative_g;
  75.                 vertices[next].f = vertices[next].g + heuristic(next, goal);
  76.                 vertices[next].parent = current;
  77.                 openset.push({ next, vertices[next] });
  78.                 ssd << " | " << next << " -> " << "g: " << vertices[next].g << " h: " << heuristic(next, goal) << " f: " << vertices[next].f << " | ";
  79.             }*/
  80.             T next = neighbor.first;
  81.            
  82.             double tentative_g_score = vertices[current].g + neighbor.second;
  83.            
  84.             /*T next_vert;
  85.             double min_weight = std::numeric_limits<double>::max();
  86.             if (min_weight < tentative_g_score) {
  87.                 real_next = next;
  88.  
  89.             }*/
  90.  
  91.             if (tentative_g_score <= vertices[next].g) {
  92.                 //std::cout << next << '\n';
  93.                 //vertices[next].edge = neighbor.second;
  94.                 //std::cout << "next: " << next << " weight: " << tentative_g_score;
  95.                 //std::cout << " " << vertices[next].parent << '\n';
  96.                 vertices[next].parent = current;
  97.                 vertices[next].edge = neighbor.second;
  98.                 vertices[next].g = tentative_g_score;
  99.                 openset.push({ next, vertices[next] });
  100.             }
  101.             /*if (tentative_g_score == vertices[next].g) {
  102.                 std::cout << current << next << '\n';
  103.                 std::cout << vertices[next].edge << ' ' << neighbor.second << '\n';
  104.                 if (vertices[next].edge > neighbor.second) {
  105.                     vertices[next].parent = next;
  106.                     vertices[next].edge = neighbor.second;
  107.                 }
  108.             }*/
  109.         }
  110.         //ssd_str = (ssd_str + ssd.str()).length() > ssd_str.length() ? ssd_str + ssd.str() + '\n' : ssd_str + " None\n";
  111.         //std::cout << ssd_str;
  112.  
  113.         //std::priority_queue<std::pair<T, Vertex<T>>, std::vector<std::pair<T, Vertex<T>>>, Compare<T>> tmp_pq = pq;
  114.         //std::vector<std::pair<T, Vertex<T>>> vec;
  115.         //while (!tmp_pq.empty()) {
  116.         //    vec.push_back(tmp_pq.top());
  117.         //    tmp_pq.pop();
  118.         //}
  119.  
  120.         //for (const auto& pair : vec) {
  121.         //    std::cout << "(" << pair.first << ", " << pair.second.f << ")" << std::endl;
  122.         //}
  123.     }
  124.     T current = goal;
  125.     std::vector<T> path;
  126.     while (current != T()) {
  127.         path.push_back(current);
  128.         current = vertices[current].parent;
  129.     }
  130.     return path;
  131. }
  132.  
  133. template<typename T>
  134. void exec() {
  135.     std::map<T, std::vector<std::pair<T, double>>> graph;
  136.     T start, goal;
  137.     std::cin >> start >> goal;
  138.  
  139.     T from, to;
  140.     double weight;
  141.     while (std::cin >> from >> to >> weight) {
  142.         graph[from].insert(graph[from].end(), { std::make_pair(to, weight) });
  143.     }
  144.  
  145.     std::vector<T> path = aStar(graph, start, goal);
  146.     /*for (int i = path.size() - 1; i >= 0; --i) {
  147.         std::cout << path[i];
  148.     }*/
  149.     /*for (const auto& pair : vertices) {
  150.         std::cout << "Vertice: " << pair.first << " Weight: " << pair.second.g << " Prev: " << pair.second.parent << '\n';
  151.     }*/
  152.  
  153.     /*T current = goal;
  154.     std::vector<T> path;
  155.     while (current != T()) {
  156.         path.push_back(current);
  157.         current = vertices[current].parent;
  158.     }*/
  159.  
  160.     for (int i = path.size() - 1; i >= 0; --i) {
  161.         std::cout << path[i];
  162.     }
  163.  
  164.     std::cout << '\n';
  165. }
  166.  
  167. int main() {
  168.     exec<char>();
  169.     return 0;
  170. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement