繁体   English   中英

Prim的MST算法的时间复杂度

[英]Time complexity of Prim's MST Algorithm

有人可以向我解释为什么使用相邻矩阵的Prim算法会导致O(V 2 )的时间复杂度?

(对于看起来粗鄙的ASCII数学提前抱歉,我认为我们不能使用LaTEX来排版答案)

实现具有O(V^2)复杂度的Prim算法的传统方法是除了邻接矩阵之外还有一个数组,让它称之为distance ,该距离具有该顶点到节点的最小距离。

这样,我们只检查distance以找到下一个目标,并且因为我们这样做V次并且有V个成员的distance ,我们的复杂度是O(V^2)

它本身就不够,因为distance的原始值很快就会过时。 要更新此数组,我们所做的就是在每个步骤结束时,迭代我们的邻接矩阵并适当地更新distance 这不会影响我们的时间复杂度,因为它仅意味着每个步骤取O(V+V) = O(2V) = O(V) 因此我们的算法是O(V^2)

在不使用distance我们必须每次迭代所有E边缘,最坏的情况是包含V ^ 2边缘,这意味着我们的时间复杂度将为O(V^3)

证明:

为了证明没有distance数组,不可能在O(V^2)时间内计算MST,考虑然后在每次迭代时使用大小为n的树,可能会添加Vn顶点。

要计算选择哪一个,我们必须检查每一个以找到它们与树的最小距离,然后将它们相互比较并找到最小值。

在最坏的情况下,每个节点包含到树中每个节点的连接,导致n *(Vn)边缘和O(n(Vn))的复杂度。

由于n从1到V,我们的总数将是每个步骤的总和,我们的最终时间复杂度是:

(sum O(n(V-n)) as n = 1 to V) =  O(1/6(V-1) V (V+1)) = O(V^3)

QED

注意:这个答案只是借用了jozefg的答案并试图更充分地解释它,因为在我理解之前我必须先思考一下。

背景

图的邻接矩阵表示构造V×V矩阵(其中V是顶点的数量)。 单元格(a,b)的值是连接顶点a和b的边的权重,如果没有边,则为零。

Adjacency Matrix

   A B C D E
--------------
A  0 1 0 3 2
B  1 0 0 0 2
C  0 0 0 4 3
D  3 0 4 0 1
E  2 2 3 1 0

Prim算法是一种算法,它采用图形和起始节点,并在图形上找到最小生成树 - 也就是说,它找到边缘的子集,以便结果是包含所有节点和组合边缘的树重量最小化。 可概括如下:

  1. 将起始节点放在树中。
  2. 重复,直到所有节点都在树中:
    1. 查找将树中的节点连接到不在树中的节点的所有边。
    2. 在这些边缘中,选择具有最小重量的边缘。
    3. 将该边和连接的节点添加到树中。

分析

我们现在可以开始像这样分析算法:

  1. 在循环的每次迭代中,我们向树中添加一个节点。 由于存在V个节点,因此该循环存在O(V)次迭代。
  2. 在循环的每次迭代中,我们需要在树中查找和测试边。 如果存在E边缘,则天真搜索实现使用O(E)来找到具有最小权重的边缘。
  3. 因此,在组合中,我们应该期望复杂度为O(VE),在最坏的情况下可能是O(V ^ 3)。

然而,jozefg给出了一个很好的答案,展示了如何实现O(V ^ 2)的复杂性。

Distance to Tree

            | A  B  C  D  E
            |----------------
Iteration 0 | 0  1* #  3  2
          1 | 0  0  #  3  2*
          2 | 0  0  4  1* 0
          3 | 0  0  3* 0  0
          4 | 0  0  0  0  0

NB. # = infinity (not connected to tree)
    * = minimum weight edge in this iteration

这里距离矢量表示将每个节点连接到树的最小加权边缘,并按如下方式使用:

  1. 使用复杂度为O(V)的起始节点A的边缘权重进行初始化。
  2. 要查找要添加的下一个节点,只需找到距离的最小元素(并将其从列表中删除)。 这是O(V)。
  3. 添加新节点后,有O(V)个新边连接树到其余节点; 对于这些中的每一个确定新边缘的重量是否小于现有距离。 如果是,请更新距离向量。 再次,O(V)。

使用这三个步骤减少了从O(E)到O(V)的搜索时间,并添加了额外的O(V)步骤以在每次迭代时更新距离矢量。 由于每次迭代现在是O(V),因此总体复杂度为O(V ^ 2)。

首先,它显然至少是O(V ^ 2),因为这是邻接矩阵的大小。

查看http://en.wikipedia.org/wiki/Prim%27s_algorithm ,您需要执行“重复直到Vnew = V”步骤V次。

在该步骤中,您需要计算V中任何顶点与V外任何顶点之间的最短链接。维护一个大小为V的数组,保持每个顶点无穷大(如果顶点为V)或最短的长度V中的任何顶点与该顶点之间的链接及其长度(所以在开始时这只是起始顶点和每个其他顶点之间的链接长度)。 要找到要添加到V的下一个顶点,只需按成本V搜索此数组。一旦有了新顶点,查看从该顶点到每个其他顶点的所有链接,看看它们中是否有任何链接从V到那个顶点。 如果是,请更新阵列。 这也花费了V.

所以你有V步(V顶点要添加)每个花费成本V,这给你O(V ^ 2)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM