Алгоритм Борувки — различия между версиями
Novik (обсуждение | вклад) м (→Реализация) |
м (rollbackEdits.php mass rollback) |
||
(не показано 5 промежуточных версий 3 участников) | |||
Строка 41: | Строка 41: | ||
'''for''' <tex>\mathtt{(u,v)} \in E </tex> | '''for''' <tex>\mathtt{(u,v)} \in E </tex> | ||
'''if''' <tex>\mathtt{u.comp} \neq \mathtt{v.comp}</tex> | '''if''' <tex>\mathtt{u.comp} \neq \mathtt{v.comp}</tex> | ||
− | '''if''' <tex>w(\mathtt{minEdge}[\mathtt{u.comp}]) | + | '''if''' <tex>w(\mathtt{minEdge}[\mathtt{u.comp}]) > w(u,v)</tex> |
<tex>\mathtt{minEdge}[\mathtt{u.comp}] = (u,v)</tex> | <tex>\mathtt{minEdge}[\mathtt{u.comp}] = (u,v)</tex> | ||
− | '''if''' <tex>w(\mathtt{minEdge}[\mathtt{v.comp}]) | + | '''if''' <tex>w(\mathtt{minEdge}[\mathtt{v.comp}]) > w(u,v)</tex> |
<tex>\mathtt{minEdge}[\mathtt{v.comp}] = (u,v)</tex> | <tex>\mathtt{minEdge}[\mathtt{v.comp}] = (u,v)</tex> | ||
'''for''' <tex>k \in </tex> Component | '''for''' <tex>k \in </tex> Component | ||
− | <tex>T\mathtt{.addEdge}(\mathtt{minEdge}[k])</tex> | + | <tex>T\mathtt{.addEdge}(\mathtt{minEdge}[k])</tex> <font color = "green">// Добавляем ребро, если его не было в <tex>T</tex></font> |
'''return''' <tex>T</tex> | '''return''' <tex>T</tex> | ||
|} | |} | ||
Строка 69: | Строка 69: | ||
==Асимптотика== | ==Асимптотика== | ||
− | + | На <tex> i </tex>-ой итерации внешнего цикла каждая компонента состоит как минимум из двух компонент из <tex> (i - 1) </tex>-й итерации. Значит, на каждой итерации число компонент уменьшается как минимум в <tex> 2 </tex> раза. Тогда внешний цикл повторяется <tex>O(\log{V})</tex> раз, так как количество компонент изначально равно количеству вершин. Что же касается внутреннего цикла, то он выполняется за <tex>O(E)</tex>, где <tex>E</tex> {{---}} количество рёбер в исходном графе. Следовательно конечное время работы алгоритма <tex>O(E\log{V})</tex>. | |
==См. также== | ==См. также== |
Текущая версия на 19:07, 4 сентября 2022
Алгоритм Борувки (англ. Borůvka's algorithm) — алгоритм поиска минимального остовного дерева во взвешенном неориентированном связном графе. Впервые был опубликован в 1926 году Отакаром Борувкой.
Содержание
Описание алгоритма
Алгоритм состоит из нескольких шагов:
- Изначально каждая вершина графа — тривиальное дерево, а ребра не принадлежат никакому дереву.
- Для каждого дерева найдем минимальное инцидентное ему ребро. Добавим все такие ребра.
- Повторяем шаг пока в графе не останется только одно дерево .
Данный алгоритм может работать неправильно, если в графе есть ребра равные по весу. Например, полный граф из трех вершин, вес каждого ребра равен один. В могут быть добавлены все три ребра. Избежать эту проблему можно, например, выбирая в первом пункте среди ребер, равных по весу, ребро с наименьшим номером.
Доказательство корректности
Теорема: |
Алгоритм Борувки строит MST. |
Доказательство: |
Очевидно, что в результате работы алгоритма получается дерево. Пусть — минимальное остовное дерево графа , а — дерево полученное после работы алгоритма.Покажем, что .Предположим обратное Понятно, что в момент, когда ребро . Пусть ребро — первое добавленное ребро дерева , не принадлежащее дереву . Пусть — путь, соединяющий в дереве вершины ребра . добавляли, какое-то ребро (назовем его ) не было добавлено. По алгоритму . Однако тогда — остовное дерево веса не превышающего вес дерева . Получили противоречение. Следовательно . |
Реализация
У вершины есть поле
— компонента связности, которой принадлежит эта вершина.
//— исходный граф // — весовая функция function while for Component // Component — множество компонент связности в . Для // каждой компоненты связности вес минимального ребра = . // Разбиваем граф на компоненты связности обычным dfs-ом. for if if if for Component // Добавляем ребро, если его не было в return |
Пример
Асимптотика
На
-ой итерации внешнего цикла каждая компонента состоит как минимум из двух компонент из -й итерации. Значит, на каждой итерации число компонент уменьшается как минимум в раза. Тогда внешний цикл повторяется раз, так как количество компонент изначально равно количеству вершин. Что же касается внутреннего цикла, то он выполняется за , где — количество рёбер в исходном графе. Следовательно конечное время работы алгоритма .