2

在您已经知道任何给定权重的最小值的情况下,如何修改 prim 的算法?例如,如果一个图由边权重 0 和 1 组成,如何让 prim 的算法更快?

4

1 回答 1

6

第一个策略似乎是改进优先级队列以利用您的数据。如果您知道权重是小于某个 C 的离散值,则可以将通常使用的二进制堆替换为基数堆。通过这种方式,您可以轻松获得与更难实现的斐波那契堆相同的算法复杂性,甚至可能更好。Dijkstra 的算法使用完全相同的数据结构,这里详细解释了如何为其实现基数堆:

http://www.cosc.canterbury.ac.nz/tad.takaoka/alg/spalgs/radixheap.txt

示例代码 radixheap.cpp 可以在这里找到:

http://www.cosc.canterbury.ac.nz/tad.takaoka/alg/spalgs/spalgs.html

您可以简单地将与 Dijkstra 算法的文本解释的相同数据结构应用于 Prim 算法,以获得复杂度 O(m + n log C),其中 m 是边,n 是顶点,C 是最大边权重。如果您的边权重只是小整数,这确实非常好。

总结一下基堆的概念,项目根据它们的优先级(必须是整数)放置在桶中。存储桶 N 覆盖的值范围大致为 2^N,因此找到正确的存储桶与最大可能数的对数成正比。当提取具有最小优先级的项目时,项目有时会重新分配到较低的桶中,摊销也适用于对数复杂度。

如果您的意思是边缘权重是 0 到 1 之间的任意浮点数,则不允许进行任何优化。显然,任何图都可以通过将所有边权重除以最大边权重来转换,使它们都在 0 和 1 之间。这种转换不可能使 Prim 算法运行得更快。您可以通过向所有边添加相同的数字或将它们与相同的正数相乘来变换所有边,而根本不会改变结果。

于 2012-04-29T19:47:14.137 回答