Когда я должен использовать Kruskal, а не Prim (и наоборот)?


194

Мне было интересно, когда следует использовать алгоритм Прима, а когда Крускала, чтобы найти минимальное остовное дерево? Они оба имеют простую логику, одинаковые наихудшие случаи, и единственное различие заключается в реализации, которая может включать в себя несколько разные структуры данных. Так что является решающим фактором?

Ответы:


201

Используйте алгоритм Прима, когда у вас есть граф с множеством ребер.

Для графа с V вершинами E ребер алгоритм Крускала выполняется за время O (E log V), а алгоритм Прима может работать за время амортизации O (E + V log V) , если вы используете кучу Фибоначчи .

Алгоритм Прима значительно быстрее в пределе, когда у вас действительно плотный граф с гораздо большим числом ребер, чем вершин. Kruskal работает лучше в типичных ситуациях (разреженные графики), потому что он использует более простые структуры данных.


8
Я бы сказал «типичные ситуации» вместо среднего. Я думаю, что это неясный термин, например, что такое «средний размер» хеш-таблицы? без понятия.
Яирчу

2
@SplittingField: я верю, что вы сравниваете яблоки и апельсины. Амортизированный анализ - это простой способ измерить функцию (если можно так выразиться) - является ли это наихудшим или средним случаем, зависит от того, что вы доказываете. На самом деле (как я сейчас вижу), в вики-статье используется язык, который подразумевает, что он используется только для анализа наихудшего случая. Теперь использование такого анализа означает, что вы не можете давать столь сильные обещания о стоимости конкретной операции, но к тому времени, когда алгоритм будет выполнен, он действительно будет O (E + VlogV), даже в худшем случае.
Agorenst

10
Это звучит хорошо в теории, но я уверен, что мало кто может реализовать кучу Фибоначчи
Александру

2
@tgamblin, в худшем случае может быть C (V, 2) ребер. Итак, разве временная полнота алгоритма Прима не сводится к O (V ^ 2 + VlogV), т.е. к O (V ^ 2) в случае кучи Фибоначчи?
Зеленый гоблин

7
Есть и еще один важный фактор: выход Prims является MST, только если граф подключен (вывод кажется мне бесполезным в противном случае), но вывод Kruskal - это леса с минимальным охватом (с некоторым использованием).
Андрей я

102

Я нашел в сети очень интересную ветку, которая объясняет разницу очень просто: http://www.thestudentroom.co.uk/showthread.php?t=232168 .

Алгоритм Крускала вырастит решение из самого дешевого ребра, добавив следующее самое дешевое ребро, при условии, что оно не создает цикл.

Алгоритм Прима вырастит решение из случайной вершины путем добавления следующей самой дешевой вершины, вершины, которая в данный момент не находится в решении, но связана с ней самым дешевым ребром.

Здесь прилагается интересный лист на эту тему.введите описание изображения здесьвведите описание изображения здесь

Если вы реализуете и Kruskal, и Prim в их оптимальной форме: с объединением find и кучей finbonacci соответственно, то вы заметите, как Kruskal проще в реализации по сравнению с Prim.

Прим сложнее с кучей Фибоначчи, главным образом потому, что вам нужно вести таблицу бухгалтерского учета для записи двунаправленной связи между узлами графа и узлами кучи. С Union Find, наоборот, структура проста и может даже производить MST напрямую, почти без дополнительных затрат.


2
Nitpick: последний «слайд» в каждом должен гласить «повторять, пока у вас не будет связующего дерева»; не раньше MST, что является чем-то вроде рекурсивной задачи - откуда я знаю, что она минимальна - вот почему я следую за Примом / Крускалом для начала!
OJFord

@OllieFord Я нашел эту ветку за поиск простой иллюстрации алгоритмов Прима и Крускала. Алгоритмы гарантируют, что вы найдете дерево, а это дерево MST. И вы знаете, что нашли дерево, когда у вас есть ровные V-1 края.
mikedu95

@ mikedu95 Вы правы, делая то же самое, что и мой предыдущий комментарий под другим углом.
OJFord

Но не является ли это предварительным условием, что вы должны выбирать только с одним весом между вершинами, вы не можете выбрать вес 2 более одного раза из приведенного выше графика, вы должны выбрать следующий вес, например: 3 @Snicolas
ani0904071

30

Я знаю, что вы не просили об этом, но если у вас есть больше единиц обработки, вы всегда должны учитывать алгоритм Боровки , потому что он может быть легко распараллелен - следовательно, он имеет преимущество в производительности по сравнению с алгоритмом Крускала и Ярника-Прима.


23

Kruskal может иметь лучшую производительность, если края могут быть отсортированы по линейному времени или уже отсортированы.

Прим лучше, если число ребер к вершинам велико.


19

Наихудший случай сложности времени Крускала - O (E log E) , потому что нам нужно отсортировать ребра. Наихудший случай сложности начального времени - O (E log V) с приоритетной очередью или даже лучше, O (E + V log V) с кучей Фибоначчи . Мы должны использовать Крускала, когда граф разрежен, например, небольшое количество ребер, например E = O (V), когда ребра уже отсортированы или если мы можем отсортировать их за линейное время. Мы должны использовать Prim, когда граф плотный, т.е. число ребер велико, как E = O (V²).


Мне кажется, что Prim никогда не хуже Kruskal по скорости. Поскольку E должно быть не менее V-1, существует связующее дерево. Я думаю, что причина, по которой мы предпочитаем Kruskal для разреженного графа, состоит в том, что его структура данных очень проста.
Ю Гу

16

Если мы остановим алгоритм в среднем приме, алгоритм всегда генерирует связанное дерево, но kruskal, с другой стороны, может дать отключенное дерево или лес.


5

Одним из важных приложений алгоритма Крускала является кластеризация в одном канале .

Рассмотрим n вершин, и вы получите полный граф. Чтобы получить ak кластеров из этих n точек. Алгоритм запуска Крускала по первым n- (k-1) ребрам отсортированного набора ребер. Вы получаете k-кластер графа с максимумом Расстояние между.


3

Лучшее время для Крускала - это O (E logV). Для Прима, использующего кучи FIB, мы можем получить O (E + V lgV). Поэтому на плотном графе Прима намного лучше.


2

Прим лучше для более плотных графов, и в этом мы также не должны уделять много внимания циклам, добавляя ребро, так как мы в основном имеем дело с узлами. Прим быстрее, чем Крускал в случае сложных графов.


2

В алгоритме Крускала у нас есть число ребер и количество вершин на данном графе, но на каждом ребре у нас есть какое-то значение или вес, от имени которого мы можем подготовить новый граф, который не должен быть циклическим или не быть близким с любой стороны. Например

график, как это _____________ | | | | | | | __________ | | Дайте имя любой вершине a, b, c, d, e, f.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.