Литмир - Электронная Библиотека

Чтобы показать, как работает этот алгоритм, рассмотрим взвешенный ненаправленный граф на рис. 5.6, а, где весовые коэффициенты соответствуют, например, расстояниям. Мы хотим найти кратчайший путь от A к D. Для начала мы черным кружком помечаем узел A как постоянный. Затем мы исследуем все соседние с ним узлы, указывая около них расстояние до узла A. Если отыскивается более короткий путь к какому-либо узлу, то вместе с указанием расстояния в отметке меняется и узел, через который прошел более короткий путь. Таким образом, позднее можно восстановить весь путь. Если бы в сети было более одного кратчайшего пути от A до D и мы хотели бы найти их все, нам нужно было бы запоминать все узлы, которые позволяют дойти до данного узла, пройдя одинаковое расстояние.

Рассмотрев все соседние с A узлы, мы помечаем ближайший узел как постоянный, как показано на рис. 5.6, б. Этот узел становится новым рабочим узлом.

Теперь мы повторяем ту же процедуру с узлом 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, он инвертируется. В результате двух инверсий мы получаем путь, идущий в нужную сторону.

Листинг 5.1. Алгоритм Дейкстры вычисления кратчайшего пути по графу

Компьютерные сети. 5-е издание - _247.jpg

Листинг 3.7 (продолжение)

Компьютерные сети. 5-е издание - _248.jpg

5.2.3. Заливка

При реализации алгоритма маршрутизации любой маршрутизатор должен принимать решения на основании локальных сведений, а не полной информации о сети. Одним из простых локальных методов является заливка (flooding), при которой каждый приходящий пакет посылается на все исходящие линии, кроме той, по которой он пришел.

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

В результате заливки с использованием счетчика переходов количество отправленных копий пакета может расти экспоненциально, если маршрутизатор повторно отправляет пакеты, которые он уже видел. Хороший способ ограничения количества тиражируемых пакетов заключается в учете проходящих через маршрутизатор пакетов. Это позволяет не посылать их повторно. Один из методов состоит в том, что каждый маршрутизатор кладет в каждый получаемый от своих хостов пакет порядковый номер. Все маршрутизаторы ведут список маршрутизаторов-источников, в котором сохраняются все порядковые номера пакетов, которые им встречались. Если пакет от данного источника с таким порядковым номером уже есть в списке, он дальше не распространяется и удаляется.

Чтобы предотвратить неограниченный рост размера списка, можно снабдить все списки счетчиком k, показывающим, что все порядковые номера вплоть до k уже встречались. И когда приходит пакет, можно очень легко проверить, был ли он уже передан, сравнивая его порядковый номер с k; при положительном ответе такой пакет отвергается. Кроме того, не нужно хранить весь список до k, поскольку этот счетчик очень действенно подытоживает его.

В большинстве случаев использование алгоритма заливки для отправки пакетов является непрактичным, но тем не менее иногда он оказывается очень полезным. Во-первых, он гарантированно доставляет пакет в каждый узел сети. Если пакет нужно доставить в одно конкретное место, этот метод может не оправдать себя. Однако он оказывается очень эффективным при широковещательной рассылке. В беспроводных сетях сообщения, передаваемые станцией, могут быть приняты любой другой станцией, находящейся в пределах радиуса действия передатчика, — и это фактически является заливкой. Некоторые алгоритмы используют это свойство.

Во-вторых, метод заливки отличается чрезвычайной надежностью. Даже если большая часть маршрутизаторов окажется полностью уничтоженной (например, если речь идет о военной сети связи в зоне вооруженных конфликтов), любой существующий путь для доставки сообщения будет найден. Кроме того, заливка практически не требует настройки. Маршрутизаторы должны лишь знать своих соседей. Это означает, что заливка может использоваться внутри другого алгоритма, более эффективного, но требующего более тщательной настройки. Также алгоритм заливки может служить эталоном при тестировании других алгоритмов выбора маршрутов, так как он всегда находит все возможные пути в сети, а следовательно, и кратчайшие. Ухудшить эталонные показатели времени доставки могут разве что накладные расходы, вызванные огромным количеством пакетов, формируемых самим алгоритмом заливки.

5.2.4. Маршрутизация по вектору расстояний

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

Алгоритмы маршрутизации по вектору расстояний (distance vector routing) работают, опираясь на таблицы (то есть векторы), поддерживаемые всеми маршрутизаторами и содержащие сведения о кратчайших известных путях к каждому из возможных адресатов и о том, какое соединение следует при этом использовать. Для обновления данных этих таблиц производится обмен информацией с соседними маршрутизаторами. В результате маршрутизатор знает наилучший способ добраться до любого адреса назначения.

130
{"b":"639789","o":1}