Изменения

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

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

2871 байт добавлено, 19:07, 4 сентября 2022
м
rollbackEdits.php mass rollback
<b>Алгоритм Борувки</b> (англ. ''Borůvka's algorithm'') {{---}} алгоритм поиска [[Остовные деревья: определения, лемма о безопасном ребре | минимального остовного дерева (minimum spanning tree, MST) ]] во взвешенном неориентированном связном графе.
Впервые был опубликован в 1926 году Отакаром Борувкой.
==Описание алгоритма==
Пусть <tex>T</tex> подграф графа <tex>G</tex>. Изначально <tex>T</tex> содердит все вершины из <tex>G</tex> и не содержит ребер.
Будем добавлять в <tex>T</tex> ребра следующим образомАлгоритм состоит из нескольких шагов:
Пока # Изначально каждая вершина графа <tex>TG </tex> не является деревом# Для каждой компоненты связанности находим минимальное по весу ребро, которое связывает вершину из данной компоненты с вершиной{{---}} тривиальное дерево, а ребра не принадлежащей данной компонентепринадлежат никакому дереву. # Добавим в Для каждого дерева <tex>T</tex> найдем минимальное инцидентное ему ребро. Добавим все такие ребра, которые хотя бы для одной компоненты оказались минимальными.Получившийся граф # Повторяем шаг <tex> 2 </tex> пока в графе не останется только одно дерево <tex>T</tex> является минимальным остовным деревом графа .   Данный алгоритм может работать неправильно, если в графе есть ребра равные по весу. Например, полный граф из трех вершин, вес каждого ребра равен один. В <tex>GT</tex>могут быть добавлены все три ребра. Избежать эту проблему можно, например, выбирая в первом пункте среди ребер, равных по весу, ребро с наименьшим номером.
==Доказательство корректности==
{{Лемма
|id=lemma1
|statement=Рассмотрим связный неориентированный взвешенный граф <tex> G = (V, E) </tex> с весовой функцией <tex>w : E \to \mathbb{R}</tex>.
Тогда после первой итерации алгоритма Борувки получившийся подграф можно достроить до MST.
|proof=Предположим обратное: пусть любое MST графа <tex>G</tex> не содержит <tex>T</tex>. Рассмотрим какое-нибудь MST.Тогда существует ребро x из <tex>T</tex> такое что <tex>x</tex> не принадлежит MST. Добавив ребро <tex>x</tex> в MST получаем цикл в котором <tex>x</tex> не максимально т.к оно было минимальным. Тогда, исходя из критерия тарьяна, получаем противоречие.
}}
{{Теорема
|id=th1. |statement=Алгоритм Борувки строит '''MST'''.|proof=Будем доказывать Очевидно, что после каждой итерации главного цикла в алгоритме Борувки мы можем текущее результате работы алгоритма получается дерево. Пусть <tex> T </tex> {{---}} минимальное остовное дерево графа <tex> G </tex>, а <tex>T' </tex> до MST{{---}} дерево полученное после работы алгоритма.Докажем это по индукции Покажем, что <tex> T = T'</tex>.База: n = 1Предположим обратное <tex> T \neq T' </tex>. Пусть ребро <tex> e' </tex> {{---}} первое добавленное ребро дерева <tex> T' </tex>, не принадлежащее дереву <tex> T </tex>. Пусть <tex> P </tex> {{---}} путь, соединяющий в дереве <tex> T </tex> вершины ребра <tex> e' </tex>.  Понятно, что в момент, когда ребро <tex> e' </tex> добавляли, какое-то ребро <tex> P </tex> (назовем его <tex> e </tex>) не было добавлено. По алгоритму <tex> w(e) \geqslant w(Лемма 1e')</tex>.Переход: Пусть Однако тогда <tex> T - e + e' </tex> {{---}} остовное дерево получившееся после n итераций алгоритма можно достроить до MSTвеса не превышающего вес дерева <tex> T </tex>. Получили противоречение. Следовательно <tex> T = T'</tex>.
}}
==Реализация==
У вершины есть поле <tex>\mathtt{comp}</tex> {{---}} компонента связности, которой принадлежит эта вершина.
 
{| width = 100%
|-
|
Graph Boruvka<font color=green>// <tex>G</tex> {{---}} исходный граф</font> <font color=green>// <tex>w</tex> {{---}} весовая функция</font> '''function''' <tex>\mathtt{boruvkaMST}(Graph G):</tex> '''while ''' <tex>T\mathtt{.size } < n- 1</tex> init'''for''' <tex>k \in </tex> Component <font color = "green">// Component {{---}} множество компонент связности в <tex>T</tex>. Для </font> <tex>w(\mathtt{minEdge}[k]) =\infty</tex> <font color = "green">// каждой компоненты связности вес минимального ребра = <tex>\infty</tex>.</ у вершины есть поле comp(компонента которой принадлежит вершина) font> <tex>\mathtt{findComp(}T\mathtt{) }</tex> <font color = "green">// разбиваеv Разбиваем граф <tex>T </tex> на компоненты связынности связности обычным ''dfs''-ом.</font> '''for uv ''' <tex>\mathtt{(u,v)} \in E </tex> E '''if ''' <tex>\mathtt{u.comp != } \neq \mathtt{v.comp}</tex> '''if ''' <tex>w(\mathtt{minEdge}[\mathtt{u.comp}].) > w (u,v)< uv.w/tex> <tex>\mathtt{minEdge}[\mathtt{u.comp}] = uv(u,v)</tex> '''if ''' <tex>w(\mathtt{minEdge}[\mathtt{v.comp}].) > w (u,v)< uv.w/tex> <tex>\mathtt{minEdge}[\mathtt{v.comp}] = uv(u,v)</tex> '''for k ''' <tex>k \in</tex> Comp // Comp — множество компонент связанности в TComponent <tex>T\mathtt{.addEdge}(\mathtt{minEdge}[k])</tex> <font color = "green">// Добавляем ребро, если его не было в <tex>T</tex></font> '''return ''' <tex>T; </tex> |} ==Пример=={| class = "wikitable"! Изображение !! Компоненты связности !! Описание|-align="center"|[[Файл:Boruvka_1.png|250px]]| <tex>\{A\}</tex><br/><tex>\{B\}</tex><br/><tex>\{C\}</tex><br/><tex>\{D\}</tex><br/><tex>\{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> i </tex>-ой итерации внешнего цикла будет равно каждая компонента состоит как минимум из двух компонент из <tex>O(E + Vi - 1)</tex>-й итерации. Значит, на каждой итерации число компонент уменьшается как минимум в <tex> 2 </tex> разаКоличество итераций которое выполняется главным циклом равно Тогда внешний цикл повторяется <tex>O(\log{V})</tex> раз, так как на каждой итерации количество компонент связанности уменьшается в 2 раза (изначально количество компонент равно количеству вершин. Что же касается внутреннего цикла, то он выполняется за <tex>|V|O(E)</tex>, где <tex>E</tex> {{---}} количество рёбер в итоге должна стать одна компонента)исходном графеОбщее Следовательно конечное время работы алгоритма получается <tex>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
правки

Навигация