Algorithm Prim&x27的运行时间;s算法

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

假设图中的所有边权重都是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 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)
    }

}