五、最小生成树之Kruskal和Prim
2012-06-15 14:57
567 查看
1.算法介绍
在实际问题中常常要遇到布线和租用的优化情况,在保持连通的情况下达到最小成本。这就是最小生成树(minimum spanning tree)或最优树(optimal tree)算法的由来。
最小生成树的两个经典算法—Kruskal与Prim,都是用于求无向连通图的最小生成树算法。
2.算法过程
Kruskal过程:
(i):初始化。集合TE和数组visit,其中TE用来存储最小生成树的边,visit通过访问标识来检测环
(ii):将图G(V,E)的所有边,按照权值不减顺序排列,选取其中的第一个边e(u,v),如果u和v的visit都为0(即都没访问过,不存在环),则将边e加入集合TE中,设置相应的visit元素
(iii):检测visit是否全部为1,如果都访问过了,则结束算法;否则,跳转到(ii)
Kruskal的复杂度一般表示为O(mlogn),其中m为图的边数,而n为图的顶点数
Prim过程:
(i):初始化。集合TE、S、数组distant和closest,将图的第一个节点1放入S中,distant[1]=0,closest[1]=0。其中TE用来存储最小生成树的边,S用来记录在集合TE中的顶点,distant用来记录任意节点v∈V-S到S的最小距离,closest用来保存节点v和S距离最近的节点。
(ii):如果S中的顶点个数小于v,则repeat:
从S中取出最后一个节点v,对于每个节点u∈V-S,如果distant[u]<e(u,v),则distant[u]更新为e(u,v),并且将closest[u]=v
更新完毕后,遍历节点u∈V-S,找出distant中的最小值distant[i],并取出其closest[i]=k,则将顶点i放入S中,将边e(i,k)放入TE中
Prim算法复杂度为O(v^2)
3.算法示例
在实际问题中常常要遇到布线和租用的优化情况,在保持连通的情况下达到最小成本。这就是最小生成树(minimum spanning tree)或最优树(optimal tree)算法的由来。
最小生成树的两个经典算法—Kruskal与Prim,都是用于求无向连通图的最小生成树算法。
2.算法过程
Kruskal过程:
(i):初始化。集合TE和数组visit,其中TE用来存储最小生成树的边,visit通过访问标识来检测环
(ii):将图G(V,E)的所有边,按照权值不减顺序排列,选取其中的第一个边e(u,v),如果u和v的visit都为0(即都没访问过,不存在环),则将边e加入集合TE中,设置相应的visit元素
(iii):检测visit是否全部为1,如果都访问过了,则结束算法;否则,跳转到(ii)
Kruskal的复杂度一般表示为O(mlogn),其中m为图的边数,而n为图的顶点数
Prim过程:
(i):初始化。集合TE、S、数组distant和closest,将图的第一个节点1放入S中,distant[1]=0,closest[1]=0。其中TE用来存储最小生成树的边,S用来记录在集合TE中的顶点,distant用来记录任意节点v∈V-S到S的最小距离,closest用来保存节点v和S距离最近的节点。
(ii):如果S中的顶点个数小于v,则repeat:
从S中取出最后一个节点v,对于每个节点u∈V-S,如果distant[u]<e(u,v),则distant[u]更新为e(u,v),并且将closest[u]=v
更新完毕后,遍历节点u∈V-S,找出distant中的最小值distant[i],并取出其closest[i]=k,则将顶点i放入S中,将边e(i,k)放入TE中
Prim算法复杂度为O(v^2)
3.算法示例
import networkx as nx def Kruskal(G=nx.Graph()): TE=[] visit=[] for node in G.nodes(): visit.append(0) sorted_edge=[] for edge in G.edges(): u=edge[0] v=edge[1] weight=G.get_edge_data(u,v)['weight'] if len(sorted_edge) is 0: sorted_edge.append((u,v)) else: inc=0 while inc<len(sorted_edge): if G.get_edge_data(sorted_edge[inc][0],sorted_edge[inc][1])['weight']>weight: sorted_edge.insert(inc,(u,v)) break inc=inc+1 if inc==len(sorted_edge): sorted_edge.append((u,v)) print sorted_edge while len(TE)<G.number_of_nodes()-1: item=sorted_edge[0] del sorted_edge[0] u=item[0] v=item[1] if visit[v-1]==0 or visit[u-1]==0: TE.append(item) visit[v-1]=1 visit[u-1]=1 print 'Kruskal',TE def Prim(G=nx.Graph()): TE=[] S=[] distant=[] closest=[] i=0 while i<G.number_of_nodes(): distant.append(100) closest.append(0) i=i+1 distant[1]=0 closest[1]=1 S.append(1) while len(S)<G.number_of_nodes(): item=S[len(S)-1] for node in G.nodes(): if node not in S and G.has_edge(item,node): if distant[node-1]>G.get_edge_data(item,node)['weight']: distant[node-1]=G.get_edge_data(item,node)['weight'] closest[node-1]=item i=index=0 while i<len(distant): if distant[i]<distant[index] and i+1 not in S: index=i i=i+1 S.append(index+1) TE.append((closest[index],index+1)) print "Prime",TE G=nx.Graph() G.add_weighted_edges_from([(1,2,1),(1,3,4),(1,4,1),(1,5,3),(1,6,3),(2,3,2),(2,5,4),(3,4,2),(4,5,4),(4,6,5),(5,6,3)]) Kruskal(G) Prim(G)
相关文章推荐
- 最小生成树prim+kruskal模板
- 51Nod 1212 无向图最小生成树(最小生成树Kruskal & Prim
- 最小生成树算法(Prim+Kruskal)
- 最小生成树 PRIM KRUSKAL
- Prim和Kruskal求最小生成树
- [kuangbin带你飞]专题六 最小生成树 (prim)(kruskal)(模板)
- 最小生成树prim和kruskal
- 图论总结 Dijkstra Tarjan 最小生成树 二分图 最短路 强连通分量 双连通分量 Bellman-Ford SPFA 二分图染色 Kruskal Prim 网络流 二分图匹配 Dinic
- hdu 1233 还是畅通工程 (最小生成树,prim,优先队列,kruskal并查集)
- 图算法(5)-最小生成树(Prim, Kruskal)
- 最小生成树 Prim和Kruskal
- POJ2485 Highways(prim和Kruskal最小生成树两种解法)
- 最小生成树-普林算法(Prim)/克鲁斯卡尔算法(Kruskal)
- (最小生成树问题:Prim,Kruskal)村村通公路
- 【算法复习】图的最小生成树(Prim&Kruskal)
- POJ 1789 Truck History 最小生成树 kruskal && Prim
- zoj 1586 QS Network【最小生成树 kruskal && prim】
- poj1258 Agri-Net 最小生成树 prim kruskal 模板
- Prim和Kruskal求最小生成树
- 图结构练习——最小生成树(Prim+Kruskal)