以下是我使用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]
}
答案 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}
}