
- •2. Алгоритмы построения деревьев
- •2.1. Неориентированные покрывающие деревья
- •2.2.Алгоритм построения максимального ориентированного леса
- •3. Алгоритмы поиска путей
- •3.1. Алгоритм поиска кратчайшего пути
- •3.2. Алгоритмы поиска всех кратчайших путей.
- •3.3. Алгоритмы поиска k кратчайших путей
- •4. Потоковые алгоритмы
- •4.1. Определения
- •4.2. Алгоритм поиска увеличивающей цепи
- •4.4. Алгоритм поиска потока минимальной стоимости
- •4.5. Алгоритм поиска максимального динамического потока
- •5. Паросочетания и покрытия
- •5.1. Понятия и определения
- •5.2. Алгоритм решения задачи о паросочетании максимальной мощности
- •5.3. Алгоритм выбора паросочетания максимального веса
- •6. Задача почтальона
- •6.1. Введение
- •6.4. Задача почтальона для смешанного графа
- •7. Сетевые графики. Метод критического пути
- •Контрольные вопросы
- •I. Организационно-методический раздел
- •4. Перечень контрольных вопросов и заданий для самостоятельной работы
- •4. Примерный перечень вопросов к экзамену и зачёту
- •III. Распределение часов курса по темам и видам работ
3. Алгоритмы поиска путей
3.1. Алгоритм поиска кратчайшего пути
Пусть a(x,y) – вес дуги (x,y) (а(х,у)>0). a(x,y) = ∞, если дуга (x,y) отсутствует в графе G. Для любых двух вершин s и t графа G могут существовать несколько путей, соединяющих вершину s с вершиной t. Путь, соединяющий вершину s с вершиной t, имеющий минимально возможную длину, называется кратчайшим путем из s в t. Алгоритм поиска в графе кратчайшего пути между двумя выделенными вершинами s и t при положительных длинах дуг предложил в 1959 г. Дейкстрой.
Перед началом выполнения алгоритма все вершины и дуги графа не окрашены. Каждой вершине в ходе выполнения алгоритма присваивается число d(x), равное длине кратчайшего пути из s в x, включающего только окрашенные вершины.
Процедура алгоритма Дейкстроя.
Шаг 1. Положить d(s) = 0 и d(x) = ∞ для всех х, отличных от s. Окрасить вершину s и положить y=s (y – последняя из окрашенных вершин).
Шаг 2. Для каждой неокрашенной вершины х следующим образом пересчитать величину d(x):
d(x) = min {d(x), d(y)+ a(y, x)}.
Если d(x) = ∞ для всех неокрашенных вершин х, закончить процедуру алгоритма: в исходном графе отсутствуют пути из вершины s в неокрашенные вершины. В противном случае окрасить ту из вершин х, для которой величина d(x) является наименьшей. Кроме того, окрасить дугу, ведущую в выбранную на данном шаге вершину х [для этой дуги достигался минимум в соответствии с выражением для d(x)]. Положить у = х.
Шаг 3. Если y = t, закончить процедуру: кратчайший путь из вершины s в вершину t – это единственный составленный из окрашенных дуг путь из s в t. В противном случае – перейти к шагу 2.
Отметим, что при окрашивании вершины окрашивается и некоторая заходящая в нее дуга, т.е. в каждую вершину заходит не более чем одна окрашенная дуга. Кроме того, окрашенные дуги не могут образовать контур, следовательно, окрашенные дуги образуют в исходном графе ориентированное дерево с корнем в вершине s. Это дерево называется ориентированным деревом кратчайших путей. Единственный путь от s до любой вершины х, принадлежащей этому дереву, является кратчайшим путем из s в х. Если вершина у принадлежит пути из s в х, то часть пути от s до у есть кратчайший путь из s в у (иначе существовал бы более короткий путь из s в х). Алгоритм Дейкстроя можно рассматривать как процедуру наращивания ориентированного дерева с корнем в вершине s. Когда в процессе достигается вершина t, процедура может быть остановлена. Но если мы хотим определить кратчайшие пути из вершины s во все вершины графа, то процедуру наращивания дерева следует продолжать, пока все вершины графа не будут окрашены, т. е. включены в ориентированное дерево кратчайших путей, если такое существует.
Пример. Построить дерево кратчайших путей для графа, изображённого на рис. 3.1.
Рис. 3.1.
Зададим для данного графа матрицу, элемент которой, стоящий в строке x и в столбце y, равен a(x,y):
|
s |
a |
b |
c |
d |
e |
t |
s |
0 |
8 |
6 |
7 |
1 |
2 |
∞ |
a |
∞ |
0 |
∞ |
∞ |
∞ |
∞ |
2 |
b |
∞ |
3 |
0 |
∞ |
∞ |
∞ |
∞ |
c |
∞ |
∞ |
1 |
0 |
∞ |
∞ |
5 |
d |
∞ |
∞ |
∞ |
2 |
0 |
∞ |
∞ |
e |
∞ |
∞ |
∞ |
∞ |
3 |
0 |
∞ |
t |
∞ |
∞ |
∞ |
∞ |
∞ |
4 |
0 |
Перед первым выполнением шага 2 окрашена только вершина s, кроме того, d(s)=0 и d(x)=∞ для всех х, отличных от s.
Шаг 2. y=s.
d(a)=min{d(a), d(s)+a(s,a)}=min{∞, 0+8}=8,
d(b)=min{d(b), d(s)+a(s,b)}=min{∞, 0+6}=6,
d(c)=min{d(c), d(s)+a(s,c)}=min{∞, 0+7}=7,
d(d)=min{d(d), d(s)+a(s,d)}=min{∞, 0+1}=1,
d(e)=min{d(e), d(s)+a(s,e)}=min{∞, 0+2}=2,
d(t)=min{d(t), d(s)+a(s,t)}=min{∞, 0+∞}=∞.
Величина d(d) является минимальной, поэтому вершина d окрашивается совместно с дугой (s,d), которая и определила величину d(d).
Шаг 3. Поскольку вершина t остаётся неокрашенной, переходим к шагу 2. При этом y= d.
Результат первой итерации алгоритма зафиксирован во втором столбце следующей таблицы. Результаты последующих итераций отображены в последующих столбцах. [Первый столбец содержит начальные значения d(x) для всех х]
|
|
s |
d |
e |
c |
b |
a |
t |
s |
0 |
– |
– |
– |
– |
– |
– |
– |
a |
∞ |
8 |
8 |
8 |
8 |
7 |
– |
– |
b |
∞ |
6 |
6 |
6 |
4 |
– |
– |
– |
c |
∞ |
7 |
3 |
3 |
– |
– |
– |
– |
d |
∞ |
1 |
– |
– |
– |
– |
– |
– |
e |
∞ |
2 |
2 |
– |
– |
– |
– |
– |
t |
∞ |
∞ |
∞ |
∞ |
8 |
8 |
8 |
– |
Полученное дерево кратчайших путей представлено на рис. 3.2.
Рис. 3.2.
Исходное предположение алгоритма Дейкстры состоит в не отрицательности длин дуг графа. В тех случаях, когда некоторые из дуг графа имеют отрицательные длины, используется модификация алгоритма Дейкстры, принадлежащая Форду. Отличие алгоритма Форда состоит в следующем:
На шаге 2 пересчет величин d(x) производится для всех вершин, а не только для неокрашенных.
Если для некоторой окрашенной вершины х происходит уменьшение величины d(x), то с этой вершины и инцидентной ей окрашенной дуги окраска снимается.
Процедура алгоритма заканчивается только тогда, когда все вершины окрашены, и когда после шага 2 ни одно из чисел d(x) не меняется.
Обоснование алгоритма Форда
Процедура алгоритма Форда заканчивается только после того, как для всех х и у выполняется соотношение
d(x) + a(x,y) ≥ d(y). (*)
(Иначе с вершины у была бы снята окраска сразу после окраски вершины х.)
Пусть после окончания процедуры алгоритма Форда величина d(y) для некоторой вершины у не совпадает с длиной кратчайшего пути из s в у. Если в графе несколько таких вершин, то, для определенности, рассмотрим ту из них, кратчайший путь до которой из вершины s содержит наименьшее число дуг. Очевидно, что если величина d(z) для произвольной вершины z конечна, то она представляет собой длину некоторого пути, соединяющего вершины s и z. Поэтому по окончании процедуры алгоритма величина d(y) должна совпадать с длиной некоторого пути из s в у, и, в силу сделанного предположения, эта величина должна превышать длину кратчайшего пути между s и у. Пусть вершина х является предпоследней вершиной кратчайшего пути от s до у. Если таких путей несколько, то в качестве х берется та вершина, кратчайший путь до которой от вершины s включает наименьшее число дуг. В силу выбора вершин у и х величина d(х) должна совпадать с длиной кратчайшего пути из s в х, откуда d(y) > d(x) + a(x,y). Однако последнее соотношение противоречит соотношению (*). Что и требовалось доказать.
Замечание. Алгоритм Форда не решает задачу нахождения кратчайшего пути при наличии в исходном графе контура отрицательной длины. Что делать, если нет сведений о наличии или отсутствии в рассматриваемом графе контуров отрицательной длины? Тогда в процессе работы алгоритма Форда необходимо считать, сколько раз окрашиваются отдельные вершины. Как только это число для какой-либо вершины достигает N, где N - число вершин графа, процедуру алгоритма можно остановить: исходный граф содержит контур отрицательной длины. Если этого не происходит, алгоритм Форда завершается за конечное число шагов.