克鲁斯卡尔vs Prim
我想知道什么时候应该使用Primalgorithm ,什么时候Kruskalfind最小生成树? 他们都有简单的逻辑,同样的最坏的情况,只有不同的是可能涉及有点不同的数据结构的实现。 那么决定因素是什么?
当你有一个有很多边的图时,使用Prim的algorithm。
对于具有V顶点E边的图,如果使用斐波那契堆 ,则Kruskalalgorithm运行在O(E log V)时间,Primalgorithm可以在O(E + V log V)分摊时间内运行。
当你有一个真正密集的graphics,比边缘更多的边缘时,Prim的algorithm在极限上明显更快。 Kruskal在典型情况下(稀疏图)performance更好,因为它使用更简单的数据结构。
我在网上发现了一个非常漂亮的线索,以一种非常直接的方式解释了这种差异: http : //www.thestudentroom.co.uk/showthread.php?t=232168 。
Kruskal的algorithm将通过添加下一个最便宜的边来增加最便宜的边的解决scheme,只要它不创build循环。
Prim的algorithm将通过添加下一个最便宜的顶点来生成一个随机顶点的解决scheme,该顶点当前不在解决scheme中,但是通过最便宜的边缘连接到顶点。
这里附上的是关于这个话题的有趣的表格。
如果你同时使用Kruskal和Prim,他们的最佳forms是:分别使用union和finbonacci堆,那么你会注意到Kruskal与Prim相比如何易于实现。
Prim对于斐波那契堆来说更加困难,主要是因为您必须维护一个logging表来logginggraphics节点和堆节点之间的双向链接。 通过联盟查找,情况正好相反,结构简单,甚至可以直接生成最高成本,几乎不需要额外的成本。
我知道你没有要求这个,但是如果你有更多的处理单元,你应该总是考虑Borůvka的algorithm ,因为它可能很容易并行 – 因此它比Kruskal和Jarník-Primalgorithm具有性能优势。
如果边缘可以线性sorting,或者已经sorting,则Kruskal可以有更好的性能。
如果顶点的边数很高,则Prim更好。
如果我们停止在中间algorithm的algorithm总是产生连接树,但克鲁斯卡尔另一方面可以给断开树或森林
克鲁斯卡尔时间复杂度最坏的情况是O(E log E) ,这是因为我们需要对边进行sorting。 Prim时间复杂度最差的情况是O(E log V) 优先队列 ,甚至更好, O(E + V log V)与Fibonacci Heap 。 当图像稀疏时,我们应该使用Kruskal,当边已经sorting或者我们可以用线性时间对它们进行sorting时,我们可以使用像E = O(V)那样less的边数。 当graphics密集时,我们应该使用Prim,即边数很高,如E = O(V²)。
Kruskalalgorithm的一个重要应用是单链路聚类 。
考虑n个顶点并且你有一个完整的图。为了得到这些n个点的k个聚类。在sorting后的边集的前n(k-1)个边上运行Kruskalalgorithm。你得到图的k-聚类间距。
Kruskal的最佳时间是O(E logV)。 对于Prim使用fib堆,我们可以得到O(E + V lgV)。 因此,在一个密集的图表上,Prim的好多了。
Prim's更适合更密集的graphics,在这一点上,我们也不必通过添加边来关注周期,因为我们主要处理节点。 在复杂graphics的情况下,Prim's比Kruskal快。
在kruskalalgorithm中,我们有一个给定图上的边数和顶点数,但是在每个边上我们有一些值或权重,我们可以准备一个新的图,它必须是不循环的,或者不能从任何一边closures。
图表像这样_____________ | | | | | | | __________ | | 给任何顶点a,b,c,d,e,f命名。