Advertisement
kostyukevich

dij

Dec 18th, 2023
776
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 2.61 KB | None | 0 0
  1. import math
  2. from dataclasses import dataclass
  3. from typing import Generic, Optional
  4. from typing import List, Tuple
  5. import heapq
  6. from graph import Graph, T
  7.  
  8. def dijkstra(graph: Graph[T], start: T, end: T) -> Tuple[List[T], int]:
  9.     heap: List[Tuple[int, T]] = [(0, start)] #очередь приоритетов
  10.     distances: List[int] = [float('inf')] * graph.length #просто расстояния. изначально бесконечность
  11.     predecessors: List[Optional[int]] = [None] * graph.length #сохраняем соседей (предшественников) каждой вершины с меньшим путем
  12.     distances[graph.vertex_names[start]] = 0 #сохарняем минимальные расстояния до каждой вершинв
  13.  
  14.     while heap:
  15.         current_distance, current_vertex = heapq.heappop(heap) #убираем наименьшие значения расстояния и вершины из очереди
  16.  
  17.         if current_vertex == end: #когда дошли до конца - восстанавливаем путь с конца к началу
  18.             path = []
  19.             current = graph.vertex_names[end] #встаем на позицию финиша
  20.             while predecessors[current] is not None:
  21.                 path.append(graph.get_vertex_by_index(current)) #просто вытаскиваем названия вершин по индексам
  22.                 current = predecessors[current] #дивагемся дальше (на предшественника текущего)
  23.             path.append(start) #добавлям старт
  24.             return path[::-1], current_distance #путь пишем в обратном порядке, возвращаем расстояние
  25.  
  26.         for neighbor_index, weight in enumerate(graph.matrix[graph.vertex_names[current_vertex]]): #Перебрать соседей текущей вершины.
  27.             if weight != 0:
  28.                 distance = current_distance + weight # смотрим новое расстояние
  29.                 if distance < distances[neighbor_index]: # Если найден более короткий путь к соседу
  30.                     distances[neighbor_index] = distance
  31.                     predecessors[neighbor_index] = graph.vertex_names[current_vertex]
  32.                     heapq.heappush(heap, (distance, graph.get_vertex_by_index(neighbor_index)))
  33.                     # обновляем расстояние, предшественника и помещаем все это в очередь приоритетов.
  34.     return [], 0
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement