针对已知边缘权重优化的Prim算法?

时间:2012-04-29 18:46:07

标签: algorithm prims-algorithm

如果您已经知道任何给定重量的最小值,您如何修改prim算法?例如,如果图形由边缘权重0和1组成,那么如何使prim的算法更快?

1 个答案:

答案 0 :(得分: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

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

总结基数堆的概念,项目根据其优先级(必须是整数)放在存储桶中。铲斗N所覆盖的值的范围大致为2 ^ N,因此找到正确的铲斗与最大可能的数量的对数成比例。在提取具有最小优先级的项目时,项目有时会重新分配到较低的存储区,这些存储区的分摊也会导致对数的复杂性。

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