什么时候我应该使用Kruskal而不是Prim(反之亦然)?

时间:2009-07-28 18:28:58

标签: algorithm graph-theory minimum-spanning-tree prims-algorithm kruskals-algorithm

我想知道何时应该使用Prim's algorithm和何时Kruskal's来查找最小生成树?它们都具有简单的逻辑,同样最坏的情况,唯一的区别是实现可能涉及一些不同的数据结构。那么决定因素是什么?

10 个答案:

答案 0 :(得分:188)

如果图表边缘很多,请使用Prim算法。

对于 V 顶点 E 边缘的图形,Kruskal的算法在 O(E log V)时间内运行,而Prim的算法可以在 O(E + V log V)如果您使用Fibonacci Heap,则摊销时间。

当你有一个比顶点更多的边缘的真正密集的图形时,Prim的算法明显更快。 Kruskal在典型情况下(稀疏图)表现更好,因为它使用更简单的数据结构。

答案 1 :(得分:92)

我在网上发现了一个非常好的主题,它以一种非常直接的方式解释了差异:http://www.thestudentroom.co.uk/showthread.php?t=232168

Kruskal的算法将通过添加下一个最便宜的边缘从最便宜的边缘增长解决方案,前提是它不会创建一个循环。

Prim的算法将通过添加下一个最便宜的顶点来增加随机顶点的解决方案,顶点当前不在解决方案中,但是通过最便宜的边缘连接到顶点。

此附件是关于该主题的有趣表格。enter image description here enter image description here

如果以最佳形式同时实现Kruskal和Prim:分别使用union find和finbonacci堆,那么您将注意到与Prim相比,Kruskal如何易于实现。

Prim对于斐波那契堆很难,主要是因为你必须维护一个记账表来记录图节点和堆节点之间的双向链接。使用Union Find,相反,结构简单,甚至可以直接生成mst,几乎不需要额外费用。

答案 2 :(得分:27)

我知道你没有要求这个,但如果你有更多的处理单元,你应该总是考虑Borůvka's algorithm,因为它可能很容易并行化 - 因此它比Kruskal和Jarník-Prim具有性能优势算法

答案 3 :(得分:21)

如果边缘可以按线性时间排序,或者已经排序,Kruskal可以获得更好的性能。

如果顶点的边数很高,则Prim会更好。

答案 4 :(得分:15)

如果我们在mid prim算法中停止算法总是生成连接树,但另一方面kruskal可以给出断开连接的树或森林

答案 5 :(得分:11)

Kruskal 时间复杂度最坏的情况是 O(E log E),这是因为我们需要对边缘进行排序。     Prim 时间复杂度最坏的情况是 O(E log V) 优先级队列甚至更好, O(E + V log V) Fibonacci堆。     我们应该在图形稀疏时使用Kruskal,即当边缘已经排序或者我们可以在线性时间内对它们进行排序时,边缘的数量很小,例如E = O(V)。     当图形密集时,我们应该使用Prim,即边缘数量很高,如E = O(V²)。

答案 6 :(得分:5)

Kruskal算法的一个重要应用是单链路聚类

考虑n个顶点,你有一个完整的图。要获得那些n个点的k个簇。运行Kruskal的算法在有序边集的第一个n-(k-1)个边缘。你得到了k-簇的最大间距的图表。

答案 7 :(得分:3)

Kruskal的最佳时间是O(E logV)。对于Prim使用fib堆,我们可以得到O(E + V lgV)。因此,在密集的图表上,Prim的更好。

答案 8 :(得分:2)

对于更密集的图形,Prim更好,在这方面我们也不必通过添加边缘来关注周期,因为我们主要处理节点。在复杂图形的情况下,Prim比Kruskal更快。

答案 9 :(得分:2)

在kruskal算法中,我们在给定图形上有多个边和顶点数,但在每个边上我们都有一些值或权重代表我们可以准备一个新的图形,它必须不是循环的或者不是从任何一边接近 例如

像这样的图表                   _____________ | | | | | | | __________ | | 为任何顶点a,b,c,d,e,f。

命名