Алгоритм Флойда — Уоршалла — различия между версиями

Материал из Викиконспекты
Перейти к: навигация, поиск
(Псевдокод)
(Перенаправление на Алгоритм Флойда)
 
(не показано 19 промежуточных версий 8 участников)
Строка 1: Строка 1:
==Задача==
+
#перенаправление [[Алгоритм Флойда]]
Пусть дано отношение <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, j) \subset R) </tex>. Затем внешним циклом перебираются все элементы <tex>k</tex> множества <tex>X</tex> и для каждого из них, если он может использоваться, как промежуточный для соединения двух элементов <tex>i</tex> и <tex>j</tex>, отношение <tex>T</tex> расширяется добавлением в него пары <tex>(i, j)</tex>.
 
 
 
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>
 
=== Сложность алгоритма ===
 
Три вложенных цикла работают за время <tex>\sum\limits_{n}\sum\limits_{n}\sum\limits_{n}O(1) = O(n^3)</tex>,
 
то есть алгоритм имеет кубическую сложность.
 
 
 
== Ссылки ==
 
* [http://e-maxx.ru/algo/floyd_warshall_algorithm Реализация алгоритма Флойда на С++]
 
* [http://plagiata.net.ru/?p=57 Реализация алгоритма Флойда на Delphi]
 
* [http://rain.ifmo.ru/cat/data/vis/graph-paths/floyd-warshall-2004/code.jar Визуализатор]
 
* [http://ru.wikipedia.org/wiki/Заглавная_страница Википедия — свободная энциклопедия]
 
 
 
== Источники ==
 
* Романовский И. В. '''Дискретный анализ: Учебное пособие для студентов, специализирующихся по прикладной математике и информатике'''. Изд. 3-е. — СПб.: Невский диалект, 2003. — 320 с. — ISBN 5-7940-0114-3.
 

Текущая версия на 19:39, 27 декабря 2015

Перенаправление на: