我何时应该使用Kruskal而非Prim(反之亦然)?


Answers:


199

当您的图形具有很多边时,请使用Prim算法。

对于具有V个顶点E边的图形,如果使用Fibonacci堆,则Kruskal算法的运行时间为O(E log V),而Prim算法的运行时间为O(E + V log V)摊销时间。

当您拥有一个非常密集的图形且其边缘比顶点多得多时,Prim的算法在极限上的速度明显更快。Kruskal在典型情况下(稀疏图)表现更好,因为它使用了更简单的数据结构。


8
我会说“典型情况”而不是平均值。我认为这是一个晦涩的术语,例如,哈希表的“平均大小”是多少?不知道。
yairchu

2
@SplittingField:我确实相信您正在比较苹果和橙子。摊销分析是一种衡量功能(可以这么说)的简便方法-是最坏情况还是平均情况取决于您的证明。实际上(正如我现在查找的那样),该Wiki文章使用的语言暗示着它用于最坏情况分析。现在,使用这种分析意味着您不能对某个特定操作的成本做出有力的保证,但是到算法完成时,它的确会以O(E + VlogV)的形式出现,甚至是最坏的情况。
agorenst

10
从理论上讲,这听起来不错,但是我敢打赌,几乎没有人可以实现斐波那契堆
Alexandru

2
@tgamblin,在最坏的情况下可能会有C(V,2)边。因此,在斐波那契堆的情况下,Prim算法的时间复杂度是否可以归结为O(V ^ 2 + VlogV)即O(V ^ 2)?
绿色妖精2012年

7
还有一个重要因素:仅在连接了图的情况下,Prims的输出才是MST(在我看来,该输出无用),但是Kruskal的输出是“最小生成林”(有一定用途)。
Andrei I

100

我在网上找到了一个很好的线程,该线程以非常简单的方式解释了差异:http : //www.thestudentroom.co.uk/showthread.php?t=232168

如果不创建循环,Kruskal的算法将通过添加下一个最便宜的边,从最便宜的边开始发展解决方案。

Prim的算法将通过添加下一个最便宜的顶点(该顶点当前不在解决方案中,但通过最便宜的边缘与其连接)来从随机顶点中生成解决方案。

附件是关于该主题的有趣的表格。在此处输入图片说明在此处输入图片说明

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

对于Fibonacci堆,Prim较难,主要是因为您必须维护一个簿记表才能记录图节点与堆节点之间的双向链接。与Union Find相反,结构简单,甚至可以直接生产mst,几乎不需要任何额外费用。


2
Nitpick:每个幻灯片中的最后一个“幻灯片”应显示为“重复,直到您有生成树为止”;直到MST,这都是递归的任务-我怎么知道这是最小的-这就是为什么我要遵循Prim / Kruskal的原因!
OJFord

@OllieFord我找到了这个线程,因为它搜索了Prim和Kruskal算法的简单图示。该算法保证您会找到一棵树,并且该树是MST。而且您知道在完全 具有V-1边的时候已经找到了一棵树。
mikedu95 '16

@ mikedu95您是正确的,从不同的角度提出了与我之前的评论相同的观点。
OJFord

但这不是前提,您只需要在顶点之间选择单个权重,就不能从上图中多次选择权重2,而必须选择下一个权重,例如:3 @Snicolas
ani0904071

30

我知道您并没有要求这样做,但是如果您有更多的处理单元,则应该始终考虑Borůvka算法,因为它很容易并行化-因此,它比Kruskal和Jarník-Prim算法具有性能优势。


23

如果可以按线性时间对边缘进行排序或已经对边缘进行排序,则Kruskal可以具有更好的性能。

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


19

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


在我看来,Prim在速度方面从来没有比Kruskal差。由于E至少应为V-1,因此存在生成树。我认为我们可能更喜欢Kruskal作为稀疏图的原因是它的数据结构非常简单。
Yu Gu

16

如果我们停止算法,那么中素数的算法总是会生成连接树,但另一方面,kruskal可以给出断开连接的树或林


5

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

考虑n个顶点,您有一个完整的图。要获得这n个点的ak聚类,请在已排序的一组边的前n-(k-1)个边上运行Kruskal算法。间距。


3

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


2

Prim's更适合于密度更大的图,在这种情况下,我们也不必过多地通过添加边来关注循环,因为我们主要处理节点。在复杂图的情况下,Prim的速度比Kruskal的快。


2

在kruskal算法中,给定图上有边数和顶点数,但是在每条边上都有一定的值或权重,可以代表它们准备一个新的图,该图必须不是循环的,或者从任一侧都不闭合

像这样的图形_____________ | | | | | | | __________ | | 给任何顶点a,b,c,d,e,f命名。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.