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