Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
DM_shpory.doc
Скачиваний:
48
Добавлен:
21.09.2019
Размер:
1.59 Mб
Скачать

40. Алгоритм вычисления расстояний между всеми парами вершин графа. Общий случай.

Очевидно, что задачу определения расстояния между всеми парами вершин можно решить, используя n раз один из ранее изложенных методов нахождения расстояний от фиксированной вершины. Таким образом, мы получаем алгоритм со сложностью O(n4) (при использовании метода Форда — Беллмана) или O(n3) для бесконтурных графов или неотрицательных весов. Однако оказывается, что в общем случае n–кратное использование метода Форда — Беллмана не является наилучшим методом.

Рассмотрим ориентированный граф G = <VE>, где V = {v1, ..., vn}, и предположим, что A = [aij] есть матрица весов (aij = a(vivj)). Обозначив через dij(m) длину кратчайшего пути из vi  в vj, содержащего не более m дуг, получаем следующие очевидные уравнения:

Если операцию min трактовать как «сумму», операцию «+» — как «произведение», то матрица [dij(m+1)] является «произведением» матриц [dij(m)] и A = [aij]. Обозначим такое «произведение» двух матриц A и B через A*B и отметим, что для этой операции единичным элементом служит матрица

Тогда [dij(0)] = U и

Произведение A*B двух матриц размерности n ´ n можно вычислить за время O(n3) (n сложений и n – 1 сравнений на каждый из n2 элементов произведения A*B). Следовательно, матрицу и тем самым расстояние между всеми парами вершин можно вычислить за время O(n4).

Пока сложность этого алгоритма такая же, как и для случая n–кратного использования алгоритма Форда — Беллмана. Однако мы можем ее снизить, если заметим, что операция * ассоциативна (т.е. (B) * C = A * (B * C)). Этот факт позволяет вычислять произведение, поочередно возводя матрицу A в квадрат и тем самым заменяя n – 1 умножение матрицы élog nù умножениями. Таким образом, мы получаем алгоритм сложности O(n3 log n), отыскивающий расстояния между всеми парами вершин в графе без контуров отрицательной длины.

41. Алгоритм нахождения расстояния от источника до всех остальных вершин в графе с неотрицательными весами дуг — метод Дейкстры. Оценка вычислительной сложности.

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

Алгоритм нахождения расстояния от источника до всех остальных вершин в графе с неотрицательными весами дуг — метод Дейкстры

Данные: Ориентированный граф V, E с выделенным источником s V, матрица весов дуг A [u, v], u, v V (все веса неотрицательны).

Результаты: Расстояния от источника до всех вершин графа D[v] = d(sv), vV.

1 Begin

2 for V do D [v] := A[s, v]; D [s] := 0;

3 T := V \ {s};

4 while T   do

5 Begin

6 u := произвольная вершина r T, такая что D[r] = min(D[p]: T};

7 T := T \ {u};

8 for T do D [v] := min(D[v], D[u] + A [u, v])

9 end

10 end

Чтобы понять действие алгоритма, покажем, что следующее условие является инвариантом цикла 4:

для каждой V \ T D[v] = d(sv),

для каждой T D[v] = длине кратчайшего из тех путей из s в v, для которых предпоследняя вершина принадлежит множеству V \ T. (4)

В самом деле, в строке 6 мы находим вершину u T, такую что значение D[u]  является минимальным (из всех) значением D[t], для t T.

Покажем, что D[u] = d(su). Это именно так, потому что если кратчайший путь из s в u имеет длину меньше D[u], то в силу второй части условия (4) его предпоследняя вершина принадлежит множеству T.

Пусть t будет первой вершиной пути, принадлежащей множеству T. Начальный отрезок пути из s в t составляет кратчайший путь из s в t, причем его предпоследняя вершина не принадлежит множеству T. По второй части условия (4) имеем D[t] = d(st). Используя предположение о неотрицательности весов, получаем

D[t] = d(st)  d(su) < D[u

вопреки принципу, по которому была выбрана вершина u.

Таким образом, D[u] = d(su) и мы можем в строке 7 удалить u из множества T , не нарушая первой части условия (4). Чтобы обеспечить выполнение также и второй части этого условия, следует еще проверить пути из из s в vT, предпоследняя вершина в которых есть u, и выполнить актуализацию переменных D [v], T. Именно это выполняет цикл 8.

Очевидно, что условие (4) выполняется при входе в цикл 4. По окончании действия алгоритма T = , а следовательно, согласно условию (4), D[v] = d(sv), V.

Оценим сложность алгоритма Дейкстры. Цикл 4 выполняется n – 1 раз, причем каждое его выполнение требует O(n) шагов: O(n) шагов для нахождения вершины u в строке 6 (предполагаем, что множество T представлено списком) и O(n) шагов для выполнения цикла 8. Таким образом, сложность алгоритма есть O(n2).

Тщательно подбирая структуры данных, можно получить вариант алгоритма со сложностью O(m log n). Для этого множество T нужно представить бинарным деревом с высотой O(log n) и с таким свойством, что для произвольных его вершин u и v :

если u — сын v, то D[u]  D[v

Вершина u, для которой значение D[u]  минимально, является тогда корнем дерева. Этот корень можно устранить за O(log n) шагов, сохраняя свойство уменьшения значения D[j] на каждом пути до корня. Достаточно сместить на место корня его сына s с большим (или равным) значением D[j], затем на освободившееся место передвинуть сына вершины s с большим значением D[j] и т.д. Если граф представлен списками ЗАПИСЬ[u], u V, то строку 8 можно заменить на

for ЗАПИСЬ [u] do

if D[u] + A [u, v] < D[v] then

begin

D[v] :=  D[u] + A [u, v];

передвинуть вершину в дереве в направлении корня так, чтобы сохранить

условие если u — сын v, то D[u]  D[v

end

Если предположить существование таблицы указателей на вершины нашего дерева, то передвижение вершины v, о которой идет речь в данной части раздела, может быть осуществлено за O(log n) шагов. Достаточно заменять v поочередно вершинами, находящимися непосредственно над ней.

В алгоритме, модифицированном таким способом, каждая дуга графа анализируется в точности один раз, причем с этим связано O(log n) шагов на передвижение соответствующей вершины в дереве, представляющем множество T. Это дает в сумме O(m log n) шагов. Сюда нужно добавить O(n log n) шагов, необходимых для построения нашего дерева и для устранения n – 1 раз из него корня. Общая сложность алгоритма есть O(m log n).

Неизвестно, существует ли алгоритм сложности O(m) нахождения расстояния от фиксированной вершины до всех остальных вершин графа с неотрицательными весами дуг. Можно показать, что существует константа C, такая что эта задача для произвольного k > 0 может быть решена за время Ck(m + n1+1/k).

Работа алгоритма Дейкстры проиллюстрирована на рисунке (V = {1, ..., 6}, веса дуг даны в скобках, значения D[v], v T, приведены со звездочкой (*), минимальные значения — с двумя звездочками.

(7)

2 6

(5) 3 (1)

(2) (1) (1)

(1)

(4)

(3)

S = 1 (2) 4 5

D[1]

D[2]

D[3]

D[4]

D[5]

D[6]

0

1*

*

*

*

*

0

1

6*

3*

*

8*

0

1

4**

3

7*

8*

0

1

4

3

7*

5**

0

1

4

3

6**

5

** = min

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]