【发布时间】:2016-02-05 12:22:10
【问题描述】:
我想知道当权重数量很少(即边只能有 2 个不同的权重)时,是否有人可以指出线性时间算法来找到图的 MST。
我在谷歌上找不到除了 Prim、Kruskal、Boruvka 之外的任何东西,在这种特殊情况下,它们似乎都没有任何会减少运行时间的属性。我猜想使它成为线性时间,它必须是 BFS 的某种修改(当权重均匀时找到 MST)。
【问题讨论】:
我想知道当权重数量很少(即边只能有 2 个不同的权重)时,是否有人可以指出线性时间算法来找到图的 MST。
我在谷歌上找不到除了 Prim、Kruskal、Boruvka 之外的任何东西,在这种特殊情况下,它们似乎都没有任何会减少运行时间的属性。我猜想使它成为线性时间,它必须是 BFS 的某种修改(当权重均匀时找到 MST)。
【问题讨论】:
Prim 的O(V lg V) 运行时中lg V 因素的原因是用于查找下一个候选边的堆。我很确定可以设计一个优先级队列,当可能的权重数量有限时,它可以在恒定时间内进行插入和删除,这会将 Prim 减少到O(V)。
对于优先级队列,我相信它的索引涵盖所有可能的权重的数组就足够了,其中每个元素都指向一个包含具有该权重的元素的链表。您仍然需要 d (不同权重的数量)的因子来确定从哪个列表中取出下一个元素(“最低”非空元素),但如果 d 是一个常数,那你就没事了。
【讨论】:
详细阐述 Aasmund Eldhuset 的回答:如果 MST 中的权重被限制为 0、1、2、3、...、U-1 范围内的数字,那么您可以调整许多现有算法以在其中运行如果 U 是常数,则(接近)线性时间。
例如,让我们以 Kruskal 算法为例。 Kruskal 算法的第一步是将边按权重升序排序。如果使用计数排序,则可以在时间 O(m + U) 中执行此操作,如果使用基数排序,则可以在时间 O(m lg U) 中执行此操作。如果 U 是一个常数,那么这两个排序步骤都需要线性时间。因此,在这种情况下运行 Kruskal 算法的运行时间为 O(m α(m)),其中 α(m) 是阿克曼函数的逆,因为限制因素将是维护不相交集森林的运行时间.
或者,看看 Prim 的算法。您需要维护到节点的候选距离的优先级队列。如果您知道所有边都在 [0, U) 范围内,那么您可以通过存储一组 U 桶数组以一种超级简单的方式执行此操作,每个可能的优先级一个桶。然后插入优先级队列只需要您将一个项目转储到正确的存储桶中。您可以通过逐出元素并将其移动到较低的存储桶来执行减少键。然后,您可以通过扫描存储桶进行查找分钟。这导致算法运行时间为 O(m + nU),如果 U 为常数,则为线性。
【讨论】: