Algorithm Prim&x27的运行时间;s算法
假设图中的所有边权重都是1到| V |范围内的整数。你能让Prim的算法运行多快?对于某个常数W,如果边权重是1到W范围内的整数,该怎么办Algorithm Prim&x27的运行时间;s算法,algorithm,time,heap,prims-algorithm,Algorithm,Time,Heap,Prims Algorithm,假设图中的所有边权重都是1到| V |范围内的整数。你能让Prim的算法运行多快?对于某个常数W,如果边权重是1到W范围内的整数,该怎么办 MST-PRIM(G,w,r) 1. for each u∈ G.V 2. u.key=inf 3. u.π=NIL 4. r.key=0 5. Q=G.V 6. while Q != Ø 7. u=EXTRACT-MIN(Q) 8. for each v ∈ G.Adj[u] 9. if
MST-PRIM(G,w,r)
1. for each u∈ G.V
2. u.key=inf
3. u.π=NIL
4. r.key=0
5. Q=G.V
6. while Q != Ø
7. u=EXTRACT-MIN(Q)
8. for each v ∈ G.Adj[u]
9. if v∈ Q and w(u,v)<v.key
10. v. π=u
11. v.key=w(u,v)
MST-PRIM(G,w,r)
1.对于每个u∈ G.V
2.u、 key=inf
3.u、 π=零
4.r、 键=0
5.Q=G.V
6.而Q!=Ø
7.u=提取最小值(Q)
8.每v∈ G.Adj[u]
9如果v∈ Q和w(u,v)答案-1
第一个问题可以在stackoverflow from-中找到
答复2
Extract min操作在O(1)时间内从根获取最小元素,但同时我们需要执行操作,使下一个Extract min操作在O(1)时间内给出最小元素。我们该怎么办?我们只需将根元素与最右边的叶节点交换,然后删除该叶节点并将根重分类,这可能会将新根渗透到叶节点,这意味着O(logn)复杂度。(如2^h=n,则h=log2(n))
答复-3
关于无向图
现在为什么是2E。可以每个节点都有一些连接到它的边(如果未连接,则其阶数为零)。现在节点的阶数为n意味着它有n条边连接到它。现在让我们举个例子
1---2
| /
| /
3
1 has degree=2
2 has degree=2
3 has degree=2
-+-+-+-+-+-+-+-
so sum(deg(v))=2+2+2=6= 2*(no of edges);
为什么会这样?你可以考虑把这种情况建模为握手B/2好友。每个节点表示朋友,每个边表示握手。如果你和B握手,B也会和你握手。因此,节点(朋友)会两次考虑每次握手(边缘)
注意:对于有向图,结果将等于E
答复-4
这些链接已经解释了这一点。检查一下,希望一切都清楚
一,
二,
让我们在这里说清楚。cormen的算法是什么?它是这样给出的-
现在应用计数排序的方法-对于每个边权重,将该边放入相应的数组位置,如
现在,在遇到边缘E1后,阵列将
A [ ] [E1] [ ] [ ] [ ] [ ] [ ] [ ]
0 1 2 3 4 5 6 7
然后是边E2
A [ ] [E1] [ ] [E2] [ ] [ ] [ ] [ ]
0 1 2 3 4 5 6 7
所以在遍历所有边之后
E6
|
A [ ] [E1] [E3] [E2] [ ] [E4] [ ] [E5]
0 1 2 3 4 5 6 7
也许现在你可以理解为什么在这个图表中提到了| V |列表或| W |列表
现在你可以在O(V)时间内从数组中得到所有的极小值。
通常,对于大范围的权重,堆数据结构用于存储边
但是,在这种情况下,权重为1|因此,您可以简单地将边存储在| V |单独的列表中,一个用于权重为1到| V |的边
要找到权重最低的边,只需从第一个列表中选择一个,除非它为空,在这种情况下,从第二个列表中选择一个边
从列表中访问和删除元素是O(1),您只需从列表中删除最上面的元素。所以Prim的算法将在O(V*W+E)中运行
所以如果W=O(V),那么它在O(V^2+E)中运行
如果权重在1..W(W=O(1)常数)范围内,那么复杂度同样为O(V*W+E)。
~O(V+E)
伪码
在C中
结构边
{
国际u,v,w;
}
结构列表节点
{
边e;
结构listnode*next;
}
复杂性分析
算法:
让我们假设权重在1..W范围内|
Then just select a vertex say s ~~~~~~~~~~> O(1)
//keep an array visisted[1..|W|]
for i=1 to |W|
visited[i]=false; ~~~~~~~~~~> O(|W|)
visited[s]=true; ~~~~~~~~~~> O(1)
no_of_visited=1; ~~~~~~~~~~> O(1)
recently_visted=s; ~~~~~~~~~~~ O(1)
while(all nodes are not visited) ~~~~~O(V) //no_of_visited!=|W|
{
insert all edges from s-x (adjacent) in the array of lists.(s is recently visited) provided x is not visited ~~~~~O(|E|) altogether
get the minimum weight one ~~~~~O(|W|)
if it is u-w and w is not visited --O(1)
{
visited[w]=true;
no_of_visited++;
recently_visited=w;
insert(u,w) in spanning tree --O(1)
}
}
所以复杂性=O(| W |)+O(| W |.| V |)+O(| E |)~O(E+VW)
当W=O(V)时,T(V,E)=O(E+VV)=O(E+V^2)
出于好奇:大学…?;)我想我已经理解了你的答案1,2,3。。。但是假设图中的所有边权重都是1到| V |范围内的整数,我还不知道让Prim算法运行的速度有多快。我们能做什么?我们必须创建列表、队列还是数组?如果是,我们能做什么?我不明白…@evinda:你不需要维护优先级队列,这是基本的想法。但是我们不能为大范围的重量做这项工作,因为这将需要更多的列表。空间要求高。这就是为什么我们在大范围权重中使用heap。我不知道列表数组将包含什么。我们是否创建一个长度为| V |,A[1..V |]的数组,并在每个位置放置与该位置数量相等的边数?或者我理解错了吗?@evinda.:你必须把边放在那里..这意味着你将为边选择的数据结构..比如它可能是这样的一对(u,(v,w))
,这是一对有序的对,其中u,v是顶点,w是权重。假设边从u到v。这些顶点保存在列表数组的每个列表中。现在,无论何时删除边,都只需从给定插槽中获取最顶部或最后一条边。插入的情况也是如此。列表部分是相当标准的。插入和删除。您可能希望将不存在的元素存储在数组的插槽中,这就是实现。您的意思是,在数组a[1…| V |]的每个位置,我们都有一个包含三个数字u、V、w的列表,并且我们将数组排序为最后一个元素w?还是我理解错了?
E6
|
A [ ] [E1] [E3] [E2] [ ] [E4] [ ] [E5]
0 1 2 3 4 5 6 7
struct listnode ** A;
A=malloc(sizeof(struct list *)*N);
Intilally all of A[i]=NULL;
A[i]=malloc(sizeof(struct listnode),1);
(*A[i]).e.u=..
(*A[i]).e.v=..
(*A[i]).e.w=..
create the array of lists don't insert anythiing.
Then just select a vertex say s
keep an array visisted[1..|V|]
visited[s]=true;
no_of_visited=1;
recently_visted=s;
while(all nodes are not visited) //no_of_visited!=|V|
{
insert all edges from s-x (adjacent) in the array of lists.(s is recently visited) provided x is not visited
get the minimum weight one
if it is u-w and w is not visited
{
visited[w]=true;
no_of_visited++;
recently_visited=w;
insert(u,w) in spanning tree
}
}
Then just select a vertex say s ~~~~~~~~~~> O(1)
//keep an array visisted[1..|W|]
for i=1 to |W|
visited[i]=false; ~~~~~~~~~~> O(|W|)
visited[s]=true; ~~~~~~~~~~> O(1)
no_of_visited=1; ~~~~~~~~~~> O(1)
recently_visted=s; ~~~~~~~~~~~ O(1)
while(all nodes are not visited) ~~~~~O(V) //no_of_visited!=|W|
{
insert all edges from s-x (adjacent) in the array of lists.(s is recently visited) provided x is not visited ~~~~~O(|E|) altogether
get the minimum weight one ~~~~~O(|W|)
if it is u-w and w is not visited --O(1)
{
visited[w]=true;
no_of_visited++;
recently_visited=w;
insert(u,w) in spanning tree --O(1)
}
}