Минимально узкое остовное дерево — различия между версиями

Материал из Викиконспекты
Перейти к: навигация, поиск
м (rollbackEdits.php mass rollback)
 
(не показано 17 промежуточных версий 5 участников)
Строка 1: Строка 1:
{{Утверждение
+
__TOC__
|statement=Минимальное остовное дерево является minimum bottleneck spanning tree.
+
 
|proof=Предположим, если минимальное остовное не является MBST, значит в графе существует набор ребер которые мы не взяли в наш остов, при замене на которые, наше дерево станет MBST. Так же рёбра вне остова должны быть меньше рёбер из остова, чтобы уменьшить минимальное максимально ребро. Но по определению MST, сумма рёбер дерева минимальна, значит вне остова нету рёбер с меньшим весом. Так как наше предположение неверно, MST является MBST.
+
{{Определение
 +
|definition='''Минимально узкое остовное дерево''' (англ. ''Minimum bottleneck spanning tree'', ''MBST'') в связанном взвешенном неориентированном графе <tex>-</tex> [[Остовные деревья: определения, лемма о безопасном ребре|остовное дерево]] графа, у которого максимальное ребро минимально.
 
}}
 
}}
{{Утверждение
+
{{Определение
|statement=Minimum bottleneck spanning tree не всегда является минимальным остовным деревом.
+
|definition='''Узким ребром''' (англ. ''bottleneck edge'') в графе назовём максимальное по весу.
|proof=Рассмотрим пример, где MBST не является минимальным остовным деревом:
+
}}
 +
{{Определение
 +
|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>.
 +
}}
 +
{{Утверждение с MBST
 +
|statement=<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>
 +
}}
  
}}
+
== Проверка остовного дерева на узкость ==
 
{{Задача
 
{{Задача
|definition=Проверка остовного дерева на MBST.
+
|definition=Проверить остовное дерево в графе на <tex>\mathrm{MBST}</tex>.
 
}}
 
}}
<h4>Алгоритм</h4>
+
=== Алгоритм ===
Если у нас получится соединить все вершины графа, используя рёбра меньше максимального из нашего остова, значит мы сможем построить другой остов, в котором максимальное ребро меньше нашего максимального. Для этого найдём максимальное ребро в нашем дереве. Соединим все вершины, между которыми рёбра с весом меньше максимального при помощи [[СНМ (наивные реализации)|СНМ]]. Если в результате у нас все вершины лежат в одном множестве, значит наше дерево не является MBST, иначе оно MBST.
+
Построим новый граф, добавим туда все рёбра меньше максимального из нашего остова. Если в результате у нас получится связный граф, значит мы сможем выделить из него остовное дерево с меньшим узким ребром <tex>-</tex> наше дерево не самое узкое. Иначе, для связности графа нам необходимо добавить максимальные рёбра <tex>-</tex> наше дерево является минимально узким.  
<h4>Асимптотика</h4>
+
Найдём максимальное ребро в нашем дереве. Добавим рёбра с весом меньше максимального при помощи [[СНМ (наивные реализации)|СНМ]], чтобы определить его связность. Если в результате у нас все вершины лежат в одном множестве, значит наше дерево не является <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>.
+
=== Асимптотика ===
<h4>Псевдокод</h4>
+
По каждому ребру пройдём один раз, для поиска максимального, займёт <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{Edge}</tex> храним следующую информацию:
 +
* <tex>\mathtt{from}, \mathtt{to}</tex> {{---}} соединяемые вершины
 +
* <tex>\mathtt{cost}</tex> {{---}} вес ребра
 
<code>
 
<code>
   '''function''' ifMBST():
+
   '''bool''' ifMBST('''Edge'''[] e, '''Edge'''[] tree):
       '''int''' united = 0, maxEdge = -Inf
+
       '''int''' united = 0     <font color=green>// Сколько вершин мы объединили</font>
       '''for''' i = 1 to tree.size
+
      '''int''' maxEdge = -<tex>\infty</tex>
         maxEdge = max(maxEdge, tree[i].cost)
+
       '''for''' i = 1 '''to''' tree.size
       '''for''' i = 1 to n
+
         maxEdge = max(maxEdge, tree[i].cost)     <font color=green>// Поиск максимального ребра в дереве</font>
         '''if''' e[i].cost >= maxEdge
+
       '''for''' i = 1 '''to''' n
 +
         '''if''' e[i].cost >= maxEdge                   <font color=green>// Не соединяем вершины, если ребро не меньше максимального</font>
 
             '''continue'''
 
             '''continue'''
         '''if''' find(e[i].from]) != find(e[i].to)
+
         '''if''' find(e[i].from]) != find(e[i].to)     <font color=green>// Объединяем вершины, если они в разных множествах</font>
 
             united++
 
             united++
       '''if''' united == e.size - 1
+
        unite(e[i].from,e[i].to)
         '''return''' true
+
       '''if''' united == e.size - 1                     <font color=green>// Дерево подходит, если в результате мы соединили все вершины</font>
 +
         '''return''' ''true''
 
       '''else'''  
 
       '''else'''  
         '''return''' false
+
         '''return''' ''false''
 
</code>
 
</code>
 +
 +
==Cм. также==
 +
*[[Алгоритм Краскала]]
 +
*[[Остовные деревья: определения, лемма о безопасном ребре]]
 +
*[[СНМ (наивные реализации)]]
 +
 +
==Источники информации==
 +
*[https://en.wikipedia.org/wiki/Minimum_bottleneck_spanning_tree Википедия — Minimum bottleneck spanning tree]
 +
 +
[[Категория: Алгоритмы и структуры данных]]
 +
[[Категория: Остовные деревья]]
 +
[[Категория: Построение остовных деревьев]]

Текущая версия на 19:13, 4 сентября 2022


Определение:
Минимально узкое остовное дерево (англ. Minimum bottleneck spanning tree, MBST) в связанном взвешенном неориентированном графе [math]-[/math] остовное дерево графа, у которого максимальное ребро минимально.


Определение:
Узким ребром (англ. bottleneck edge) в графе назовём максимальное по весу.


Определение:
Остовное дерево является минимально узким (англ. minimum bottleneck), если в графе нет остовного дерева с меньшим узким ребром.

Свойства минимального узкого остовного дерева

Утверждение c MBST:
Каждое минимальное остовное дерево является [math]\mathrm{MBST}[/math].
[math]\triangleright[/math]
Предположим, если минимальное остовное не является [math]\mathrm{MBST}[/math], значит в графе существует набор ребер которые мы не взяли в наш остов, при замене на которые, наше дерево станет [math]\mathrm{MBST}[/math]. Также рёбра вне остова должны быть меньше рёбер из остова, чтобы уменьшить минимальное максимально ребро. Но по определению [math]\mathrm{MST}[/math], сумма рёбер дерева минимальна, значит вне остова нету рёбер с меньшим весом. Так как наше предположение неверно, [math]\mathrm{MST}[/math] является [math]\mathrm{MBST}[/math].
[math]\triangleleft[/math]
Утверждение c MBST:
[math]\mathrm{MBST}[/math] не всегда является минимальным остовным деревом.
[math]\triangleright[/math]

Рассмотрим пример, где [math]\mathrm{MBST}[/math] не является минимальным остовным деревом:

Пример MBST дерева.
Пример MST дерева.
[math]\triangleleft[/math]

Проверка остовного дерева на узкость

Задача:
Проверить остовное дерево в графе на [math]\mathrm{MBST}[/math].

Алгоритм

Построим новый граф, добавим туда все рёбра меньше максимального из нашего остова. Если в результате у нас получится связный граф, значит мы сможем выделить из него остовное дерево с меньшим узким ребром [math]-[/math] наше дерево не самое узкое. Иначе, для связности графа нам необходимо добавить максимальные рёбра [math]-[/math] наше дерево является минимально узким. Найдём максимальное ребро в нашем дереве. Добавим рёбра с весом меньше максимального при помощи СНМ, чтобы определить его связность. Если в результате у нас все вершины лежат в одном множестве, значит наше дерево не является [math]\mathrm{MBST}[/math], иначе оно [math]\mathrm{MBST}[/math].

Асимптотика

По каждому ребру пройдём один раз, для поиска максимального, займёт [math]O(N)[/math], где [math]N -[/math] число рёбер в графе.
Работа с СНМ займет [math]O(N\alpha(V))[/math], где [math]\alpha[/math] — обратная функция Аккермана, которая не превосходит [math]4[/math] во всех практических приложениях и которую можно принять за константу.
В результате получаем алгоритм работающий за линейное время [math]O(N)[/math].

Псевдокод

Все рёбра графа будем хранить в списке [math]\mathtt{e}[/math], а рёбра остовного дерева в списке [math]\mathtt{tree}[/math].
В каждом ребре [math]\mathtt{Edge}[/math] храним следующую информацию:

  • [math]\mathtt{from}, \mathtt{to}[/math] — соединяемые вершины
  • [math]\mathtt{cost}[/math] — вес ребра

  bool ifMBST(Edge[] e, Edge[] tree):
     int united = 0      // Сколько вершин мы объединили 
     int maxEdge = -[math]\infty[/math]
     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

Cм. также

Источники информации