【问题标题】:Prim and Kruskal's algorithms complexityPrim 和 Kruskal 的算法复杂度
【发布时间】:2012-06-02 14:51:51
【问题描述】:

给定一个带权重的无向连通图。 w:E->{1,2,3,4,5,6,7} - 意味着只有 7 个可能的权重。 我需要使用 O(n+m) 中的 Prim 算法和 O(m*a(m,n)) 中的 Kruskal 算法找到一棵生成树。

我不知道如何做到这一点,真的需要一些关于权重如何帮助我的指导。

【问题讨论】:

  • 你能解释一下n、m和a是什么吗?
  • @Helen m - 边,N - 顶点

标签: algorithm minimum-spanning-tree prims-algorithm kruskals-algorithm


【解决方案1】:

您可以更快地对边权重进行排序。

在 Kruskal 算法中,您不需要 O(M lg M) 排序,您只需使用计数排序(或任何其他 O(M) 算法)。所以最终的复杂度是 O(M) 用于排序和 O(Ma(m)) 用于联合查找阶段。总共是 O(Ma(m))。

以 Prim 算法为例。您不需要使用堆,您需要 7 个列表/队列/数组/任何东西(具有恒定时间插入和检索),每个权重一个。然后,当您正在寻找最便宜的传出边缘时,您检查这些列表之一是否为非空(来自最便宜的列表)并使用该边缘。由于 7 是一个常数,因此整个算法的运行时间为 O(M)。

【讨论】:

  • 你并不需要一个链表。任何具有恒定时间插入和检索的东西。
  • 如何使用具有两种权重 {1,2} 的 prim 我们达到 O(E)?我不明白这一点
  • @MioUnio 你可以为两个具有常量类型插入和检索的值实现优先级队列吗?
  • 喜欢 +1 不错的答案,但您能提供更多详细信息吗?我无法理解这一点
  • 如果你有两个权重。你只有两个数组。在一个中,您插入权重 1,在另一个中插入权重 2(以及有关边缘的相关信息)。因此,插入是恒定的时间。检索也是如此。您首先查看权重为 1 的数组,如果它不为空,则从那里选择任何边缘。如果它是空的,你从权重为 2 的数组中选择边。
【解决方案2】:

据我了解,回答家庭作业并不受欢迎,但这可能对其他人有用,而不仅仅是你;)

Prim:

Prim 是一种用于查找最小生成树 (MST) 的算法,就像 Kruskal 一样。 可视化算法的一种简单方法是在一张纸上绘制图形。 然后在您选择的所有节点上创建一条可移动的线(剪切)。在下面的示例中,集合 A 将是剪切内的节点。然后选择穿过切口的最小边,即从线内部的节点到外部的节点。始终选择权重最低的边缘。添加新节点后,您移动剪切,因此它包含新添加的节点。然后重复,直到所有节点都在剪切内。

算法的简短总结是:

  1. 创建一个集合 A,它将包含选定的顶点。它最初会包含一个由您选择的随机起始节点。
  2. 创建另一个集合 B。这最初是空的,用于标记所有选定的边。
  3. 选择一条边E(u,v),即从节点u到节点v的边。边E必须是权重最小的边,即节点u在集合A内,v不在集合内A.(如果有多条边权重相等,可以任意选择)
  4. 将边 (u, v) 添加到集合 B,将 v 添加到集合 A。
  5. 重复第 3 步和第 4 步,直到 A = V,其中 V 是所有顶点的集合。
  6. 集合 A 和 B 现在描述了生成树! MST 将包含 A 中的节点,B 将描述它们如何连接。

克鲁斯卡尔:

Kruskal 与 Prim 相似,只是没有剪辑。所以你总是选择最小的边。

  1. 创建一个集合 A,它最初是空的。它将用于存储选择的边。
  2. 从集合 E 中选择权重最小的边 E,该边不在 A 中。(u,v) = (v,u),因此您只能沿一个方向遍历该边。
  3. 将 E 添加到 A。
  4. 重复 2 和 3 直到 A 和 E 相等,也就是说,直到您选择了所有边。

我不确定这些算法的确切性能,但我假设 Kruskal 为 O(E log E),而 Prim 的性能取决于您用于存储边缘的数据结构。如果使用二叉堆,搜索最小边比使用邻接矩阵存储最小边要快。

希望这会有所帮助!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-10-17
    • 2013-12-24
    • 1970-01-01
    • 2012-10-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多