21. Алгоритм Дейкстры нахождения кратчайшего пути. Метод заливки.
Выбор кратчайшего пути. Начнем наше изучение алгоритмов выбора маршрутов с метода, широко применяемого в различных формах благодаря его простоте и понятности. Идея заключается в построении графа подсети, в котором каждый узел будет соответствовать маршрутизатору, а каждая дуга - линии связи (часто называемой просто связью). При выборе маршрута между двумя маршрутизаторами алгоритм просто находит кратчайший путь между ними на графе. Концепция кратчайшего пути требует некоторого пояснения. Один из способов измерения длины пути состоит в подсчете количества транзитных участков. В таком случае путь ABC и ABE на рис. 5.6 имеют одинаковую длину. Можно измерять расстояния в километрах. В таком случае окажется, что путь ABC значительно длиннее пути ABE (предполагается, что рисунок изображен с соблюдением масштаба). Однако помимо учета количества транзитных участков и физической длины линий возможен учет и других параметров. Например, каждой дуге графа можно поставить в соответствие среднюю длину очереди и время задержки пересылки, определяемые каждый час с помощью передачи специального тестового пакета. В таком графе кратчайший путь определяется как самый быстрый путь, а не путь с самой короткой длиной кабеля или путь, состоящий из минимального числа отдельных отрезков кабеля.
В общем случае параметры дуг графа являются функциями расстояния, пропускной способности, средней загруженности, стоимости связи средней длины очереди, измеренной величины задержки и других факторов. Изменяя весовую функцию, алгоритм может вычислять кратчайший путь с учетом любого количества критериев в различных комбинациях. Известно несколько алгоритмов вычисления кратчайшего пути между двумя узлами графа. Один из них был создан знаменитым Дейкстрой (Dijkstra) в 1959 году. Каждый узел помечается (в скобках) расстоянием до него от узла отправителя по наилучшему известному пути. Вначале пути неизвестны, поэтому все узлы помечаются символом бесконечности. По мере работы алгоритма и нахождения путей отметки узлов изменяются, показывая оптимальные пути. Отметка может быть постоянной или экспериментальной. Вначале все отметки являются ориентировочными. Когда выясняется, что отметка действительно соответствует кратчайшему возможному пути, она становится постоянной и в дальнейшем не изменяется. Чтобы показать, как работает этот алгоритм, рассмотрим взвешенный ненаправленный граф (рис. 5.6, а), где весовые коэффициенты соответствуют, например, расстояниям. Мы хотим найти кратчайший путь от А к D. Для начала мы черным кружком помечаем узел А как постоянный. Затем мы исследуем все соседние с ним узлы, указывая около них расстояние до узла А. Если отыскивается более короткий путь к какому-либо узлу, то вместе с указанием расстояния в отметке меняется и узел, через который прошел более короткий путь. Таким образом, позднее можно восстановить весь путь. Рассмотрев все соседние с А узлы, мы помечаем ближайший узел как постоянный, как показано на рис. 5.6, б. Этот узел становится новым рабочим узлом. Теперь мы повторяем ту же процедуру с узлом В, исследуя все его соседние узлы. Если сумма расстояния от узла В и значения отметки в узле В (расстояния от А до В) оказывается меньше, чем отметка у исследуемого узла (уже найденное другим путем расстояние от А), это значит, что найден более короткий путь, поэтому пометка узла изменяется. После того как все соседние с рабочим узлы исследованы и временные отметки при необходимости изменены, по всему графу ищется узел с наименьшей временной отметкой. Этот узел помечается как постоянный и становится текущим рабочим узлом. На рис. 5.6 показаны первые пять этапов работы алгоритма. Чтобы понять, как работает алгоритм, посмотрим на рис. 5.6, в. На данном этапе узел Е только что был отмечен как постоянный. Предположим, что существует более короткий путь, нежели ABE, например AXYZE. В этом случае есть две возможности - либо узел Z уже сделан постоянным, либо еще нет. Если да, значит, узел Е уже проверялся, когда узел Z был сделан постоянным и, следовательно, рабочим узлом. В этом случае путь AXYZE уже исследовался. Теперь рассмотрим случай, когда узел Z все еще помечен как временный. В этом случае отметка узла Z либо больше или равна пометки узла Е, либо меньше ее. В первом случае путь AXYZE не может быть короче, чем путь ABE Если же отметка узла Z меньше пометки узла Е, то тогда узел Z должен был стать постоянным раньше узла Е, и узел Е проверялся бы с узла Z.Этот алгоритм приведен в листинге 5.1. Глобальные переменные п и dist описывают граф и инициализируются раньше, чем вызывается shortest_path. Единственное отличие программы от описанного выше алгоритма заключается в том. что вычисление кратчайшего пути в программе начинается не от узла-источника s, а от конечного узла t Поскольку в однонаправленном графе кратчайший путь от t к s тот же самый, что и от s к t, не имеет значения, с какого конца начинать. (Если только не существует несколько кратчайших путей. В таком случае, двигаясь в противоположном направлении, мы можем обнаружить другой путь.) Причина поиска пути в обратном направлении заключается в том, что каждый узел помечается предшествующим узлом, а не следующим. Когда найденный путь копируется в выходную переменную path, он инвертируется. С помощью реверсивного поиска убирается неправильность направления поиска, и мы получаем путь, идущий в нужную сторону.
Заливка. Метод заливки представляет собой еще один статический алгоритм, при котором каждый приходящий пакет посылается на все исходящие линии, кроме той, по которой пришел пакет. Очевидно, что алгоритм заливки порождает огромное количество дублированных пакетов, даже бесконечное количество в сетях с замкнутыми контурами, если не принять специальных мер. Одна из таких мер состоит в помещении в заголовок пакета счетчика преодоленных им транзитных участков, уменьшаемого при прохождении каждого маршрутизатора. Когда значение этого счетчика падает до нуля, пакет удаляется. В идеальном случае счетчик транзитных участков должен вначале устанавливаться равным длине пути от отправителя до получателя. Если отправитель не знает расстояния до получателя, он может установить значение счетчика равным длине максимального пути (диаметру) в данной подсети. Альтернативный способ ограничения количества тиражируемых пакетов заключается в учете проходящих через маршрутизатор пакетов. Это позволяет не посылать их повторно. Один из методов состоит в том, что каждый маршрутизатор помещает в каждый получаемый от своих хостов пакет порядковый номер. Все маршрутизаторы ведут список маршрутизаторов-источников, в котором сохраняются все порядковые номера пакетов, которые им встречались. Если пакет от данного источника с таким порядковым номером уже есть в списке, он дальше не распространяется и удаляется. Чтобы предотвратить неограниченный рост размера списка, можно снабдить все списки счетчиком k, показывающим, что все порядковые номера вплоть до k уже встречались. И когда приходит пакет, можно очень легко проверить, не является ли он дубликатом. При положительном ответе такой пакет отвергается. Кроме того, не нужно хранить весь список до k, поскольку этот счетчик очень действенно подытоживает его. На практике чаще применяется вариант данного алгоритма под названием выборочная заливка. В этом алгоритме маршрутизаторы посылают пакеты не по всем линиям, а только по тем, которые идут приблизительно в нужном направлении. Вряд ли есть смысл посылать пакет, направляющийся на запад, по линии, идущей на восток, если только топология сети не представляет собой лабиринт и маршрутизатор не знает об этом. В большинстве случаев алгоритм заливки является непрактичным, но, тем не менее, иногда он применяется. Например, в военных приложениях, где большая часть маршрутизаторов в любой момент может оказаться уничтоженной, высокая надежность алгоритма заливки является, наоборот, желательной. В распределенных базах данных иногда бывает необходимо одновременно обновить все базы данных, и в этом случае заливка также оказывается полезной. Третье применение алгоритма заливки - эталонное тестирование других алгоритмов выбора маршрутов, так как заливка всегда находит все возможные пути в сети, а, следовательно, и кратчайшие. Ухудшить эталонные показатели времени доставки могут разве что накладные расходы, вызванные огромным количеством пакетов, формируемых самим алгоритмом заливки.