Найти тему

Теперь мы повторяем ту же процедуру с узлом B, исследуя все его соседние узлы. Если сумма расстояния от узла B и значения отметк

Теперь мы повторяем ту же процедуру с узлом B, исследуя все его соседние узлы. Если сумма расстояния от узла B и значения отметки в узле B (расстояния от A до B) оказывается меньше, чем отметка у исследуемого узла (уже найденное другим путем расстояние от A), это значит, что найден более короткий путь, поэтому пометка узла изменяется.

После того как все соседние с рабочим узлы исследованы и временные отметки при необходимости изменены, по всему графу ищется узел с наименьшей временной отметкой. Этот узел помечается как постоянный и становится текущим рабочим узлом. На рис. 5.6 показаны первые шесть этапов работы алгоритма.

Чтобы понять, как работает алгоритм, посмотрим на рис. 5.6, в. На данном этапе узел E только что был отмечен как постоянный. Предположим, что существует более короткий путь, нежели ABE, например AXYZE (для некоторых X и Y). В этом случае есть две возможности — либо узел Z уже сделан постоянным, либо еще нет. Если да, значит, узел E уже проверялся, когда узел Z был сделан постоянным и, следовательно, рабочим узлом. В этом случае путь AXYZE уже исследовался.

Теперь рассмотрим случай, когда узел Z все еще помечен как временный. Если отметка узла Z больше или равна пометки узла E, путь AXYZE не может быть короче, чем путь ABE. Если же отметка узла Z меньше пометки узла E, то тогда узел Z должен был стать постоянным раньше узла E, и узел E проверялся бы с узла Z.

Этот алгоритм приведен в листинге 5.1. Глобальные переменные n и dist описывают граф и инициализируются раньше, чем вызывается shortest_path. Единственное отличие программы от описанного выше алгоритма заключается в том, что вычисление кратчайшего пути в программе начинается не от узла-источника s, а от конечного узла t.

Поскольку в однонаправленном графе кратчайшие пути от t к s те же самые, что и от s к t, не имеет значения, с какого конца начинать. Причина поиска пути в обратном направлении заключается в том, что каждый узел помечается предшествующим узлом, а не следующим. Когда найденный путь копируется в выходную переменную path, он инвертируется. В результате двух инверсий мы получаем путь, идущий в нужную сторону.