Минимально узкое остовное дерево — различия между версиями
Nemzs (обсуждение | вклад) (→Свойства минимального узкого остовного дерева) |
Nemzs (обсуждение | вклад) (→Асимптотика) |
||
| Строка 28: | Строка 28: | ||
Найдём максимальное ребро в нашем дереве. Добавим рёбра с весом меньше максимального при помощи [[СНМ (наивные реализации)|СНМ]], чтобы определить его связность. Если в результате у нас все вершины лежат в одном множестве, значит наше дерево не является <tex>\mathrm{MBST}</tex>, иначе оно <tex>\mathrm{MBST}</tex>. | Найдём максимальное ребро в нашем дереве. Добавим рёбра с весом меньше максимального при помощи [[СНМ (наивные реализации)|СНМ]], чтобы определить его связность. Если в результате у нас все вершины лежат в одном множестве, значит наше дерево не является <tex>\mathrm{MBST}</tex>, иначе оно <tex>\mathrm{MBST}</tex>. | ||
=== Асимптотика === | === Асимптотика === | ||
| − | По каждому ребру пройдём один раз, для поиска максимального, займёт <tex>O(N)</tex>.<br>Работа с СНМ займет <tex>O(N\alpha(V))</tex>, где <tex>\alpha</tex> — обратная функция Аккермана, которая не превосходит <tex>4</tex> во всех практических приложениях и которую можно принять за константу.<br>В результате получаем алгоритм работающий за линейное время <tex>O(N)</tex>. | + | По каждому ребру пройдём один раз, для поиска максимального, займёт <tex>O(N)</tex>, где <tex>N -</tex> количество рёбер в графе.<br>Работа с СНМ займет <tex>O(N\alpha(V))</tex>, где <tex>\alpha</tex> — обратная функция Аккермана, которая не превосходит <tex>4</tex> во всех практических приложениях и которую можно принять за константу.<br>В результате получаем алгоритм работающий за линейное время <tex>O(N)</tex>. |
| + | |||
=== Псевдокод === | === Псевдокод === | ||
Все рёбра графа будем хранить в списке <tex>\mathtt{e}</tex>, а рёбра остовного дерева в списке <tex>\mathtt{tree}</tex>.<br> | Все рёбра графа будем хранить в списке <tex>\mathtt{e}</tex>, а рёбра остовного дерева в списке <tex>\mathtt{tree}</tex>.<br> | ||
Версия 23:07, 8 января 2017
| Определение: |
| Минимально узкое остовное дерево (англ. Minimum bottleneck spanning tree, MBST) в связанном взвешенном неориентированном графе остовное дерево графа, у которого максимальное ребро минимально. |
| Определение: |
| Узким ребром в графе назовём максимальное по весу. |
| Определение: |
| Остовное дерево является минимально узким, если в графе нет остовного дерева с меньшим узким ребром. |
Содержание
Свойства минимального узкого остовного дерева
| Свойство MBST: |
| Каждое минимальное остовное дерево является . |
| Предположим, если минимальное остовное не является , значит в графе существует набор ребер которые мы не взяли в наш остов, при замене на которые, наше дерево станет . Также рёбра вне остова должны быть меньше рёбер из остова, чтобы уменьшить минимальное максимально ребро. Но по определению , сумма рёбер дерева минимальна, значит вне остова нету рёбер с меньшим весом. Так как наше предположение неверно, является . |
| Свойство MBST: |
| не всегда является минимальным остовным деревом. |
|
Рассмотрим пример, где не является минимальным остовным деревом: |
Проверка остовного дерева на узкость
| Задача: |
| Проверить остовное дерево в графе на . |
Алгоритм
Построим новый граф, добавим туда все рёбра меньше максимального из нашего остова. Если в результате у нас получится связный граф, значит мы сможем выделить из него остовное дерево с меньшим узким ребром наше дерево не самое узкое. Иначе, для связности графа нам необходимо добавить максимальные рёбра наше дерево является минимально узким. Найдём максимальное ребро в нашем дереве. Добавим рёбра с весом меньше максимального при помощи СНМ, чтобы определить его связность. Если в результате у нас все вершины лежат в одном множестве, значит наше дерево не является , иначе оно .
Асимптотика
По каждому ребру пройдём один раз, для поиска максимального, займёт , где количество рёбер в графе.
Работа с СНМ займет , где — обратная функция Аккермана, которая не превосходит во всех практических приложениях и которую можно принять за константу.
В результате получаем алгоритм работающий за линейное время .
Псевдокод
Все рёбра графа будем хранить в списке , а рёбра остовного дерева в списке .
В каждом ребре храним следующую информацию:
- — соединяемые вершины
- — вес ребра
bool ifMBST(Edge[] e, Edge[] tree):
int united = 0 // Сколько вершин мы объединили
int maxEdge = -
for i = 1 to tree.size
maxEdge = max(maxEdge, tree[i].cost) // Поиск максимального ребра в дереве
for i = 1 to n
if e[i].cost >= maxEdge // Не соединяем вершины, если ребро не меньше максимального
continue
if find(e[i].from]) != find(e[i].to) // Объединяем вершины, если они в разных множествах
united++
unite(e[i].from,e[i].to)
if united == e.size - 1 // Дерево подходит, если в результате мы соединили все вершины
return true
else
return false

