Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
SAOD..doc
Скачиваний:
142
Добавлен:
11.05.2015
Размер:
959.49 Кб
Скачать

8.10 Алгоритм Дейкстры

Существуют более эффективные алгоритмы для двух важных случаев:

  1. веса всех дуг неотрицательны;

  2. граф не имеет контуров.

Для первого случая справедлив известный нам алгоритм Дейкстры. Обобщенно он может быть записан следующим образом.

1 BEGIN

  1. FOR v eV DO D[v] := a[s, v]; D[s] := 0;

  2. T := V \ {s};

  3. WHILE T;t0DO

  4. BEGIN

  1. u := произвольная вершина t eT, такая, что D[t]=min{D[p], peT};

  1. T := T \ {u};

  2. FOR v eT DO D[v] := min(D[v], D[u]+a[u, v])

9 END

10 END

Чтобы пояснить работу алгоритма, покажем, что инвариантом цикла 4 является следующее условие: для каждой вершины D[v]=d(s, v), v eV \ T

D[v]= длине кратчайшего из тех путей из s в v, для которых предпоследняя вершина принадлежит множеству V \ Т. В самом деле, в строке 5 мы находим вершину и еТ такую, что значение D[u] является минимальным из всех значением D[t] для t еТ. Причем, D[u]=d(s,u).

Это действительно так, потому что, если кратчайший путь из s в и имеет длину меньше D[u], то в силу второй части условия (1) его предпоследняя вершина принадлежит множеству Т. Пусть t - первая вершина пу­ти, принадлежащая множеству Т. Начальный отрезок нашего пути из s в t составляет кратчайший путь из s в t, причем его предпоследняя вершина не принадлежит множеству Т. По первой части условия (1) имеем

D[t] = d(s, t). Используя предположение о неотрицательности весов, получаем

D[t] = d(s, t)<d(s, u) < D[u] вопреки принципу, по которому была выбрана вершина и.

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

Очевидно, что условие (1) выполняется при входе в цикл 4. По окончании работы алгоритма Т = 0, а сле­довательно, согласно условию (1), D[v]=d(s, v), veV.

Оценим сложность алгоритма Дейкстры. Цикл 4 выполняется п-1 раз, прчем каждое его выполнение тре­бует 0(п) шагов:

(1)

для каждой вершины v еТ

O(n) шагов для нахождения вершины u в строке 6 и O(n) шагов для выполнения цикла 8.

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

если u – сын v, то D[u]≤D[v]. (2)

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

Если граф представлен списками инцидентности, то строку 8 можно заменить на FOR v∈СПИСОК[u] DO

IF D[u] + a(u, v) < D[v] THEN BEGIN D[v] := D[u] + a(u, v); передвинуть вершину v в дереве в направлении корня

так,

чтобы сохранить условие (2)

END

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

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

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