Поиск кратчайших путей в графе. Алгоритм Флойда. Алгоритм Дейкстры. Алгоритм Форда-Беллмана.

Вес пути – сумма весов ребер, входящих в путь

Вес кратчайшего пути из u в v (b(u,v)) – минимальный по длине путь из u в v, если он существует. Иначе – бесконечность

Кратчайший путь из u вv – путь из u в v, имеющий вес равный b(u,v) (т.к. может быть несколько кратчайших путей)

Задачи по поиску кр. путей:

1) P(u,v)? – Решаем, сводясь к 2 пункту (более быстрого алгоритма не существует)

2) P(u, v[i]) для всех I – Дейсктра, Форд-Беллман

3) Кратчайшие пути из всех вершин во все – Форд-Уоршелл

Свойства релаксаций:

ЛеммаP = <V1…Vk> - кратчайший путь из 1 в k. Тогда Pij = <Vj…Vj> - кратчайший путь между I и j.

Док-во: Если Pij – не кратчайший, то заменив в P этот участок более коротким путем – уменьшим вес пути P – противоречие.

Вес цикла может быть > 0, < 0 и равным 0

1) Если < 0 – то кратчайший путь уйдет по нему – поэтому Дейкстра не работает если есть цикл отрицательного веса (в отличии от Форда-Белммана)

2) Если > 0 – то он не войдет в кратчайший путь

3) Если == 0 – не имеет смысла ведь, но чтобы не было проблем:

Определения:

|P1k| <= |V| - 1

d[v] – массив кратчайших путей (текущий кратчайший путь из s)

Pi[v] – вершина-родитель в кратчайшем пути

Граф G(Pi) = (V(Pi), E(Pi))

V(Pi) = {v | Pi[v] != NULL} и s – стартовая вершина

E(Pi) = { (Pi[v], v) | v из V(Pi) \ {s}}

Дерево кратчайших путей – ориент подграф G’, что:

1) V’ – множество вершин, достижимых из s

2) S – корень, а G’ - дерево

3) Для каждой вершины v путь из s в v в G’ – кратчайший пусть из s в vвG

Relax(u,v,w)

{

If (d[v] > d[u] + w(u,v))

Then

d[v] = d[u] + w(u,v)

Pi[v] = u

}

b(s,v) – длина кратчайшего пути из s в v

Утверждения:

0) d[v] >=b(s,v)

1) b(s,v) <= b(s,u) + w(u,v)

2) Если нет пути из s в v – d[v] = b(s,v) = inf

3) Если есть путь s->u, и u->v, и u->v – кратчайший, а d[u] = b(s,u) до релаксации, то после нее – d[v] = b(s,v)

4) Есть путь P = <V0,..,Vk>. Релаксация шла в порядке (V0,V1), (V1,V2) и т.д

Тогда d[Vk] = b(s, Vk)

5) Если v из V и d[v] = b(s,v), то подграф G(Pi) – дерево кратчайших путей с корнем s

Доказательства:

0) От противного

1) Вес кратчайшего пути из s в v<= весу любого пути из s в v, в том числе, и проходящего на последнем шаге через u

2) Очевидно

3) Из s->u – кратчайший

d[v] <= d[u] + w(u,v) = b(s,u) + w(u,v) = b(s,v) (т.к. s->u->v - кратчайший)

4) Вытекает из 3-его пункта

5) Следует из 0-4

Решение задачи P(u, v[i]) для всех i:

Через TopSort

1) TopSort(G)

2) Init

3) Перебор вершин в порядке сортировки:

Для всех v из Adj(u)

Relax(u,v,W)

Сложность: O(|E|*|V| + DFS(G)) – вроде

Дейкстра (Dijkstra)

Вход: взвешенный граф (веса положительны), стартовая вершина
Выход: вектор расстояний до стартовой вершины (опционально - вектор предков, чтобы восстановить кратчайший путь)
Алгоритм:

Проставляем расстояния: для стартовой 0, для остальных inf

Пусть PQ – очередь с приоритетом. PQ->push(s)

While(!PQ.empty())

u = PQ.ExtractMin();

u->color = Black;

for v из Adj(u)

If(v->color == WHITE)

d[v] = w(u,v) + d[u]

PQ.push(v)

v->color = Grey

else if v->color == Grey

if (d[v] > d[u] + w(u,v))

PQ.decreaseKey(v, d[u] + w(u,v) )

Сложность алгоритма Дейкстры зависит от способа нахождения вершины v, а также способа хранения множества непосещенных вершин и способа обновления меток. Обозначим черезn количество вершин, а через m — количество ребер в графе G.

· В простейшем случае, когда для поиска вершины сминимальным d[v] просматривается все множество вершин, а для хранения величин d используется массив, время работы алгоритма есть Поиск кратчайших путей в графе. Алгоритм Флойда. Алгоритм Дейкстры. Алгоритм Форда-Беллмана. - student2.ru . Основной цикл выполняется порядка n раз, в каждом из них на нахождение минимума тратится порядка n операций. На циклы по соседям каждой посещаемой вершины тратится количество операций, пропорциональное количеству рёбер m (поскольку каждое ребро встречается в этих циклах ровно дважды и требует константное число операций). Таким образом, общее время работы алгоритма Поиск кратчайших путей в графе. Алгоритм Флойда. Алгоритм Дейкстры. Алгоритм Форда-Беллмана. - student2.ru , но, так как Поиск кратчайших путей в графе. Алгоритм Флойда. Алгоритм Дейкстры. Алгоритм Форда-Беллмана. - student2.ru , оно составляет Поиск кратчайших путей в графе. Алгоритм Флойда. Алгоритм Дейкстры. Алгоритм Форда-Беллмана. - student2.ru .

· Для разреженных графов (то есть таких, для которых m много меньше n²) непосещенные вершины можно хранить в двоичной куче, а в качестве ключа использовать значения d[i], тогда время удаления вершины из Поиск кратчайших путей в графе. Алгоритм Флойда. Алгоритм Дейкстры. Алгоритм Форда-Беллмана. - student2.ru станет Поиск кратчайших путей в графе. Алгоритм Флойда. Алгоритм Дейкстры. Алгоритм Форда-Беллмана. - student2.ru , при том, что время модификации Поиск кратчайших путей в графе. Алгоритм Флойда. Алгоритм Дейкстры. Алгоритм Форда-Беллмана. - student2.ru возрастет до Поиск кратчайших путей в графе. Алгоритм Флойда. Алгоритм Дейкстры. Алгоритм Форда-Беллмана. - student2.ru . Так как цикл выполняется порядка n раз, а количество релаксаций (смен меток) не больше m, скорость работы такой реализации Поиск кратчайших путей в графе. Алгоритм Флойда. Алгоритм Дейкстры. Алгоритм Форда-Беллмана. - student2.ru .

· Если для хранения непосещенных вершин использовать фибоначчиеву кучу, для которой удаление происходит в среднем за Поиск кратчайших путей в графе. Алгоритм Флойда. Алгоритм Дейкстры. Алгоритм Форда-Беллмана. - student2.ru , а уменьшение значения в среднем за Поиск кратчайших путей в графе. Алгоритм Флойда. Алгоритм Дейкстры. Алгоритм Форда-Беллмана. - student2.ru , то время работы алгоритма составит Поиск кратчайших путей в графе. Алгоритм Флойда. Алгоритм Дейкстры. Алгоритм Форда-Беллмана. - student2.ru .

Доказательство корректности Дейкстры:

Инвариант – для вершины, вытащенной из очереди уже нашли кр. путь (d[v] = b(s,v))

Это верно для любой вершины из S (множество вершин, для которых b(s,v) уже найдено – были вытащены из PQ)

0) S = пустое – для него верно

1) пусть u из S. От противного: d[u] != b(s,u), т.е. d[u] >b(s,u)

Пусть P – кратчайший путь из s в u

s->x->y->u, x из S, а y – еще не из S. u – первая вершина, для которой условие не выполняется

Утверждение:

d[y] = b(s,y)

d[x] = b(S,x) – верно, т.к. х из S (u – первая вершина с неверным условием)

при добавлении u в S - мы релаксируем (x,y) èd[y] = b(s,y)ЧТД

b(s,y) <= b(s,u) – очевидно

Значит d[y] = b(s,y) <= b(s,u) <= d[u] <= d[y], т.к. u – первая вершина с неверным условием, а мы вытащили u – т.е. ее приоритет ниже чем приоритет yèd[u] <= d[y]

Но тогда противоречие с d[u] >b(s,u).чтд

Алгоритм Белмана-Форда:

Алгоритм поиска кратчайшего пути во взвешенном графе
Условие: взвешенный граф, можно с отрицательными весами и циклами (с добавлением дополнительной проверки), стартовая вершина.
Алгоритм (без отрицательных циклов):

Для всех вершин проставляем расстояние = inf

Для начальной вершины расстояние = 0

For i = 1 to (V - 1)

Для всех ребер (u ,v)

Еслиd[v] >d[u] + w(u, v)

D[v] =d[u] + w(u, v)

Возвращаем вектор расстояний

Алгоритм (c отрицательными циклами):
Алгоритм Беллмана–Форда позволяет очень просто определить, существует ли в графе G отрицательный цикл, достижимый из вершины s. Достаточно произвести внешнюю итерацию цикла не Поиск кратчайших путей в графе. Алгоритм Флойда. Алгоритм Дейкстры. Алгоритм Форда-Беллмана. - student2.ru , a ровно |V| раз. Если при исполнении последней итерации длина кратчайшего пути до какой-либо вершины строго уменьшилась, то в графе есть отрицательный цикл, достижимый из s. На основе этого можно предложить следующую оптимизацию: отслеживать изменения в графе и, как только они закончатся, сделать выход из цикла (дальнейшие итерации будут бессмысленны).
Сложность; O(|E|*|V|)

Доказательство корректности:

Утверждение:G – без циклов с отриц весом. Для всех достижимых вершин v из s – d[v] = b(s,v) после алг БФ

Док-во:

Рассмотрим v – достижима из s.

P = <V0,…,Vk> - кратчайший ацикличный путь из s в v.

|P| <=|V| - 1 (ацикличный)

Во время i-ой итерации рассматриваем ребро (Vi-1, Vi).

d[v] = d[Vk] = b(s,Vk) = b(s,v). Если v – недостижима – d[v] = inf
Иначе d[v] <inf. Чтд

Утверждение – код - Алгоритм (c отрицательными циклами) корректен:

А) Нет цикла с отриц. весом

d[v] = b(s,v) <= b(s,u) + w(u,v) – нер-во треугольника

Верно для любых u и vè условие про уменьшение кр. расстояния в алгоритме не сработает на |V|-ой итерации

Б) есть цикл с отриц. Весом

С=<V0,..,Vk>. V0=Vk– цикл отриц. Веса

d[Vi] <= d[Vi-1] + w(Vi-1, Vi). Просуммируем его от 1 до k.

Т.к. V0=Vk, то сумма d[Vi-1] = сумме d[Vi] è 0<= сумме w(Vi-1, Vi) < 0 – противоречие è условие в алгоритме – сработает.

Чтд

Наши рекомендации