Флойд-Уоршалл (Floyd-Warshall)

Вход: взвешенный орграф
Выход: матрица длин кратчайших путей.
Алгоритм:
For v = 1 to V

For i = 1 to V

For j = 1 to V

Table[ i ][ j ] = min (Table[ i ][ j ], Table[ i ][ v ] + Table[ v ][ j ]);

Сложность: O(|V|^3)

Док-во корректности:

Ключевая идея алгоритма — разбиение процесса поиска кратчайших путей на фазы.

Перед Флойд-Уоршалл (Floyd-Warshall) - student2.ru -ой фазой ( Флойд-Уоршалл (Floyd-Warshall) - student2.ru ) считается, что в матрице расстояний Флойд-Уоршалл (Floyd-Warshall) - student2.ru сохранены длины таких кратчайших путей, которые содержат в качестве внутренних вершин только вершины из множества Флойд-Уоршалл (Floyd-Warshall) - student2.ru (вершины графа мы нумеруем, начиная с единицы).

Иными словами, перед Флойд-Уоршалл (Floyd-Warshall) - student2.ru -ой фазой величина Флойд-Уоршалл (Floyd-Warshall) - student2.ru равна длине кратчайшего пути из вершины Флойд-Уоршалл (Floyd-Warshall) - student2.ru в вершину Флойд-Уоршалл (Floyd-Warshall) - student2.ru , если этому пути разрешается заходить только в вершины с номерами, меньшими Флойд-Уоршалл (Floyd-Warshall) - student2.ru (начало и конец пути не считаются).

Легко убедиться, что чтобы это свойство выполнилось для первой фазы, достаточно в матрицу расстояний Флойд-Уоршалл (Floyd-Warshall) - student2.ru записать матрицу смежности графа: Флойд-Уоршалл (Floyd-Warshall) - student2.ru — стоимости ребра из вершины Флойд-Уоршалл (Floyd-Warshall) - student2.ru в вершину Флойд-Уоршалл (Floyd-Warshall) - student2.ru . При этом, если между какими-то вершинами ребра нет, то записать следует величину "бесконечность" Флойд-Уоршалл (Floyd-Warshall) - student2.ru . Из вершины в саму себя всегда следует записывать величину Флойд-Уоршалл (Floyd-Warshall) - student2.ru , это критично для алгоритма.

Пусть теперь мы находимся на Флойд-Уоршалл (Floyd-Warshall) - student2.ru -ой фазе, и хотим пересчитать матрицу Флойд-Уоршалл (Floyd-Warshall) - student2.ru таким образом, чтобы она соответствовала требованиям уже для Флойд-Уоршалл (Floyd-Warshall) - student2.ru -ой фазы. Зафиксируем какие-то вершины Флойд-Уоршалл (Floyd-Warshall) - student2.ru и Флойд-Уоршалл (Floyd-Warshall) - student2.ru . У нас возникает два принципиально разных случая:

· Кратчайший путь из вершины Флойд-Уоршалл (Floyd-Warshall) - student2.ru в вершину Флойд-Уоршалл (Floyd-Warshall) - student2.ru , которому разрешено дополнительно проходить через вершины Флойд-Уоршалл (Floyd-Warshall) - student2.ru , совпадает с кратчайшим путём, которому разрешено проходить через вершины множества Флойд-Уоршалл (Floyd-Warshall) - student2.ru .

В этом случае величина Флойд-Уоршалл (Floyd-Warshall) - student2.ru не изменится при переходе с Флойд-Уоршалл (Floyd-Warshall) - student2.ru -ой на Флойд-Уоршалл (Floyd-Warshall) - student2.ru -ую фазу.

· "Новый" кратчайший путь стал лучше "старого" пути.

Это означает, что "новый" кратчайший путь проходит через вершину Флойд-Уоршалл (Floyd-Warshall) - student2.ru . Сразу отметим, что мы не потеряем общности, рассматривая далее только простые пути (т.е. пути, не проходящие по какой-то вершине дважды).

Тогда заметим, что если мы разобьём этот "новый" путь вершиной Флойд-Уоршалл (Floyd-Warshall) - student2.ru на две половинки (одна идущая Флойд-Уоршалл (Floyd-Warshall) - student2.ru , а другая — Флойд-Уоршалл (Floyd-Warshall) - student2.ru ), то каждая из этих половинок уже не заходит в вершину Флойд-Уоршалл (Floyd-Warshall) - student2.ru . Но тогда получается, что длина каждой из этих половинок была посчитана ещё на Флойд-Уоршалл (Floyd-Warshall) - student2.ru -ой фазе или ещё раньше, и нам достаточно взять просто сумму Флойд-Уоршалл (Floyd-Warshall) - student2.ru , она и даст длину "нового" кратчайшего пути.

Объединяя эти два случая, получаем, что на Флойд-Уоршалл (Floyd-Warshall) - student2.ru -ой фазе требуется пересчитать длины кратчайших путей между всеми парами вершин Флойд-Уоршалл (Floyd-Warshall) - student2.ru и Флойд-Уоршалл (Floyd-Warshall) - student2.ru следующим образом:

new_d[i][j] = min (d[i][j], d[i][k] + d[k][j]);

Таким образом, вся работа, которую требуется произвести на Флойд-Уоршалл (Floyd-Warshall) - student2.ru -ой фазе — это перебрать все пары вершин и пересчитать длину кратчайшего пути между ними. В результате после выполнения Флойд-Уоршалл (Floyd-Warshall) - student2.ru -ой фазы в матрице расстояний Флойд-Уоршалл (Floyd-Warshall) - student2.ru будет записана длина кратчайшего пути между Флойд-Уоршалл (Floyd-Warshall) - student2.ru и Флойд-Уоршалл (Floyd-Warshall) - student2.ru , либо Флойд-Уоршалл (Floyd-Warshall) - student2.ru , если пути между этими вершинами не существует.

Последнее замечание, которое следует сделать, — то, что можно не создавать отдельную матрицу Флойд-Уоршалл (Floyd-Warshall) - student2.ru для временной матрицы кратчайших путей на Флойд-Уоршалл (Floyd-Warshall) - student2.ru -ой фазе: все изменения можно делать сразу в матрице Флойд-Уоршалл (Floyd-Warshall) - student2.ru . В самом деле, если мы улучшили (уменьшили) какое-то значение в матрице расстояний, мы не могли ухудшить тем самым длину кратчайшего пути для каких-то других пар вершин, обработанных позднее.

Асимптотика алгоритма, очевидно, составляет Флойд-Уоршалл (Floyd-Warshall) - student2.ru .

Алгоритм A*. Эвристики.

Алгоритм поиска А*

Находит маршрут с наименьшей стоимостью от одной вершины (начальной) к другой (конечной) с использованием эвристической функцией.
Вход: взвешенный граф, начальная вершина, конечная вершина.
Выход: последовательность вершин от начальной вершины до конечной.
Алгоритм: в каждой вершине есть поля h(x) - допустимая эвристическая оценка до конечной вершины (не превышает реального расстояния), g(x) - стоимость пути он начальной вершины, f(x) = g(x) + h(x). Алгоритм пошагово просматривает все пути, ведущие от начальной вершины в конечную, пока не найдет минимальный. В первую очередь он просматривает то алгоритмы, которые “кажутся” ведущими к цели, основываясь на значении функции f(x). В начале работы просматриваются вершины, смежные с данной, из них выбирается с минимальным значением f(x), после чего этот узел “закрывается” (помещается в множество “закрытых вершин”). На каждом этапе алгоритм работает с множеством “открытых вершин” (еще не пройденных), которые помещаются в очередь с приоритетом (приоритет по значению f(x)). Алгоритм продолжает свою работу до тех пор, пока значение f(x) целевой вершины не окажется меньшим, чем любое значение в очереди (либо пока всё дерево не будет просмотрено). Из множественных решений выбирается решение с наименьшей стоимостью.

Требования для эвристики (оценки)

1. h(u,t) <= b(u,t) – кратчайшее расстояние

2. h(a,c) <= h(a,b) + h(b,c)

Если сделать f(x) = g(x) – это Дейкстра.

Если всем вершинам сделать одинаковые, большие веса, а при доставании вершины из очереди уменьшать на 1 приоритет соседей – то будет BFS

Эвристики:

Поведение алгоритма сильно зависит от того, какая эвристика используется. В свою очередь, выбор эвристики зависит от постановки задачи. Часто А* используется для моделирования перемещения по поверхности, покрытой координатной сеткой.

§ Если мы можем перемещаться в четырех направлениях, в качестве эвристики стоит выбрать манхэттенское расстояние
Флойд-Уоршалл (Floyd-Warshall) - student2.ru .

§ Расстояние Чебышева применяется когда к четырем направлениям добавляются диагонали:
Флойд-Уоршалл (Floyd-Warshall) - student2.ru .

§ Если передвижение не ограниченно сеткой, то можно использовать евклидово расстояние по прямой:
Флойд-Уоршалл (Floyd-Warshall) - student2.ru .

Также стоит обратить внимание на то как соотносятся Флойд-Уоршалл (Floyd-Warshall) - student2.ru и Флойд-Уоршалл (Floyd-Warshall) - student2.ru . Если они измеряются в разных величинах (например, Флойд-Уоршалл (Floyd-Warshall) - student2.ru — это расстояние в километрах, а Флойд-Уоршалл (Floyd-Warshall) - student2.ru — оценка времени пути в часах) А* может выдать некорректный результат.


Псевдокод:
OPEN = priority queue containing START
CLOSED = empty set
while lowest rank in OPEN is not the GOAL:
current = remove lowest rank item from OPEN
add current to CLOSED
for neighbors of current:
cost = g(current) + movementcost(current, neighbor)
if neighbor in OPEN and cost less than g(neighbor):
remove neighbor from OPEN, because new path is better
if neighbor not in OPEN and neighbor not in CLOSED:
set g(neighbor) to cost
add neighbor to OPEN
set priority queue rank to g(neighbor) + h(neighbor)
set neighbor's parent to current

reconstruct reverse path from goal to start
by following parent pointers

Если пишем пятнашки:

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