最小生成樹之Prim演算法和Kruskal演算法
一個連通圖可能有多棵生成樹,而最小生成樹是一副連通加權無向圖中一顆權值最小的生成樹,它可以根據Prim演算法和Kruskal演算法得出,這兩個演算法分別從點和邊的角度來解決。
Prim演算法
- 輸入:一個加權連通圖,其中頂點集合為V,邊集合為E;
- 初始化:Vn = {x},其中x為集合V中的任一節點(起始點),Enew = {};
- 重複下列操作,直到Vn = V:(在集合E中選取權值最小的邊(u, v),其中u為集合Vn中的元素,而v則是V中沒有加入Vn的頂點(如果存在有多條滿足前述條件即具有相同權值的邊,則可任意選取其中之一);
將v加入集合Vn中,將(u, v)加入集合En中;) - 輸出:使用集合Vn和En來描述所得到的最小生成樹。
以下面這張圖作為例子,表格中的Vertex、Kown、Cost、Path分別表示頂點資訊、是否訪問過,權值,到達路徑;
我們隨機的選擇頂點0作為起點,其執行步驟為:
步驟 | 選中結點 |
---|---|
頂點0作為起始點 | 0 |
根據(6, 7, 8)的方案選中6 | 1 |
根據頂點1能夠到達的權值(7, 4, 3)和頂點0能夠到達的權值(7, 8)中選擇3 | 5 |
根據頂點5能夠到達的權值(8)和根據頂點1能夠到達的權值(7, 4)和頂點0能夠到達的權值(7, 8)中選擇4 | 6 |
根據頂點6能夠到達的權值(6, 7)和頂點0能夠到達的權值(7)中選擇6 | 2 |
根據頂點0能夠到達的權值(7)和頂點6能夠到達的權值(7)中選擇7 | 4 |
根據頂點6能夠到達的權值(7)選擇7 | 7 |
根據頂點7能夠到達的權值(2)選擇2 | 3 |
全部結點都訪問過,退出 |
Prim演算法實現
根據前面的那幅圖來實現,如下:class MST(object):
def __init__(self, graph):
self.graph = graph
self.N = len(self.graph)
pass
def prim(self, start):
index = start
cost, path = [0] * self.N, [0] * self.N
# 初始化起點
known = [x for x in map(lambda x: True if x == start else False, [x for x in range(self.N)])]
path[start] = -1
for i in range(self.N):
cost[i] = self.graph[start][i]
# 遍歷其餘各個結點
for i in range(1, self.N):
mi = 1e9
# 找出相對最小權重的結點
for j in range(self.N):
if not known[j] and mi > cost[j]:
mi, index = cost[j], j
# 計算路徑值
for j in range(self.N):
if self.graph[j][index] == mi:
path[index] = j
known[index] = True
# 更新index連通其它結點的權重
for j in range(self.N):
if not known[j] and cost[j] > self.graph[index][j]:
cost[j] = self.graph[index][j]
print(path)
# 圖用臨接矩陣表示
MST([
[1e9, 6, 8, 1e9, 7, 1e9, 1e9, 1e9],
[6, 1e9, 7, 1e9, 1e9, 3, 4, 1e9],
[8, 7, 1e9, 1e9, 1e9, 1e9, 6, 1e9],
[1e9, 1e9, 1e9, 1e9, 1e9, 1e9, 1e9, 2],
[7, 1e9, 1e9, 1e9, 1e9, 1e9, 1e9, 1e9],
[1e9, 3, 1e9, 1e9, 1e9, 1e9, 1e9, 9],
[1e9, 4, 6, 1e9, 1e9, 1e9, 1e9, 7],
[1e9, 1e9, 1e9, 2, 1e9, 9, 7, 1e9],
]).prim(0)
path結果為:[-1, 0, 6, 7, 0, 1, 1, 6]Kruskal演算法
構造一個只含n個頂點,而邊集為空的子圖,若將該子圖中各個頂點看成是各棵樹的根節點,則它是一個含有n棵樹的森林 。之後,從圖的邊集中選取一條權值最小的邊,若該邊的兩個頂點分屬不同的樹 ,則將其加入子圖,也就是這兩個頂點分別所在的 兩棵樹合成一棵樹;反之,若該邊的兩個頂點已落在同一棵樹上,則不可取,而應該取下一條權值最小的邊再試之。依次類推,直至森林只有一棵樹。kruskal演算法能夠在並查集的基礎很快的實現。以下面這張圖作為例子,其中左邊的表格是一個並查集,表示可以連通的結點。我們首先要根據權值對每條邊進行排序,接著開始處理每一條邊的情況。
最終得到下面的結果圖:
Kruskal演算法實現
因為我們要處理邊,所以需要建立邊的資料結構,並且要從給定的圖中獲取每一條邊的資料。class Edge(object):
def __init__(self, start, end, weight):
self.start = start
self.end = end
self.weight = weight
def getEdges(self):
edges = []
for i in range(self.vertex):
for j in range(i+1, self.vertex):
if self.graph[i][j] != 1e9:
edge = Edge(i, j, self.graph[i][j])
edges.append(edge)
return edges
接下來就是kruskal函式:def kruskal(self):
union = dict.fromkeys([i for i in range(self.vertex)], -1) # 輔助陣列,判斷兩個結點是否連通
self.edges = self.getEdges()
self.edges.sort(key=lambda x: x.weight)
res = []
def getend(start):
while union[start] >= 0:
start = union[start]
return start
for edge in self.edges:
# 找到連通線路的最後一個結點
n1 = getend(edge.start)
n2 = getend(edge.end)
# 如果為共同的終點則不處理
if n1 != n2:
print('{}----->{}'.format(n1, n2))
(n1, n2) = (n2, n1) if union[n1] < union[n2] else (n1, n2)
union[n2] += union[n1]
union[n1] = n2
res.append(edge)
print(union.values())
其中union列印出來的結果和圖中是一致的,為[3, 3, 5, 6, 6, 6, -8, 3]。相關文章
- 最小生成樹:Kruskal演算法和Prim演算法演算法
- 最小生成樹-Prim演算法和Kruskal演算法演算法
- 最小生成樹之 Prim 演算法演算法
- Kruskal 最小生成樹演算法演算法
- 最小生成樹__Prim演算法演算法
- 最小生成樹——Prim演算法和Kruscal演算法演算法
- 最小生成樹---普里姆演算法(Prim演算法)和克魯斯卡爾演算法(Kruskal演算法)演算法
- 最小生成樹,Prim演算法與Kruskal演算法,408方向,思路與實現分析演算法
- 最小生成樹prim普里姆演算法演算法
- 最小生成樹(MinSpanTree)的Kruskal演算法演算法
- 【JAVA演算法】圖論演算法 --求最小生成樹Prim演算法Java演算法圖論
- 圖解Prim&Kruskal演算法圖解演算法
- Matlab生成Kruskal最小生成樹Matlab
- Prim 最小生成樹 圖解圖解
- 最小生成樹的性質與prim演算法(C++實現)演算法C++
- 圖論之帶權圖「最小生成樹之Prim」圖論
- 關於圖的最小生成路徑——Kruskal演算法和Prime演算法演算法
- 最小生成樹之普里姆演算法演算法
- 最小生成樹__Kurskal演算法演算法
- 最小生成樹的演算法演算法
- 東哥帶你刷圖論第五期:Kruskal 最小生成樹演算法圖論演算法
- 【演算法學習】最小生成樹演算法
- 演算法-圖論-最小生成樹演算法圖論
- 圖論之帶權圖「最小生成樹prim的優化」圖論優化
- 北極通訊網路——最小生成樹kruskal
- 圖論之帶權圖「最小生成樹prim的最佳化」圖論
- 演算法學習之路|最小生成樹——prime演算法演算法
- 資料結構------最短路徑Dijkstra和最小生成樹Prim資料結構
- Prim演算法(最小生成樹) 我TM只能先做到這兒了 後面繼續補充演算法
- Boruvka求最小生成樹(菠蘿演算法)演算法
- 圖論中的最小生成樹演算法圖論演算法
- 最小樹形圖(有向圖的最小生成樹)朱劉演算法演算法
- 演算法基礎 第5版 第四章 最小生成樹Prim方法的Ruby實現演算法
- 前端必會演算法 - 最小生成樹問題前端演算法
- POJ2031 Building a Space Station(最小生成樹,prim)UI
- Kruskal演算法演算法
- 如何在 Java 中實現最小生成樹演算法Java演算法
- 演算法 最小高度樹演算法