Минимально узкое остовное дерево — различия между версиями
| м (rollbackEdits.php mass rollback) | |||
| (не показано 9 промежуточных версий 4 участников) | |||
| Строка 1: | Строка 1: | ||
| + | __TOC__ | ||
| + | |||
| {{Определение | {{Определение | ||
| |definition='''Минимально узкое остовное дерево''' (англ. ''Minimum bottleneck spanning tree'', ''MBST'') в связанном взвешенном неориентированном графе <tex>-</tex> [[Остовные деревья: определения, лемма о безопасном ребре|остовное дерево]] графа, у которого максимальное ребро минимально. | |definition='''Минимально узкое остовное дерево''' (англ. ''Minimum bottleneck spanning tree'', ''MBST'') в связанном взвешенном неориентированном графе <tex>-</tex> [[Остовные деревья: определения, лемма о безопасном ребре|остовное дерево]] графа, у которого максимальное ребро минимально. | ||
| }} | }} | ||
| {{Определение | {{Определение | ||
| − | |definition=Узким ребром в графе назовём максимальное по весу. | + | |definition='''Узким ребром''' (англ. ''bottleneck edge'') в графе назовём максимальное по весу. | 
| }} | }} | ||
| {{Определение | {{Определение | ||
| − | |definition=Остовное дерево является минимально узким, если в графе нет остовного дерева с меньшим узким ребром. | + | |definition=Остовное дерево является '''минимально узким''' (англ. ''minimum bottleneck''), если в графе нет остовного дерева с меньшим узким ребром. | 
| }} | }} | ||
| == Свойства минимального узкого остовного дерева == | == Свойства минимального узкого остовного дерева == | ||
| − | {{ | + | {{Утверждение с MBST | 
| − | | | + | |statement=Каждое минимальное остовное дерево является <tex>\mathrm{MBST}</tex>. | 
| |proof=Предположим, если минимальное остовное не является <tex>\mathrm{MBST}</tex>, значит в графе существует набор ребер которые мы не взяли в наш остов, при замене на которые, наше дерево станет <tex>\mathrm{MBST}</tex>. Также рёбра вне остова должны быть меньше рёбер из остова, чтобы уменьшить минимальное максимально ребро. Но по определению <tex>\mathrm{MST}</tex>, сумма рёбер дерева минимальна, значит вне остова нету рёбер с меньшим весом. Так как наше предположение неверно, <tex>\mathrm{MST}</tex> является <tex>\mathrm{MBST}</tex>. | |proof=Предположим, если минимальное остовное не является <tex>\mathrm{MBST}</tex>, значит в графе существует набор ребер которые мы не взяли в наш остов, при замене на которые, наше дерево станет <tex>\mathrm{MBST}</tex>. Также рёбра вне остова должны быть меньше рёбер из остова, чтобы уменьшить минимальное максимально ребро. Но по определению <tex>\mathrm{MST}</tex>, сумма рёбер дерева минимальна, значит вне остова нету рёбер с меньшим весом. Так как наше предположение неверно, <tex>\mathrm{MST}</tex> является <tex>\mathrm{MBST}</tex>. | ||
| }} | }} | ||
| − | {{ | + | {{Утверждение с MBST | 
| − | | | + | |statement=<tex>\mathrm{MBST}</tex> не всегда является минимальным остовным деревом. | 
| |proof=Рассмотрим пример, где <tex>\mathrm{MBST}</tex> не является минимальным остовным деревом: | |proof=Рассмотрим пример, где <tex>\mathrm{MBST}</tex> не является минимальным остовным деревом: | ||
| <div class="tleft" style="clear:none">[[Файл:MBST-example.png|left|thumb|700px|Пример MBST дерева.]]</div> | <div class="tleft" style="clear:none">[[Файл:MBST-example.png|left|thumb|700px|Пример MBST дерева.]]</div> | ||
| <div class="tleft" style="clear:none">[[Файл:MSTisMBST.png|left|thumb|700px|Пример MST дерева.]]</div> | <div class="tleft" style="clear:none">[[Файл:MSTisMBST.png|left|thumb|700px|Пример MST дерева.]]</div> | ||
| }} | }} | ||
| + | |||
| == Проверка остовного дерева на узкость == | == Проверка остовного дерева на узкость == | ||
| {{Задача | {{Задача | ||
| Строка 27: | Строка 30: | ||
| Найдём максимальное ребро в нашем дереве. Добавим рёбра с весом меньше максимального при помощи [[СНМ (наивные реализации)|СНМ]], чтобы определить его связность. Если в результате у нас все вершины лежат в одном множестве, значит наше дерево не является <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> | ||
Текущая версия на 19:13, 4 сентября 2022
Содержание
| Определение: | 
| Минимально узкое остовное дерево (англ. Minimum bottleneck spanning tree, MBST) в связанном взвешенном неориентированном графе остовное дерево графа, у которого максимальное ребро минимально. | 
| Определение: | 
| Узким ребром (англ. bottleneck edge) в графе назовём максимальное по весу. | 
| Определение: | 
| Остовное дерево является минимально узким (англ. minimum bottleneck), если в графе нет остовного дерева с меньшим узким ребром. | 
Свойства минимального узкого остовного дерева
| Утверждение c MBST: | 
| Каждое минимальное остовное дерево является . | 
| Предположим, если минимальное остовное не является , значит в графе существует набор ребер которые мы не взяли в наш остов, при замене на которые, наше дерево станет . Также рёбра вне остова должны быть меньше рёбер из остова, чтобы уменьшить минимальное максимально ребро. Но по определению , сумма рёбер дерева минимальна, значит вне остова нету рёбер с меньшим весом. Так как наше предположение неверно, является . | 
| Утверждение c 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


