Алгоритмы

Алгоритм Дейкстры на пальцах

9 мин чтения · Python, графы, heapq

Алгоритм Дейкстры находит кратчайшее расстояние от одной вершины графа до всех остальных, если все веса рёбер неотрицательные. Классический пример применения — построение маршрутов на карте.

Идея

Держим для каждой вершины текущую лучшую известную оценку расстояния от старта. На каждом шаге берём ещё не обработанную вершину с наименьшей оценкой, «фиксируем» её и пробуем через неё улучшить оценки соседей. Так постепенно расстояния становятся окончательными.

Ключевой момент: если веса могут быть отрицательными, алгоритм Дейкстры перестаёт гарантировать правильный ответ — для таких случаев нужен алгоритм Беллмана — Форда.

Реализация на Python

Для эффективного выбора вершины с минимальной оценкой используем кучу (heapq) — она даёт следующий минимум за O(log n).

import heapq

def dijkstra(graph: dict[str, list[tuple[str, int]]], start: str) -> dict[str, float]:
    distances = {node: float("inf") for node in graph}
    distances[start] = 0

    queue = [(0, start)]
    visited = set()

    while queue:
        current_distance, current_node = heapq.heappop(queue)

        if current_node in visited:
            continue
        visited.add(current_node)

        for neighbor, weight in graph[current_node]:
            distance = current_distance + weight
            if distance < distances[neighbor]:
                distances[neighbor] = distance
                heapq.heappush(queue, (distance, neighbor))

    return distances

Пример графа и вызова:

graph = {
    "A": [("B", 4), ("C", 1)],
    "B": [("A", 4), ("C", 2), ("D", 5)],
    "C": [("A", 1), ("B", 2), ("D", 8)],
    "D": [("B", 5), ("C", 8)],
}

print(dijkstra(graph, "A"))
# {'A': 0, 'B': 3, 'C': 1, 'D': 8}

Почему B получает расстояние 3, а не 4

Прямое ребро A → B стоит 4, но есть путь A → C → B ценой 1 + 2 = 3, который дешевле. Алгоритм находит его, потому что после обработки вершины C он пересчитывает оценку для B и видит более короткий путь.

Сложность

Типичные ошибки

← Ко всем статьям