Алгоритм Краскала — различия между версиями
(→Идея) |
(→Задача о максимальном ребре минимального веса) |
||
Строка 16: | Строка 16: | ||
==Задача о максимальном ребре минимального веса== | ==Задача о максимальном ребре минимального веса== | ||
− | Очевидно, что максимальное ребро в MST минимально. Пусть это не так, тогда рассмотрим разрез, который оно пересекает. В этом разрезе должно быть ребро с меньшим весом, иначе максимальное ребро было бы минимальным, но в таком случае минимальный остов не является минимальным, следовательно, максимальное ребро в минимальном остовном дереве минимально. Если же максимальное ребро в остовном дереве минимально, то такое дерево может не быть минимальным. Зато его можно найти быстрее чем MST, а конкретно за <tex>O(E)</tex>. С помощью [[Поиск_k-ой_порядковой_статистики_за_линейное_время | алгоритма поиска k-ой порядковой статистики]] найдем ребро-медиану за <tex>O(E)</tex> и разделим множество ребер на два равных по мощности так, чтобы в первом подмножестве все ребра не превосходили ребро-медиану, а во втором были не меньше его. Запустим [[Использование_обхода_в_глубину_для_проверки_связности|обход в глубину]], чтобы проверить образуют ли ребра из первого подмножества остов, содержащий все вершины графа. Если да, то, так как все ребра в первом подмножестве меньше чем во втором, рекурсивно запустим алгоритм от него. В противном случае сконденсируем в супервершины получившиеся несвязные компоненты и рассмотрим граф с этими супервершинами и ребрами из второго подмножества. | + | Очевидно, что максимальное ребро в MST минимально. Пусть это не так, тогда рассмотрим разрез, который оно пересекает. В этом разрезе должно быть ребро с меньшим весом, иначе максимальное ребро было бы минимальным, но в таком случае минимальный остов не является минимальным, следовательно, максимальное ребро в минимальном остовном дереве минимально. Если же максимальное ребро в остовном дереве минимально, то такое дерево может не быть минимальным. Зато его можно найти быстрее чем MST, а конкретно за <tex>O(E)</tex>. С помощью [[Поиск_k-ой_порядковой_статистики_за_линейное_время | алгоритма поиска k-ой порядковой статистики]] найдем ребро-медиану за <tex>O(E)</tex> и разделим множество ребер на два равных по мощности так, чтобы в первом подмножестве все ребра не превосходили ребро-медиану, а во втором были не меньше его. Запустим [[Использование_обхода_в_глубину_для_проверки_связности|обход в глубину]], чтобы проверить образуют ли ребра из первого подмножества остов, содержащий все вершины графа. Если да, то, так как все ребра в первом подмножестве меньше чем во втором, рекурсивно запустим алгоритм от него. В противном случае сконденсируем в супервершины получившиеся несвязные компоненты и рассмотрим граф с этими супервершинами и ребрами из второго подмножества. На последнем шаге останется одно ребро, оно и будет максимальным ребром минимального веса. На каждом шаге ребер становится в два раза меньше, а все операции выполняются за время пропорциональное количеству ребер на текущем шаге, следовательно, время работы алгоритма <tex>O(E+\frac{E}{2}+\frac{E}{4}+...+1)=O(E)</tex>. Чтобы восстановить остовное дерево, достаточно запустить алгоритм поиска в глубину и добавлять в остов только те ребра, которые не превосходят найденное алгоритмом ребро. |
==Пример== | ==Пример== |
Версия 13:33, 15 декабря 2014
Алгоритм Краскала (англ. Kruskal's algorithm) — алгоритм поиска минимального остовного дерева (англ. minimum spanning tree, MST) во взвешенном неориентированном связном графе.
Содержание
Идея
Будем последовательно строить подграф разрез такой, что одна из компонент связности составляет одну его часть, а оставшаяся часть графа — вторую. Тогда — минимальное ребро, пересекающее этот разрез. Значит, из леммы о безопасном ребре следует, что является безопасным, поэтому добавим это ребро в . На последнем шаге ребро соединит две оставшиеся компоненты связности, полученный подграф будет минимальным остовным деревом графа .
графа ("растущий лес"), пытаясь на каждом шаге достроить до некоторого MST. Начнем с того, что включим в все вершины графа . Теперь будем обходить множество в порядке неубывания веса ребер. Если очередное ребро соединяет вершины одной компоненты связности , то добавление его в остов приведет к возникновению цикла в этой компоненте связности. В таком случае, очевидно, не может быть включено в . Иначе соединяет разные компоненты связности , тогда существуетРеализация
//— исходный граф // — минимальный остов // для проверки возможности добавления ребра используется система непересекающихся множеств function for if и в разных компонентах связности
Задача о максимальном ребре минимального веса
Очевидно, что максимальное ребро в MST минимально. Пусть это не так, тогда рассмотрим разрез, который оно пересекает. В этом разрезе должно быть ребро с меньшим весом, иначе максимальное ребро было бы минимальным, но в таком случае минимальный остов не является минимальным, следовательно, максимальное ребро в минимальном остовном дереве минимально. Если же максимальное ребро в остовном дереве минимально, то такое дерево может не быть минимальным. Зато его можно найти быстрее чем MST, а конкретно за алгоритма поиска k-ой порядковой статистики найдем ребро-медиану за и разделим множество ребер на два равных по мощности так, чтобы в первом подмножестве все ребра не превосходили ребро-медиану, а во втором были не меньше его. Запустим обход в глубину, чтобы проверить образуют ли ребра из первого подмножества остов, содержащий все вершины графа. Если да, то, так как все ребра в первом подмножестве меньше чем во втором, рекурсивно запустим алгоритм от него. В противном случае сконденсируем в супервершины получившиеся несвязные компоненты и рассмотрим граф с этими супервершинами и ребрами из второго подмножества. На последнем шаге останется одно ребро, оно и будет максимальным ребром минимального веса. На каждом шаге ребер становится в два раза меньше, а все операции выполняются за время пропорциональное количеству ребер на текущем шаге, следовательно, время работы алгоритма . Чтобы восстановить остовное дерево, достаточно запустить алгоритм поиска в глубину и добавлять в остов только те ребра, которые не превосходят найденное алгоритмом ребро.
. С помощьюПример
Задан неориентированный связный граф, требуется построить в нём минимальное остовное дерево.
Создадим новый граф, содержащий все вершины из заданного графа, но не содержащий рёбер.
Этот новый граф будет ответом, в него будут добавлены рёбра из заданного графа по ходу выполнения алгоритма.
Отсортируем рёбра заданного графа по их весам и рассмотрим их в порядке возрастания.
Рёбра (в порядке их просмотра) | ae | cd | ab | be | bc | ec | ed |
Веса рёбер |
Асимптотика
Сортировка
Работа с системой непересекающихся множеств займет , где — обратная функция Аккермана, которая не превосходит 4 во всех практических приложениях и которую можно принять за константу.
Алгоритм работает за .
См. также
Источники информации
- Томас Х. Кормен, Чарльз И. Лейзерсон, Рональд Л. Ривест, Клиффорд Штайн — Алгоритмы: построение и анализ, 2-е издание. Пер. с англ. — М.:Издательский дом "Вильямс", 2010. — 1296 с.: ил. — Парал. тит. англ. — ISBN 978-5-8459-0857-5 (рус.)
- Википедия — Функция Аккермана
- Википедия — Алгоритм Крускала
- Wikipedia — Kruskal's algorithm
- MAXimal :: algo :: Минимальное остовное дерево. Алгоритм Крускала