Алгоритм Флойда — Уоршалла — различия между версиями
Строка 1: | Строка 1: | ||
==Задача== | ==Задача== | ||
− | Пусть дано отношение <tex>R</tex> на множестве <tex>X</tex>. Необходимо построить его [[Транзитивное замыкание|транзитивное замыкание]] <tex>\mathrm{TrCl}(R)</tex>. | + | Пусть дано отношение <tex>R</tex> на множестве <tex>X</tex>. Необходимо построить его [[Транзитивное замыкание|транзитивное замыкание]] <tex>T = \mathrm{TrCl}(R)</tex>. |
+ | |||
== Алгоритм == | == Алгоритм == | ||
− | + | Сформулируем нашу задачу в терминах графов: рассмотрим граф <tex>G=(V,\; E),\; |V| = n</tex>, соответствующий отношению <tex>R</tex>. Тогда необходимо найти все пары вершин <tex>(x, y) </tex>, соединенных некоторым путем. | |
− | + | Иными словами, требуется построить новое отношение <tex>T</tex>, которое будет состоять из всех пар <tex>(x, y) </tex> таких, что найдется последовательность <tex>x = x_0, x_1, \dots, x_k = y </tex>, где <tex> (x_{i-1}, x_i) \subset R, i = 1, 2, \dots, k </tex>. | |
− | |||
− | |||
− | |||
=== Псевдокод === | === Псевдокод === | ||
− | + | Изначально матрица <tex>W</tex> заполняется соответственно отношению <tex>R</tex>, то есть <tex>W[i][j] = ((i, ) \subset R) </tex>. Затем внешним циклом перебираются все элементы множества <tex>X</tex> и для каждого <tex>k</tex> из них, если он может использоваться, как промежуточный для соединения двух элементов <tex>i</tex> и <tex>j</tex>, отношение <tex>T</tex> расширяется добавлением в него пары <tex>(i, j)</tex>. | |
− | |||
for k = 1 to n | for k = 1 to n | ||
Строка 17: | Строка 14: | ||
W[i][j] = W[i][j] or (W[i][k] and W[k][j]) | W[i][j] = W[i][j] or (W[i][k] and W[k][j]) | ||
+ | === Обоснование === | ||
+ | <wikitex> | ||
+ | Покажем, что если в отношении $R$ существовал путь $x = x_0, x_1, \dots, x_k = y$, то после работы алгоритма отношение $T$ будет содержать пару $(x, y)$. Действительно, как только параметр внешнего цикла дойдет до вершины $u$, лежащей внутри этого пути, то обязательно появится дуга, минующая эту вершину, то есть появится путь из $x$ в $y$ на одну дугу короче предыдущего. После полного просмотра элементов множества $M$ внешним циклом мы исключим все промежуточные вершины.</wikitex> | ||
=== Сложность алгоритма === | === Сложность алгоритма === | ||
Три вложенных цикла работают за время <tex>\sum\limits_{n}\sum\limits_{n}\sum\limits_{n}O(1) = O(n^3)</tex>, | Три вложенных цикла работают за время <tex>\sum\limits_{n}\sum\limits_{n}\sum\limits_{n}O(1) = O(n^3)</tex>, |
Версия 02:40, 24 ноября 2011
Задача
Пусть дано отношение транзитивное замыкание .
на множестве . Необходимо построить егоАлгоритм
Сформулируем нашу задачу в терминах графов: рассмотрим граф
, соответствующий отношению . Тогда необходимо найти все пары вершин , соединенных некоторым путем. Иными словами, требуется построить новое отношение , которое будет состоять из всех пар таких, что найдется последовательность , где .Псевдокод
Изначально матрица
заполняется соответственно отношению , то есть . Затем внешним циклом перебираются все элементы множества и для каждого из них, если он может использоваться, как промежуточный для соединения двух элементов и , отношение расширяется добавлением в него пары .for k = 1 to n for i = 1 to n for j = 1 to n W[i][j] = W[i][j] or (W[i][k] and W[k][j])
Обоснование
<wikitex> Покажем, что если в отношении $R$ существовал путь $x = x_0, x_1, \dots, x_k = y$, то после работы алгоритма отношение $T$ будет содержать пару $(x, y)$. Действительно, как только параметр внешнего цикла дойдет до вершины $u$, лежащей внутри этого пути, то обязательно появится дуга, минующая эту вершину, то есть появится путь из $x$ в $y$ на одну дугу короче предыдущего. После полного просмотра элементов множества $M$ внешним циклом мы исключим все промежуточные вершины.</wikitex>
Сложность алгоритма
Три вложенных цикла работают за время
, то есть алгоритм имеет кубическую сложность.