Python数模笔记-NetworkX(4)最小生成树
1、生成樹和最小生成樹
1.1 生成樹
連通的無圈圖稱為樹,就是不包含循環的回路的連通圖。
對于無向連通圖,生成樹(Spanning tree)是原圖的極小連通子圖,它包含原圖中的所有 n 個頂點,并且有保持圖連通的最少的邊,即只有足以構成一棵樹的 n-1 條邊。
生成樹滿足:
- (1)包含連通圖中所有的頂點;
- (2)任意兩頂點之間有且僅有一條通路。
因此,生成樹中邊的數量 = 頂點數 - 1。
對于非連通無向圖, 遍歷每個連通分量中的頂點集合所經過的邊是多顆生成樹,這些連通分量的生成樹構成非連通圖的生成森林 。
歡迎關注 Youcans 原創系列,數模筆記每周更新
Python數模筆記-PuLP庫
Python數模筆記-StatsModels統計回歸
Python數模筆記-Sklearn
Python數模筆記-NetworkX
Python數模筆記-模擬退火算法
1.2 最小生成樹和最大生成樹
遍歷連通圖的方式有多種,也就是說對于一張連通圖,可能有多種不同的生成樹。
帶權的連通圖的生成樹中各條邊的權重之和最小的生成樹,稱為最小生成樹(minimum spanning tree,MST),也稱最小權重生成樹。
對應地,各條邊的權重之和最大的生成樹,稱為最大生成樹。
生成樹和最小生成樹有許多重要的應用。例如在若干城市之間鋪設通信線路,使任意兩個城市之間都可以通信,要使鋪設線路的總費用最低,就需要找到最小生成樹。
2、最小生成樹算法
構造最小生成樹的算法很多,通常是基于MST性質,從空樹開始,按照貪心法逐步選擇并加入 n-1 條安全邊(不產生回路),最終生成一棵最小生成樹。
最小生成樹的典型算法有普里姆算法(Prim算法)和克魯斯卡算法(Kruskal算法)。
2.1 普里姆算法(Prim算法)
Prim 算法以頂點為基礎構造最小生成樹:從某一個頂點 s 開始,每次選擇剩余的代價最小的邊所對應的頂點,加入到最小生成樹的頂點集合中,逐步擴充直到包含整個連通網的所有頂點,可以稱為“加點法”。Prim算法中每個頂點只與連通圖連接一次,因此不用考慮在加入頂點的過程中是否會形成回路。
Prim 算法中圖的存貯結構采用鄰接矩陣,使用一個頂點集合 u 構造最小生成樹。由于不斷向集合u中加點,還需要建立一個輔助數組來同步更新最小代價邊的信息。
Prim 算法每次選擇頂點時,都需要進行排序,但每次都只需要對一部分邊進行排序。Prim 算法的時間復雜度為 O(n*n),與邊的數量無關,適用于邊很多的稠密圖。采用堆實現優先隊列來維護最小點,可以將Prim算法的時間復雜度降低到 O(mlogn),稱為Prim_heap 算法,但該算法的空間消耗很大。
2.2 克魯斯卡算法(Kruskal算法)
Kruskal 算法以邊為基礎構造最小生成樹:初始邊數為 0,每次選擇一條滿足條件的最小代價邊,加入到邊集合中,逐步擴充直到包含整個生成樹,可以稱為“加邊法”。Kruskal 算法是利用避圈思想,每次找到不使圖構成回路的代價最小的邊。
Kruskal 算法中圖的存貯結構采用邊集數組,權值相等的邊在數組中的排列次序是任意的。
Kruskal算法開始就要對所有的邊進行排序,之后還需要對所有邊應用 Union-Find算法,但不再需要排序。Kruskal 算法的時間復雜度為 O(mlogm),主要是對邊排序的時間復雜度,適用于邊較少的稀疏圖。
3、NetworkX 的最小生成樹算法
3.1 最小/最大生成樹函數
| minimum_spanning_tree(G[, weight,…]) | 計算無向圖上的最小生成樹 |
| maximum_spanning_tree(G[, weight,…]) | 計算無向圖上的最大生成樹 |
| minimum_spanning_edges(G[, algorithm,…]) | 計算無向加權圖最小生成樹的邊 |
| maximum_spanning_edges(G[, algorithm,…]) | 計算無向加權圖最大生成樹的邊 |
3.2 minimum_spanning_tree() 使用說明
minimum_spanning_tree(G, weight=‘weight’, algorithm=‘kruskal’, ignore_nan=False)
minimum_spanning_edges(G, algorithm=‘kruskal’, weight=‘weight’, keys=True, data=True, ignore_nan=False)
minimum_spanning_tree() 用于計算無向連通圖的最小生成樹(森林)。minimum_spanning_edges() 用于計算無向連通圖的最小生成樹(森林)的邊。
對于連通無向圖,計算最小生成樹;對于非連通無向圖,計算最小生成森林。
主要參數:
- G(undirected graph):無向圖。
- weight(str):指定用作計算權重的邊屬性。
- algorithm(string):計算最小生成樹的算法,可選項為 ‘kruskal’、‘prim’ 或 ‘boruvka’。默認算法為 ‘kruskal’。
- data(bool):指定返回值是否包括邊的權值。
- ignore_nan(bool) :在邊的權重為 Nan 時產生異常。
返回值:
- minimum_spanning_tree() 的返回值是最小生成樹,類型為<class ‘networkx.classes.graph.Graph’> 。
- minimum_spanning_edges() 的返回值是最小生成樹的構成邊,類型為<class ‘generator’>。
3.3 minimum_spanning_tree() 算法使用例程
本案例問題來自:司守奎、孫兆亮,數學建模算法與應用(第2版),P48,例4.5,國防工業出版社。
例:最小生成樹問題。已知如圖的有權無向圖,求最小生成樹。
# networkX_E4.py # Demo of minimum spanning tree(MST) with NetworkX # Copyright 2021 YouCans, XUPT # Crated:2021-05-21import matplotlib.pyplot as plt # 導入 Matplotlib 工具包 import networkx as nx # 導入 NetworkX 工具包G = nx.Graph() # 創建:空的 無向圖 G.add_weighted_edges_from([(1,2,50),(1,3,60),(2,4,65),(2,5,40),(3,4,52),(3,7,45),(4,5,50),(4,6,30),(4,7,42),(5,6,70)]) # 向圖中添加多條賦權邊: (node1,node2,weight)T = nx.minimum_spanning_tree(G) # 返回包括最小生成樹的圖 print(T.nodes) # [1, 2, 3, 4, 5, 7, 6] print(T.edges) # [(1,2), (2,5), (3,7), (4,6), (4,7), (4,5)] print(sorted(T.edges)) # [(1,2), (2,5), (3,7), (4,5), (4,6), (4,7)] print(sorted(T.edges(data=True))) # data=True 表示返回值包括邊的權重 # [(1,2,{'weight':50}), (2,5,{'weight':40}), (3,7,{'weight':45}), (4,5,{'weight':50}), (4,6,{'weight':30}), (4,7,{'weight':42})]mst1 = nx.tree.minimum_spanning_edges(G, algorithm="kruskal") # 返回值 帶權的邊 print(list(mst1)) # [(4,6,{'weight':30}), (2,5,{'weight':40}), (4,7,{'weight':42}), (3,7,{'weight':45}), (1,2,{'weight':50}), (4,5,{'weight':50})] mst2 = nx.tree.minimum_spanning_edges(G, algorithm="prim",data=False) # data=False 表示返回值不帶權 print(list(mst2)) # [(1,2), (2,5), (5,4), (4,6), (4,7), (7,3)]pos={1:(2.5,10),2:(0,5),3:(7.5,10),4:(5,5),5:(2.5,0),6:(7.5,0),7:(10,5)} # 指定頂點位置 nx.draw(G, pos, with_labels=True, alpha=0.8) # 繪制無向圖 labels = nx.get_edge_attributes(G,'weight') # YouCans, XUPT nx.draw_networkx_edge_labels(G,pos,edge_labels=labels, font_color='c') # 顯示邊的權值 nx.draw_networkx_edges(G,pos,edgelist=T.edges,edge_color='r',width=4) # 設置指定邊的顏色 plt.show()3.4 程序運行結果
[1, 2, 3, 4, 5, 7, 6] [(1, 2), (2, 5), (3, 7), (4, 6), (4, 7), (4, 5)] [(1, 2), (2, 5), (3, 7), (4, 5), (4, 6), (4, 7)] [(1, 2, {'weight': 50}), (2, 5, {'weight': 40}), (3, 7, {'weight': 45}), (4, 5, {'weight': 50}), (4, 6, {'weight': 30}), (4, 7, {'weight': 42})] [(4, 6, {'weight': 30}), (2, 5, {'weight': 40}), (4, 7, {'weight': 42}), (3, 7, {'weight': 45}), (1, 2, {'weight': 50}), (4, 5, {'weight': 50})] [(1, 2), (2, 5), (5, 4), (4, 6), (4, 7), (7, 3)]3.5 程序說明
版權說明:
YouCans 原創作品:Python 數模筆記
本文內容及例程為作者原創,并非轉載書籍或網絡內容。
本文中案例問題來自:司守奎、孫兆亮,數學建模算法與應用(第2版),國防工業出版社
YouCans 原創作品,轉載需標注原始鏈接。
Copyright 2021 YouCans, XUPT
Crated:2021-05-21
歡迎關注 Youcans 原創系列,每周更新數模筆記
Python數模筆記-PuLP庫(1)線性規劃入門
Python數模筆記-PuLP庫(2)線性規劃進階
Python數模筆記-PuLP庫(3)線性規劃實例
Python數模筆記-Scipy庫(1)線性規劃問題
Python數模筆記-StatsModels 統計回歸(1)簡介
Python數模筆記-StatsModels 統計回歸(2)線性回歸
Python數模筆記-StatsModels 統計回歸(3)模型數據的準備
Python數模筆記-StatsModels 統計回歸(4)可視化
Python數模筆記-Sklearn (1)介紹
Python數模筆記-Sklearn (2)聚類分析
Python數模筆記-Sklearn (3)主成分分析
Python數模筆記-Sklearn (4)線性回歸
Python數模筆記-Sklearn (5)支持向量機
Python數模筆記-模擬退火算法(1)多變量函數優化
Python數模筆記-模擬退火算法(2)約束條件的處理
Python數模筆記-模擬退火算法(3)整數規劃問題
Python數模筆記-模擬退火算法(4)旅行商問題
Python數模筆記-NetworkX(1)圖的操作
Python數模筆記-NetworkX(2)最短路徑
Python數模筆記-NetworkX(3)條件最短路徑
總結
以上是生活随笔為你收集整理的Python数模笔记-NetworkX(4)最小生成树的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: ios开发中计算代码运算时间_理解Uni
- 下一篇: 如何删除Win All的流氓程序文件