当边长受限时最小生成树的快速算法?
假设您有一个有向图,其非负整数边长在 0 到 U - 1 范围内(包括 0 和 U - 1)。计算该图的最小生成树最快的算法是什么?我们仍然可以使用现有的最小生成树算法,例如Kruskal算法O(m log n))或Prim算法(O(m + n log n))。然而,对于 U 很小的情况,我认为应该可以做得更好。
是否有任何算法能够与更传统的 MST 算法竞争,能够利用边长度被限制在某个范围内的事实?
谢谢!
Suppose that you have a directed graph with nonnegative, integer edge lengths that are in the range 0 to U - 1, inclusive. What is the fastest algorithm for computing a minimum spanning tree of this graph? We can still use existing minimum spanning tree algorithms, such as Kruskal's algorithm O(m log n)) or Prim's algorithm (O(m + n log n)). However, for cases where U is small, I think it should be possible to do much better this.
Are there any algorithms that are competitive with more traditional MST algorithms that are able to exploit the fact that the edge lengths are constrained to be in some range?
Thanks!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
Fredman–Willard 针对单位成本 RAM 上的整数边长给出了 O(m + n) 算法。
这可以说并不算太大的改进:在没有边长度限制的情况下(即,长度是一种不透明的数据类型,仅支持比较),Chazelle 给出了 O(m alpha(m, n) + n) 算法(alpha 是反阿克曼函数)和 Karger-Klein-Tarjan 给出了随机 O(m + n) 算法。
我不认为 Darren 的想法会导致 O(m + n + U) 时间算法。 Jarnik(“Prim”)不单调地使用其优先级队列,因此桶可能会被多次扫描; Kruskal 需要一个不相交集的数据结构,它不能是 O(m + n)。
Fredman–Willard gave an O(m + n) algorithm for integer edge lengths on the unit-cost RAM.
That's arguably not much of an improvement: without the restriction on edge lengths (i.e., the lengths are an opaque data type that supports only comparisons), Chazelle gave an O(m alpha(m, n) + n) algorithm (alpha is the inverse Ackermann function) and Karger–Klein–Tarjan gave a randomized O(m + n) algorithm.
I don't think Darren's idea leads to a O(m + n + U)-time algorithm. Jarnik ("Prim") does not use its priority queue monotonically, so buckets may be scanned multiple times; Kruskal requires a disjoint-set data structure, which cannot be O(m + n).
通过整数边权重,您可以使用分桶来实现最坏情况
O(1)
复杂度的优先级队列,但会增加O(U)
空间复杂度。在您提到的 MST 算法中,您应该能够用此整数结构替换基于比较的优先级队列,从而消除复杂性要求中的
O(log(n))
依赖性。我预计您最终会得到O(n + m)
风格的整体复杂性。本质上,您设置了一组压缩链接列表,其中每个列表都按与该存储桶关联的(整数!)成本进行索引:
此结构基于每个项目只能同时位于单个存储桶列表中的事实。
基于此结构,您可以实现这些操作的最坏情况
O(1)
复杂度:要使用此结构作为优先级队列,您只需维护一个指向当前要扫描的最小存储桶的索引。当您想要获得下一个成本最低的项目时,您只需从该存储桶中弹出头项目即可。如果存储桶为空,则增加存储桶索引,直到找到非空存储桶。
当然,如果
U
变得非常大,额外的空间复杂度以及项目在存储桶上稀疏分布的可能性可能会使这种方法失去吸引力。With integer edge weights you can use bucketing to achieve a priority queue with worst-case
O(1)
complexity, but additionalO(U)
space complexity.Within the MST algorithms you've mentioned you should be able to replace the comparison based priority queues with this integer structure, and hence remove the
O(log(n))
depenedence in the complexity requirements. I expect you'd end up with an overall complexity in the style ofO(n + m)
.Essentially you setup a set of compressed linked-lists, where each list is indexed by the (integer!) cost associated with that bucket:
This structure is based on the fact that each item can only be in a single bucket list at once.
Based on this structure you can achieve worst-case
O(1)
complexity for these operations:To use this structure as a priority queue you simply maintain an index pointing at the current minimum bucket to scan. When you want to get the next lowest cost item, you simply pop the head item from this bucket. If the bucket is empty you increment your bucket index until you find a non-empty one.
Of course if
U
becomes very large the extra space complexity, and the possiblity of a sparse distribution of items over the buckets may make this kind of approach unattractive.