最小生成树的Python实现
Posted zhangcheng2020
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了最小生成树的Python实现相关的知识,希望对你有一定的参考价值。
最小生成树是指带权无向图中,其各边权值和最小的生成树。这个问题在日常生活中会广泛遇到,如何用最小的代价把网络中各点连接起来。
常用的算法有Kruskal,Prim,我们对这两个典型算法进行Python实现。
Kruskal
Kruskal算法基于简单连通分量的最小代价互联。将初始图G中各边按权值从小到大排列成列表edges,存储方式为 (weight, vi, vj),每次取出一条边,检查其连接的两端是否已连通,若尚未连通则将该边加入生成树,并修改该边所连接的两个连通分量的状态,否则删除该边。相应的Python代码实现如下:
1 def Kruskal(graph): 2 vnum = graph.vertex_num() #得到图中点的个数 3 mst, edges = [], [] 4 reps = [i for i in range(vnum)] #初始化代表元 5 for vi in range(vnum): #收集各边 6 for vj,weight in graph.out_edges(vi): 7 edges.append((weight,vi,vj)) 8 edges.sort() #将边按权值weight从小到大排序 9 for weight, vi, vj in edges: #逐个遍历边,将其加入到mst中 10 if reps[vi] != reps[vj]: 11 mst.append((vi, vj, weight)) 12 repi, repj = reps[i], reps[j] 13 for v in range(vnum): #更新代表元 14 if reps[v] == repj: 15 reps[v] = repi 16 return mst
Prim
Prim算法是基于所谓的MST准则,将图的点集分为两部分,mst和V,依次将边顶点分属于两个点集的最小权值边加入到生成树中,同时将V中连接的点加入到mst中,相比于Kruskal不断将最小权值边加入生成树,Prim则是连续扩大最小生成树中的点集。
相应的Python代码实现如下:
1 def Prim(graph): 2 vnum = graph.vertex_num() 3 edges = PrioQueue((0,0,0)) #每次将新边加入到一个优先队列中 4 mst = [None] * vnum #用于判断边所连接的点是否已经遍历过 5 edge_count = 0 6 while edge_count < vnum and not edges.is_empty(): 7 weight, vi, vj = edges.dequeue() 8 if mst[vj] == None: 9 edge_count += 1 10 mst[vj] = (vi, weight) 11 for i,w in graph.out_edges(vj): #将新点的出边加入优先队列 12 if not mst[i]: 13 edges.enqueue((w, vj, i)) 14 return mst
以上是关于最小生成树的Python实现的主要内容,如果未能解决你的问题,请参考以下文章
[Python]贪心算法-Prim-和-Kruskal实现-最小生成树