Kruskal与堆或排序算法

时间:2015-08-14 23:29:54

标签: java algorithm time graph-theory kruskals-algorithm

我正在尝试尽可能高效地实施Kruskal。

为了提高运行效率,使用堆或排序算法对边缘进行排序是否有区别?

还有哪些其他技术可以让Kruskal算法更有效地工作?

1 个答案:

答案 0 :(得分:3)

这取决于您要解决的确切问题。如果您要实现通用解决方案,只需选择“最快”的排序算法。我怀疑那是不是heapsort。我会默认使用Java正在使用的任何排序算法(如果你正在排序对象,可能是timsort)。此外,在某些情况下,排序可以比O(ElogE)更快地完成。假设你的边缘只能有一个小间隔的整数权重,那么你可以选择与countort非常相似的东西。因此,如果您处于其中一种情况,那么堆可能不是一个好选择。 另外,我看不出有人会单独在Kruskal算法的上下文中使用堆。

要回答你的第二个问题(但你可能已经知道了),Disjoint-set data structure对集合操作的使用给出了很好的加速。它具有各种优点:易于实现,良好的渐近行为和低常数。

修改

我已经重新考虑了堆/ heapsort选项,主要是由于我的帖子上的评论。如果只排序直到树完成,使用堆可能会带来巨大的优势。 180度打开我的意见。这就是原因。

考虑Erdős–Rényi model。现在,这是一个非常简单的模型,其中一个以G个顶点上的空图n开头(即没有边),并将每个可能的边加上概率p到{{1} },独立于任何其他边缘。这并不是Kruskal的算法在编写树时所做的事情,但如果G具有二次数的边(就顶点数而言),它就像'相当好',边缘分布不是'偏向的'并且权重分配不是“有偏见的”。

现在这里有趣的部分。在Erdős-Rényi模型下,当G大约为p时(即,在向图表添加ln(n)/n边后'粗略'说话),图表就会连接起来。结果众所周知(检查here)。

尽管Kruskal算法的设置有所不同,但如果O(nln(n))具有二次边数(就顶点数而言),则边缘分布不是“偏向”且权重分配是没有“偏见”,在G个边缘内可以到达树是合理的。如果确实如此,那么在开始编写树之前,它会使用堆并仅对树进行排序,直到比使用比较排序方法对整个边集进行排序更好。

因此,使用堆可能会使运行时速度提高,而且可能相当可观。