最小生成樹的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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM