python最小生成樹kruskal與prim算法詳解
kruskal算法基本思路:先對邊按權重從小到大排序,先選取權重最小的一條邊,如果該邊的兩個節(jié)點均為不同的分量,則加入到最小生成樹,否則計算下一條邊,直到遍歷完所有的邊。
prim算法基本思路:所有節(jié)點分成兩個group,一個為已經(jīng)選取的selected_node(為list類型),一個為candidate_node,首先任取一個節(jié)點加入到selected_node,然后遍歷頭節(jié)點在selected_node,尾節(jié)點在candidate_node的邊,選取符合這個條件的邊里面權重最小的邊,加入到最小生成樹,選出的邊的尾節(jié)點加入到selected_node,并從candidate_node刪除。直到candidate_node中沒有備選節(jié)點(這個循環(huán)條件要求所有節(jié)點都有邊連接,即邊數(shù)要大于等于節(jié)點數(shù)-1,循環(huán)開始前要加入這個條件判斷,否則可能會有節(jié)點一直在candidate中,導致死循環(huán))。
#coding=utf-8
class Graph(object):
def __init__(self, maps):
self.maps = maps
self.nodenum = self.get_nodenum()
self.edgenum = self.get_edgenum()
def get_nodenum(self):
return len(self.maps)
def get_edgenum(self):
count = 0
for i in range(self.nodenum):
for j in range(i):
if self.maps[i][j] > 0 and self.maps[i][j] < 9999:
count += 1
return count
def kruskal(self):
res = []
if self.nodenum <= 0 or self.edgenum < self.nodenum-1:
return res
edge_list = []
for i in range(self.nodenum):
for j in range(i,self.nodenum):
if self.maps[i][j] < 9999:
edge_list.append([i, j, self.maps[i][j]])#按[begin, end, weight]形式加入
edge_list.sort(key=lambda a:a[2])#已經(jīng)排好序的邊集合
group = [[i] for i in range(self.nodenum)]
for edge in edge_list:
for i in range(len(group)):
if edge[0] in group[i]:
m = i
if edge[1] in group[i]:
n = i
if m != n:
res.append(edge)
group[m] = group[m] + group[n]
group[n] = []
return res
def prim(self):
res = []
if self.nodenum <= 0 or self.edgenum < self.nodenum-1:
return res
res = []
seleted_node = [0]
candidate_node = [i for i in range(1, self.nodenum)]
while len(candidate_node) > 0:
begin, end, minweight = 0, 0, 9999
for i in seleted_node:
for j in candidate_node:
if self.maps[i][j] < minweight:
minweight = self.maps[i][j]
begin = i
end = j
res.append([begin, end, minweight])
seleted_node.append(end)
candidate_node.remove(end)
return res
max_value = 9999
row0 = [0,7,max_value,max_value,max_value,5]
row1 = [7,0,9,max_value,3,max_value]
row2 = [max_value,9,0,6,max_value,max_value]
row3 = [max_value,max_value,6,0,8,10]
row4 = [max_value,3,max_value,8,0,4]
row5 = [5,max_value,max_value,10,4,0]
maps = [row0, row1, row2,row3, row4, row5]
graph = Graph(maps)
print('鄰接矩陣為\n%s'%graph.maps)
print('節(jié)點數(shù)據(jù)為%d,邊數(shù)為%d\n'%(graph.nodenum, graph.edgenum))
print('------最小生成樹kruskal算法------')
print(graph.kruskal())
print('------最小生成樹prim算法')
print(graph.prim())
初始的圖如下。

運行結果如下。

以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
相關文章
Python使用pypinyin實現(xiàn)中文拼音轉(zhuǎn)換
pypinyin是一個Python庫,用于將中文漢字轉(zhuǎn)換為拼音,這篇文章主要為大家詳細介紹了pypinyin的基本用法并探討其應用場景,需要的可以參考下2024-02-02
python實現(xiàn)一次性封裝多條sql語句(begin end)
這篇文章主要介紹了python實現(xiàn)一次性封裝多條sql語句(begin end),具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-06-06

