Изменения

Перейти к: навигация, поиск

Алгоритм Борувки

3211 байт добавлено, 19:07, 4 сентября 2022
м
rollbackEdits.php mass rollback
<b>Алгоритм Борувки</b> (англ. ''Borůvka's algorithm'') {{---}} алгоритм поиска [[Остовные деревья: определения, лемма о безопасном ребре | минимального остовного дерева (minimum spanning tree, MST) ]] во взвешенном неориентированном связном графе.
Впервые был опубликован в 1926 году Отакаром Борувкой.
==Описание алгоритма==
<tex>F</tex> — подграф исходого графа <tex>G</tex>.
пока <tex>F</tex> не является деревом:
1)для каждой компоненты связанности находим минимальное ребро, которое связывает вершину из данной компоненты с вершиной не принадлежащей данной компоненте.
2) добавим в t
Будем последовательно строить подграф Алгоритм состоит из нескольких шагов: # Изначально каждая вершина графа <tex> G </tex >{{---}} тривиальное дерево, а ребра не принадлежат никакому дереву.# Для каждого дерева <tex>FT </tex> графа найдем минимальное инцидентное ему ребро. Добавим все такие ребра.# Повторяем шаг <tex> 2 </tex> пока в графе не останется только одно дерево <tex>GT </tex> ("растущий лес").   Данный алгоритм может работать неправильно, если в графе есть ребра равные по весу. Например, полный граф из трех вершин, поддерживая следующий инвариант: на каждом шаге вес каждого ребра равен один. В <tex>FT</tex> могут быть добавлены все три ребра. Избежать эту проблему можно достроить до некоторого , например, выбирая в первом пункте среди ребер, равных по весу, ребро с наименьшим номером. ==Доказательство корректности== {{Теорема|statement= Алгоритм Борувки строит '''MST'''. Начнем с того|proof=Очевидно, что включим в результате работы алгоритма получается дерево. Пусть <tex>FT </tex> все вершины {{---}} минимальное остовное дерево графа <tex>G</tex>, а <tex> T' </tex> {{---}} дерево полученное после работы алгоритма. Покажем, что <tex> T = T'</tex>. Теперь будем обходить множество  Предположим обратное <tex>EGT \neq T' </tex> в порядке увеличения веса ребер. Добавление очередного ребра Пусть ребро <tex>e' </tex> в {{---}} первое добавленное ребро дерева <tex>FT' </tex> может привести к возникновению цикла в одной из компонент связности , не принадлежащее дереву <tex>FT </tex>. В этом случае, очевидно, Пусть <tex>eP </tex> не может быть включено {{---}} путь, соединяющий в дереве <tex>FT </tex>. В противном случае вершины ребра <tex>e' </tex> соединяет разные компоненты связности .  Понятно, что в момент, когда ребро <tex>Fe' </tex>добавляли, тогда существует [[Лемма о безопасном ребре#Необходимые определения|разрез]] какое-то ребро <tex> \langle S, T \rangle P </tex> такой, что одна из компонент связности составляет одну (назовем его часть, а оставшаяся часть графа - вторую<tex> e </tex>) не было добавлено. Тогда По алгоритму <tex>w(e) \geqslant w(e') </tex> и есть минимальное ребро, пересекающее этот разрез. Значит, из [[Лемма о безопасном ребре|леммы о безопасном ребре]] следует, что Однако тогда <tex>FT - e +e' </tex> можно продолжить до MST, поэтому добавим это ребро в {{---}} остовное дерево веса не превышающего вес дерева <tex>FT </tex>.Получили противоречение. Следовательно <brtex>T = T'</tex>.Несложно понять, что после выполнения такой процедуры получится остовное дерево, при этом его минимальность вытекает из леммы о безопасном ребре.}}
==Реализация==
У вершины есть поле <btex>Вход\mathtt{comp}</btex> {{---}} компонента связности, которой принадлежит эта вершина. {| width = 100%|-| <font color=green>: граф // <tex>G </tex> {{---}} исходный граф</font> <font color= green>// <tex>w</tex> {{---}} весовая функция</font> '''function''' <tex>\mathtt{boruvkaMST}(V, E):</tex> '''while''' <tex>T\mathtt{.size} <brn - 1</tex> '''for''' <btex>Выходk \in </btex>: минимальный остов Component <font color = "green">// Component {{---}} множество компонент связности в <tex>T</tex>. Для </font> <tex>Fw(\mathtt{minEdge}[k])=\infty</tex> графа <font color = "green">// каждой компоненты связности вес минимального ребра = <tex>G\infty</tex>.<br/font>1) <tex>F := \mathtt{findComp(V, }T\varnothingmathtt{)}</tex> <brfont color = "green">// Разбиваем граф <tex>T</tex> на компоненты связности обычным ''dfs''-ом.</font>1) Отсортируем '''for''' <tex>\mathtt{(u,v)} \in E</tex> по весу ребер '''if''' <tex>\mathtt{u.comp} \neq \mathtt{v.comp}<br/tex>2 '''if''' <tex>w(\mathtt{minEdge}[\mathtt{u.comp}]) Заведем систему непересекающихся множеств > w(DSUu,v) и инициализируем ее множеством </tex> <tex>V\mathtt{minEdge}[\mathtt{u.comp}] = (u,v)</tex> '''if''' <tex>w(\mathtt{minEdge}[\mathtt{v.comp}]) > w(u,v)<br/tex>3 <tex>\mathtt{minEdge}[\mathtt{v.comp}] = (u,v) Перебирая ребра </tex> '''for''' <tex>uv k \in EG</tex> Component <tex>T\mathtt{.addEdge}(\mathtt{minEdge}[k])</tex> <font color = "green">// Добавляем ребро, если его не было в порядке увеличения веса, смотрим, принадлежат ли <tex>uT</tex> и </font> '''return''' <tex>vT</tex> одному множеству |} ==Пример=={| class = "wikitable"! Изображение !! Компоненты связности !! Описание|-align="center"|[[Файл:Boruvka_1. Если нет, то объединяем множества, в которых лежат png|250px]]| <tex>\{A\}</tex><br/><tex>\{B\}</tex><br/><tex>u\{C\}</tex> и <br/><tex>v\{D\}</tex>, и добавляем ребро <br/><tex>uv\{E\}</tex> к <br/><tex>\{F\}</tex><br/><tex>\{G\}</tex>|Начальный граф <tex>G</tex>.Каждая вершина является компонентой (синие окружности).|-align="center"|[[Файл:Boruvka_2.png|250px]]| <tex>\{ABDF\}</tex><br/><tex>\{CEG\}</tex>|На первой итерации внешнего цикла для каждой компоненты были добавлены минимальные сопряженные ребра. Некоторые ребра добавлены несколько раз (<tex dpi = 120>AD</tex> и <tex dpi = 120>CE</tex>). Осталось две компоненты.|-align="center"|[[Файл:Boruvka_3.png|250px]]| <tex>\{ABCDEFG\}</tex>|На последней итерации внешнего цикла было добавлено минимальное ребро, соединяющее две оставшиеся компоненты (ребро <tex dpi = 120>BE</tex>). Осталась одна компонента. Минимальное остовное дерево графа <tex dpi = 120>G</tex> построено. |-|}
==Асимптотика==
Сортировка На <tex>Ei </tex> займет -ой итерации внешнего цикла каждая компонента состоит как минимум из двух компонент из <tex>O(E\log Ei - 1)</tex>-й итерации.Значит, на каждой итерации число компонент уменьшается как минимум в <tex> 2 <br/tex>Работа с DSU займет раза. Тогда внешний цикл повторяется <tex>O(E\alpha(log{V})</tex> раз, так как количество компонент изначально равно количеству вершин. Что же касается внутреннего цикла, то он выполняется за <tex>O(E)</tex>, где <tex>\alphaE</tex> {{-- обратная функция Аккермана, которая не превосходит 4 во всех практических приложениях и которую можно принять за константу-}} количество рёбер в исходном графе.<br>Алгоритм работает за Следовательно конечное время работы алгоритма <tex>O(E(\log E+\alpha(V))) = O(E\log E) = O(E\log V^2) = O(E\log {V})</tex>. ==Литература==* ''Кормен, Томас Х., Лейзерсон, Чарльз И., Ривест, Рональд Л., Штайн Клиффорд'' '''Алгоритмы: построение и анализ''', 2-е издание. Пер. с англ. — М.:Издательский дом "Вильямс", 2010. — 1296 с.: ил. — Парал. тит. англ. — ISBN 978-5-8459-0857-5 (рус.)
==См. также==
* [[Алгоритм Прима]]
* [[Алгоритм Краскала]]
* [[Алгоритм двух китайцев]]
 
== Источники информации ==
* [http://rain.ifmo.ru/cat/view.php/vis/graph-spanning-trees/mst-2006 Визуализатор алгоритма]
* [http://www.csee.wvu.edu/~ksmani/courses/fa01/random/lecnotes/lecture11.pdf Minimum Spanning Trees]
* [[wikipedia:ru:Алгоритм Борувки|Алгоритм Борувки— Википедия]]
[[Категория: Алгоритмы и структуры данных]]
[[Категория: Остовные деревья ]]
1632
правки

Навигация