使用Prim算法从O(n ^ 3)到O(n ^ 2)优化MST

时间:2013-10-12 19:42:57

标签: time-complexity minimum-spanning-tree prims-algorithm

以下是我使用Prim算法将连接图转换为MST的伪代码。然而,我得到n ^ 3而不是n ^ 2的复杂性。请帮我弄清楚不需要的步骤。我有一个邻接矩阵“a”来存储图形边缘的权重,一个2D矩阵“check”存储“1”表示已经在树中的顶点,“0”表示剩余。

还请注意,这也可以在nlog(n)中完成,但我不想引用任何现有的伪代码并希望自己尝试。我希望得到一个优化我自己的方法的答案。

Initialize check. //check[0][1]==1
while(--no_of_vertices)
{
    minimum_outer = infinite
    for(i from 1 to no_of_vertices)
        { 
            minimum_inner = infinite
            select i from check having value 1
            for(j from 1 to no_of_vertices )
            {

                select j from check having value 0
                if(a[i-j] < minimum_inner)
                    minimum_inner = a[i-j]
                    temp_j = j;
            }
            if(minimum_inner<minimum_outer)
            {
              minimum_outer = minimum_inner
              final_i = i
              final_j = temp_j
            }

        }

        //until here basically what I have done is, selected an i-j with lowest 
        //weight where "i" is chosen from vertices already in MST and "j" from 
        //remaining vertices

        check[final_j][1] = 1
        print final_i - final_j
        cost_of_mst += a[final_i][final_j]
}

1 个答案:

答案 0 :(得分:1)

您的算法以O(V^3)时间运行的原因是因为在每次迭代中您都要经历整个邻接矩阵,这需要O(V^2)并执行一些冗余操作。

每当您将一个顶点添加到生成树时,最多可以将|V-1|个新边添加到解决方案中。在每次迭代时,您应该只检查这些边是否将最小权重更改为每个其他顶点。

该算法应如下所示:

1. Select a random vertex v, add v to S, assign an array A where A[i] = d{v, i}
2. While there are vertices that belong to G and not to S do:
    2.1. Iterate through A, select the minimum value A[i], add vertex i to S
    2.2. for each edge e={i, j} connected to vertex i do:
         2.2.1. if d{i, j} < A[j] then A[j] = d{i ,j}

这样您就可以为添加的每个顶点而不是O(V)执行O(V^2)操作,整体运行时间为O(V^2)

以下是对代码的修改:

Select a random vertex x
Initialize DistanceTo               // DistanceTo[i] = d{x, i}
Initialize Visited                  // Visited[i]    = false if i!=x, Visited[x] = true

while(--no_of_vertices)
{
    min_val = infinite
    min_index = 1;
    for(i from 1 to DistanceTo.size)
    { 
         if (Visited[i] = false && DistanceTo[i] < min_val)
         {
             min_val = DistanceTo[i]
             min_index = i
         }
    }

    Visited[min_index] = true

    For(i from 1 to Distance.size)
    {
        if (Visited[i] = false && d{min_index, i} < DistanceTo[i])
        {
           DistanceTo[i] = d{min_index, i}
        }
    }

    print edge {min_index, i} was added to the MST
    cost_of_mst += d{min_index, i}
}