您的位置:首页 > 其它

五、最小生成树之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.算法示例






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)

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: