国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

求無向圖的最小生成樹——Kruskal算法(超詳細(xì))【并查集,python實現(xiàn)】

這篇具有很好參考價值的文章主要介紹了求無向圖的最小生成樹——Kruskal算法(超詳細(xì))【并查集,python實現(xiàn)】。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點(diǎn)擊"舉報違法"按鈕提交疑問。

一、題目

以如下無向圖為例,求最小生成樹及其權(quán)值。求無向圖的最小生成樹——Kruskal算法(超詳細(xì))【并查集,python實現(xiàn)】
補(bǔ)充知識點(diǎn):
最小生成樹(不官方的解釋):包含所有節(jié)點(diǎn),保持整個圖連通,所有邊權(quán)值之和最小。

二、思路

1、補(bǔ)充在前

(1)圖的存儲

采用二維列表存儲(點(diǎn),點(diǎn),邊的權(quán)值)

# 由圖我們得到的信息
edges = [['A', 'B', 2], ['A', 'D', 5], ['A', 'F', 8],
         ['B', 'C', 7], ['B', 'D', 7], ['B', 'E', 2],
         ['C', 'E', 3], ['D', 'E', 6], ['D', 'F', 7],
         ['D', 'G', 3], ['E', 'G', 4], ['F', 'G', 4]]
(2)頂點(diǎn)轉(zhuǎn)換

為了便于計算,將字母A ~ G用數(shù)字0 ~ 6代替(這里可以使用字典實現(xiàn))

# 字典key:value值
di = {0: 'A', 1: 'B', 2: 'C', 3: 'D', 4: 'E', 5: 'F', 6: 'G'}
# 頂點(diǎn)和邊的關(guān)系轉(zhuǎn)換如下
edges = [[0, 1, 2], [0, 3, 5], [0, 5, 8],
         [1, 2, 7], [1, 3, 7], [1, 4, 2],
         [2, 4, 3], [3, 4, 6], [3, 5, 7],
         [3, 6, 3], [4, 6, 4], [5, 6, 4]]

2、Kruskal算法思想

【畫出所有節(jié)點(diǎn)(n 個),不加邊】—> 【將邊按權(quán)值由小到大排列】—> 【依次加上每一條邊,判斷加上該邊后是否形成閉環(huán),若形成閉環(huán),則去掉該邊;若不形成,則不動,繼續(xù)下一條邊的判斷,直到圖中一共加了 n - 1 條邊,結(jié)束】
那么我們該怎么判斷加上一條邊后是否形成閉環(huán)呢?
畫圖我們很容易看出有沒有形成閉環(huán),重點(diǎn)是怎么利用代碼實現(xiàn)這個過程,這就要用到下面的并查集了(說實話,我第一次遇到并查集這個概念的時候是很懵的,記得當(dāng)時搞了好久才把這個思路理清楚,過程曲折且痛苦。。。)

3、并查集模板

(1)初始化父節(jié)點(diǎn)

初始化每一個頂點(diǎn)的父節(jié)點(diǎn)都自己(因為最開始一條邊都還沒有加上的時候,每一個頂點(diǎn)之間還沒有聯(lián)系)`

# 初始化n個節(jié)點(diǎn)的 fa(父節(jié)點(diǎn))
# 這里的下劃線和變量 i 同理
fa = [_ for _ in range(n)]
(2)查詢父節(jié)點(diǎn)——查
# 查找當(dāng)前元素所在樹的根節(jié)點(diǎn)(代表元素)
def found(node):
	# 如果父節(jié)點(diǎn)就是自己,代表已經(jīng)找到,直接返回即可
    if fa[node] == node:
        return node
    else:
        # 如果父節(jié)點(diǎn)不是自己,那就往上找一層,找父節(jié)點(diǎn)的父節(jié)點(diǎn)
        # 遞歸下去一定能找到
        fa[node] = found(fa[node])
        return fa[node]
(3)合并兩節(jié)點(diǎn)所在集合——并
# 合并元素 node1, node2 所處的集合
def unite(node1, node2):
	# 先找兩個節(jié)點(diǎn)的父節(jié)點(diǎn)
    node1 = found(node1)
    node1 = found(node1)
    # 如果父節(jié)點(diǎn)都一樣,說明已經(jīng)在一個集合中,不能再合并了
    if node1 == node2:
        return False
    else:
        # 統(tǒng)一兩頂點(diǎn)的父節(jié)點(diǎn),能合并
        fa[node1] = node2
        return True

三、完整實現(xiàn)及結(jié)果

def Kruskal(n, m, edges):
    # 按邊權(quán)值排序
    edges.sort(key=lambda edges: int(edges[2]))

    # 初始化邊數(shù)和放置邊數(shù)的集合
    edge_num = 0
    res = []

    # 遍歷每一條邊
    for i in range(m):

        # 先判斷,邊數(shù) = n - 1 就結(jié)束
        if edge_num == n - 1:
            break

        # 判斷能否合并(能合并,證明不成環(huán))
        if unite(edges[i][0], edges[i][1]):
            res.append(edges[i])
        edge_num += 1
    return res


# 查找當(dāng)前元素所在樹的根節(jié)點(diǎn)(代表元素)
def found(node):
    if fa[node] == node:
        return node
    else:
        fa[node] = found(fa[node])
        return fa[node]


# 合并元素 node1, node2 所處的集合
def unite(node1, node2):
    node1 = found(node1)
    node1 = found(node1)
    if node1 == node2:
        return False
    else:
        fa[node1] = node2
        return True


m = 12  # 邊數(shù)
n = 7  # 頂點(diǎn)個數(shù)
di = {0: 'A', 1: 'B', 2: 'C', 3: 'D', 4: 'E', 5: 'F', 6: 'G'}

fa = [_ for _ in range(n)]

# 頂點(diǎn)和邊的關(guān)系
edges = [[0, 1, 2], [0, 3, 5], [0, 5, 8],
         [1, 2, 7], [1, 3, 7], [1, 4, 2],
         [2, 4, 3], [3, 4, 6], [3, 5, 7],
         [3, 6, 3], [4, 6, 4], [5, 6, 4]]
res = Kruskal(n, m, edges)
# 打印最終點(diǎn)邊關(guān)系
s = 0
for edge in res:
	# 這里箭頭只代表兩頂點(diǎn)之間的連接作用,與方向無關(guān)
    print(f'{di[edge[0]]}->{di[edge[1]]}: {edge[2]}')
    s += edge[2]
print(f'權(quán)值:{s}')

結(jié)果展示:
求無向圖的最小生成樹——Kruskal算法(超詳細(xì))【并查集,python實現(xiàn)】
最后,如果哪里寫的有問題,歡迎大家指出來哦,共勉。(如有侵權(quán),可聯(lián)系改正/刪除)文章來源地址http://www.zghlxwxcb.cn/news/detail-442779.html

到了這里,關(guān)于求無向圖的最小生成樹——Kruskal算法(超詳細(xì))【并查集,python實現(xiàn)】的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點(diǎn)擊違法舉報進(jìn)行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • 算法提升:圖的最小生成樹算法-克魯斯卡爾(Kruskal)

    算法提升:圖的最小生成樹算法-克魯斯卡爾(Kruskal)

    目錄 概念 思路 代碼 克魯斯卡爾算法查找最小生成樹的方法是:將連通網(wǎng)中所有的邊按照權(quán)值大小做升序排序,從權(quán)值最小的邊開始選擇,只要此邊不和已選擇的邊一起構(gòu)成環(huán)路,就可以選擇它組成最小生成樹。對于 N 個頂點(diǎn)的連通網(wǎng),挑選出 N-1 條符合條件的邊,這些邊組

    2024年02月03日
    瀏覽(13)
  • 5G網(wǎng)絡(luò)建設(shè)--并查集--最小生成樹

    題目描述 現(xiàn)需要在某城市進(jìn)行5G網(wǎng)絡(luò)建設(shè),已經(jīng)選取N個地點(diǎn)設(shè)置5G基站,編號固定為1到N,接下來需要各個基站之間使用光纖進(jìn)行連接以確?;灸芑ヂ?lián)互通,不同基站之間假設(shè)光纖的成本各不相同,且有些節(jié)點(diǎn)之間已經(jīng)存在光纖相連。 請你設(shè)計算法,計算出能聯(lián)通這些基站

    2024年04月17日
    瀏覽(23)
  • Java高階數(shù)據(jù)結(jié)構(gòu) & 并查集 & 最小生成樹

    Java高階數(shù)據(jù)結(jié)構(gòu) & 并查集 & 最小生成樹

    并查集與最小生成樹 1.1 并查集的原理 在一些應(yīng)用問題中,我們常常會遇到一類問題 一開始是一個人 后來新增的人可能與這個人有關(guān)系,也可能與這個人無關(guān)系。 一個人與一個人有關(guān)系,這個人與另一個人也有關(guān)系,那么三人都有關(guān)系。 有關(guān)系的和沒關(guān)系的之間是不同的類

    2024年02月03日
    瀏覽(17)
  • 【算法導(dǎo)論】圖論(圖的基本概念,圖上的深度優(yōu)先搜索(DFS),廣度優(yōu)先搜索(BFS),最小生成樹(MST)及Prim,Kruskal算法)

    【算法導(dǎo)論】圖論(圖的基本概念,圖上的深度優(yōu)先搜索(DFS),廣度優(yōu)先搜索(BFS),最小生成樹(MST)及Prim,Kruskal算法)

    圖(Graph)是一種包含節(jié)點(diǎn)與節(jié)點(diǎn)的邊的集合,記作G=(V,E),V是節(jié)點(diǎn)的集合,E是邊的集合。 有向圖 一個有向圖G=(V,E),E中每個元素是V上的一個二值關(guān)系:一條從a出發(fā)的連向b的邊e可以記作一個 有序 對e = (a,b) 。 無向圖 一個無向圖G=(V,E),E的每個元素e可以表示V上的一個 無序 對,記

    2024年02月03日
    瀏覽(28)
  • 已知無向圖G如下所示,使用普里姆 (Prim)算法求圖G的最小生成樹。 (a)請寫出從頂點(diǎn)T出發(fā),加到最小生成樹中的邊次序。 (6分) (2)說明Prim算法更適用于求哪種類型無向圖的最小生 成樹。(2分) (3)當(dāng)圖中頂點(diǎn)個數(shù)為n,邊的個數(shù)為e時,該算法

    (a)從頂點(diǎn)T出發(fā),加到最小生成樹中的邊次序如下: 先加入頂點(diǎn)T到頂點(diǎn)E的邊,得到的最小生成樹為:T-E 再加入頂點(diǎn)E到頂點(diǎn)D的邊,得到的最小生成樹為:T-E-D 再加入頂點(diǎn)D到頂點(diǎn)B的邊,得到的最小生成樹為:T-E-D-B 再加入頂點(diǎn)B到頂點(diǎn)C的邊,得到的最小生成樹為:T-E-D-B-C 再加

    2024年01月17日
    瀏覽(17)
  • 最小生成樹——Kruskal算法

    最小生成樹——Kruskal算法

    目錄 基本思想 實現(xiàn) 偽代碼 實際問題求解 最小生成樹 :帶權(quán)連通圖的生成樹中 邊的權(quán)值之和最小的生成樹。 最小生成樹不是唯一的。當(dāng)圖中的各邊權(quán)值互不相等時,最小生成樹是唯一的; 若無向連通圖本身是一棵樹時(邊數(shù)比頂點(diǎn)數(shù)少1 ),則最小生成樹就是它本身。 最

    2023年04月26日
    瀏覽(29)
  • Kruskal 算法 最小生成樹

    1.按邊從小到大進(jìn)行排序 2.從小到大進(jìn)行加邊,保證加入的邊的兩端點(diǎn)不連通,即保證不形成回路

    2024年02月10日
    瀏覽(22)
  • Kruskal算法求解最小生成樹

    Kruskal算法求解最小生成樹

    最小生成樹是一個連通圖。 什么是連通圖,(強(qiáng))連通圖詳解 前面介紹了《圖存儲結(jié)構(gòu)》,本節(jié)繼續(xù)講解什么是 連通圖 。 前面講過,圖中從一個頂點(diǎn)到達(dá)另一頂點(diǎn),若存在至少一條路徑,則稱這兩個頂點(diǎn)是連通著的。例如圖 1 中,雖然 V1 和 V3 http://c.biancheng.net/view/3405.ht

    2024年02月07日
    瀏覽(19)
  • 最小生成樹——Kruskal算法詳解

    1.Kruskal算法解決問題 :最小生成樹 2.Kruskal所需要的前提知識: 邊集數(shù)組(引用)和 結(jié)構(gòu)體 3.Kruskal算法主要思想: Kruskal算法將 n 個點(diǎn)看成 n 個獨(dú)立的連通分支。 首先按邊權(quán)大小排序。 然后只要在 m 條邊里按 下表從小到大遍歷 選出 合適 的 n - 1 條(前提條件:選出的邊不

    2024年02月03日
    瀏覽(16)
  • 最小生成樹(Prim算法,Kruskal算法)

    最小生成樹(Prim算法,Kruskal算法)

    (1)生成樹: 如果在一個無向連通圖不包含回路(連通圖中不存在環(huán)),則為一個樹 (2)最小生成樹(minimal spanning tree): 在一個圖所有生成樹中,代價最小的生成樹稱為最小生成樹 (3)生成樹的代價: 在一個無向連通網(wǎng)中,生成樹各邊的權(quán)值之和稱為該生成樹的代價

    2024年02月08日
    瀏覽(24)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包