最小生成树的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实现的主要内容,如果未能解决你的问题,请参考以下文章

❤️数据结构入门❤️(3 - 4)- 最小生成树

[Python]贪心算法-Prim-和-Kruskal实现-最小生成树

图相关算法

LeetCode第111题—二叉树的最小深度—Python实现

对最小生成树的两种算法感悟

关于最小生成树的Prim算法和Kruskal算法