數據結構:最小生成樹的普里姆算法和克魯斯卡爾算法

對于一個帶權(假設每條邊上的權均為大于零的實數)連通無向圖 G 中的不同生成樹,其每棵樹的所有邊上的權值之和也可能不同;圖的所有生成樹中具有邊上的權值之和最小的樹稱為圖的最小生成樹(Minimal Spanning Tree)。

按照生成樹的定義, n n n 個頂點的連通圖的生成樹有 n n n 個頂點、 ( n ? 1 ) (n-1) (n?1) 條邊。因此,構造最小生成樹的準則有以下 3 條:

  1. 必須只使用該圖中的邊來構造最小生成樹;
  2. 必須使用且僅使用 ( n ? 1 ) (n-1) (n?1) 條邊來連接圖中的 n n n 個頂點;
  3. 不能使用產生回路的邊。

構造最小生成樹有多種算法,其中多數算法利用了最小生成樹的下列一種簡稱為 MST 的性質:假設 N = ( V , E ) N=(V,E) N=(V,E) 是一個連通網(帶權連通圖), U U U 是頂點集 V V V 的一個非空子集。若 ( u , v ) (u,v) (u,v) 是一條具有最小權值(代價)的邊,其中 $ u\in U,~v\in V-U$ ,則必存在一棵包含邊 ( u , v ) (u,v) (u,v) 的最小生成樹。

這個結論的證明,此處從略,可以參考《數據結構》(嚴蔚敏,人民郵電出版社)。

求圖的最小生成樹有很多實際應用,例如城市之間的交通工程造價最優問題就是一個最小生成樹問題。求圖的最小生成樹有兩個算法著名的算法:普里姆算法和克魯斯卡爾算法。

普里姆算法

普里姆算法的構造過程

普里姆(Prim)算法是一種構造最小生成樹的算法。

假設 G = ( V , E ) G=(V,E) G=(V,E) 是一個具有 n n n 個頂點的帶權連通圖, T = ( U , T E ) T=(U,TE) T=(U,TE) G G G 的最小生成樹,其中 U U U T T T 的頂點集, T E TE TE T T T 的邊集,則由 G G G 構造從起始點 v v v 出發的最小生成樹 T T T 的步驟如下:

  1. 初始化 U = { v } U=\{v\} U={v} ,以 v v v 到其他頂點的所有邊為候選邊。
  2. 重復以下步驟 ( n ? 1 ) (n-1) (n?1) 次,使得其他 ( n ? 1 ) (n-1) (n?1) 個頂點被加入到 U U U 中。
    • 從候選邊中挑選權值最小的邊加入 T E TE TE ,設該邊在 V ? U V-U V?U 中的頂點是 k k k ,將 k k k 加入 U U U 中;
    • 考査當前 V ? U V-U V?U 中的所有頂點 j j j ,修改候選邊,若 ( k , i ) (k,i) (k,i) 的權值小于原來和頂點 j j j 關聯的候選邊,則用 ( k , i ) (k,i) (k,i) 取代后者作為候選邊。

例如,對于圖 8.4.7 所示帶權連通圖,假設起始點為頂點 0,采用普里姆算法構造最小生成樹。

在這里插入圖片描述

圖 8.4.7 帶權連通圖
  1. 最小生成樹 T T T 包含所有頂點。
  2. U = { 0 } , V ? U = { 1 , 2 , 3 , 4 , 5 , 6 } U=\{0\},~V-U=\{1,2,3,4,5,6\} U={0},?V?U={1,2,3,4,5,6} ,在這兩個頂點集之間選擇第 1 條最小邊 ( 0 , 5 ) (0,5) (0,5) 添加到 T E TE TE 中,即 T E = { ( 0 , 5 ) } TE=\{(0,5)\} TE={(0,5)}
  3. U = { 0 , 5 } , V ? U = { 1 , 2 , 3 , 4 , 6 } U=\{0,5\},~V-U=\{1,2,3,4,6\} U={0,5},?V?U={1,2,3,4,6} ,在這兩個頂點集之間選擇第 2 條最小邊 ( 5 , 4 ) (5,4) (5,4) 添加到 T E TE TE 中,即 T E = { ( 0 , 5 ) , ( 5 , 4 ) } TE=\{(0,5),(5,4)\} TE={(0,5),(5,4)}
  4. U = { 0 , 5 , 4 } , V ? U = { 1 , 2 , 3 , 6 } U=\{0,5,4\},~V-U=\{1,2,3,6\} U={0,5,4},?V?U={1,2,3,6}? ,在這兩個頂點集之間選擇第 3 條最小邊 ( 4 , 3 ) (4,3) (4,3)? 添加到 T E TE TE? 中,即 T E = { ( 0 , 5 ) , ( 5 , 4 ) , ( 4 , 3 ) } TE=\{(0,5),(5,4),(4,3)\} TE={(0,5),(5,4),(4,3)}?。
  5. U = { 0 , 5 , 4 , 3 } , V ? U = { 1 , 2 , 6 } U=\{0,5,4,3\},~V-U=\{1,2,6\} U={0,5,4,3},?V?U={1,2,6}? ,在這兩個頂點集之間選擇第 4 條最小邊 ( 3 , 2 ) (3,2) (3,2)? 添加到 T E TE TE? 中,即 T E = { ( 0 , 5 ) , ( 5 , 4 ) , ( 4 , 3 ) , ( 3 , 2 ) } TE=\{(0,5),(5,4),(4,3),(3,2)\} TE={(0,5),(5,4),(4,3),(3,2)}?。
  6. U = { 0 , 5 , 4 , 3 , 2 } , V ? U = { 1 , 6 } U=\{0,5,4,3,2\},~V-U=\{1,6\} U={0,5,4,3,2},?V?U={1,6}? ,在這兩個頂點集之間選擇第 5 條最小邊 ( 2 , 1 ) (2,1) (2,1)? 添加到 T E TE TE? 中,即 T E = { ( 0 , 5 ) , ( 5 , 4 ) , ( 4 , 3 ) , ( 3 , 2 ) , ( 2 , 1 ) } TE=\{(0,5),(5,4),(4,3),(3,2),(2,1)\} TE={(0,5),(5,4),(4,3),(3,2),(2,1)}?。
  7. U = { 0 , 5 , 4 , 3 , 2 , 1 } , V ? U = { 6 } U=\{0,5,4,3,2,1\},~V-U=\{6\} U={0,5,4,3,2,1},?V?U={6} ,在這兩個頂點集之間選擇第 6 條最小邊 ( 1 , 6 ) (1,6) (1,6) 添加到 T E TE TE 中,即 T E = { ( 0 , 5 ) , ( 5 , 4 ) , ( 4 , 3 ) , ( 3 , 2 ) , ( 2 , 1 ) , ( 1 , 6 ) } TE=\{(0,5),(5,4),(4,3),(3,2),(2,1),(1,6)\} TE={(0,5),(5,4),(4,3),(3,2),(2,1),(1,6)},即得到了最小生成樹,如圖 8.4.8 所示。

在這里插入圖片描述

圖 8.4.8 由普里姆算法得到的最小生成樹

如果每次選擇最小邊時,存在多條同樣權值的邊可選,則任選其一即可。

克魯斯卡爾算法

克魯斯卡爾(Kruskal)算法是一種按權值的遞增次序選擇合適的邊來構造最小生成樹的方法。

克魯斯卡爾算法的構造過程

假設 G = ( V , E ) G=(V,E) G=(V,E) 是一個具有 n n n 個頂點的帶權連通無向圖, T = ( U , T E ) T=(U,TE) T=(U,TE) G G G 的最小生成樹,則構造最小生成樹的步驟如下:

  1. U U U 的初值為 V V V (即包含有 G G G 中的全部頂點), T E TE TE 的初值為空集(即圖 T T T 中的每一個頂點都構成一個分量)。
  2. 將圖 G G G 中的邊按權值從小到大的順序依次選取,若選取的邊未使生成樹 T T T 形成回路,則加入 T E TE TE ,否則舍棄,直到 T E TE TE 中包含 ( n ? 1 ) (n-1) (n?1) 條邊為止。

以圖 8.4.7 所示的帶權連通圖為例,采用克魯斯卡爾算法構造最小生成樹,其過程如下:

  1. 將所有邊按權值遞增排序:(0,5), (2,3), (1,6), (1,2), (3,6), (3,4), (4,6), (4,5), (0,1)

  2. 最小生成樹 T T T 包含所有頂點。

  3. 選最小的邊 (0,5) 加入到 T T T 中,此時不會出現回路。

  4. 選第 2 小的邊 (2,3) 加入到 T T T 中,此時不出現回路。

  5. 選第 3 小的邊 (1,6) 加入到 T T T 中,此時不出現回路。

  6. 選第 4 小的邊 (1,2) 加入到 T T T? 中,此時不出現回路。

  7. 選第 5 小的邊 (3,6) 加入到 T T T 中,此時出現回路,故舍棄它。選第 6 小的邊 (3,4) 加入到 T T T 中,此時不出現回路。

  8. 選第 7 小的邊 (4,6) 加入到 T T T 中,此時出現回路,故舍棄它。選第 8 小的邊 (4,5) 加入到 T T T? 中,此時不出現回路。

    至此在 T T T 中已經有 6 條邊( n = 7 n=7 n=7),產生了最小生成樹,如圖 8.4.9 所示。

    在這里插入圖片描述

    圖 8.4.9 由克魯斯卡爾算法得到的最小生成樹

將這里用克魯斯卡爾算法所得到的最小生成樹,與上一節中用普里姆算法得到的最小生成樹對比,可以發現,二者結果相同。這在本例中是一個巧合。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/901655.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/901655.shtml
英文地址,請注明出處:http://en.pswp.cn/news/901655.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Information-Theoretic Limits of Bistatic Integrated Sensing and Communication

摘要 雙靜態感知指的是發射器(照亮目標)和感知接收器(估計目標狀態)在物理上分離的場景,這與發射和感知功能共存的單靜態感知形成對比。在實際場景中,雙靜態感知可能需要應對系統約束,或者作為…

XCTF-web(四)

unserialize3 需要反序列化一下:O:4:“xctf”:2:{s:4:“flag”;s:3:“111”;} php_rce 題目提示rce漏洞,測試一下:?s/Index/\think\app/invokefunction&functioncall_user_func_array&vars[0]phpinfo&vars[1][]1 flag&#xff1…

Java Stream深度解析 高階技巧與性能優化實戰

文章目錄 一、Stream底層機制揭秘1.1 Stream流水線架構1.2 Spliterator探秘 二、自定義收集器高級實現2.1 實現高性能統計收集器2.2 多級分組優化技巧 三、并行流深度優化3.1 并行度控制策略3.2 工作竊取(Work-Stealing)優化 四、無限流與短路操作4.1 生成無限質數流4.2 短路操…

TailwindCss快速上手

什么是Tailwind Css? 一個實用優先的 CSS 框架,可以直接在標記中組合以構建任何設計。 開始使用Tailwind Css 如何安裝 下面是使用vite構建工具的方法 ①安裝 Tailwind CSS: tailwindcss通過tailwindcss/vitenpm安裝。 npm install tailwindcss tailwindcss…

Web前端 (CSS篇)

什么是CSS? css(Cascading Style Sheets)是層疊樣式表或級聯樣式表,是一組設置規則,用于控制web頁面外觀。 為什么使用CSS? CSS 用于定義網頁的樣式,包括針對不同設備和屏幕尺寸的設計和布局。 CSS 實例 body {background-col…

微服務2--服務治理與服務調用

前言 :本文主要闡述微服務架構中的服務治理,以及Nacos環境搭建、服務注冊、服務調用,負載均衡以及Feign實現服務調用。 服務治理 服務治理是微服務架構中最核心最基本的模塊。用于實現各個微服務的自動化注冊與發現。 服務注冊:在…

智能麻將出牌組件

開篇引言? 麻將作為一款風靡全球的策略性游戲,其復雜的規則和多變的牌局給玩家帶來了無盡樂趣。在數字化時代,運用編程技術為麻將游戲賦予智能,實現自動出牌功能,不僅能提升玩家體驗,還能深入探索算法在博弈游戲中的…

“大灣區珠寶藝境花園”璀璨綻放第五屆消博會

2025年4月13日,第五屆中國國際消費品博覽會(以下簡稱"消博會")重要主題活動——《大灣區珠寶藝境花園》啟動儀式在海南國際會展中心2號館隆重舉行。由廣東省金銀珠寶玉器業廠商會組織帶領粵港澳大灣區優秀珠寶品牌,以“…

基于前端技術的QR碼API開發實戰:從原理到部署

前言 QR碼(Quick Response Code)是一種二維碼,于1994年開發。它能快速存儲和識別數據,包含黑白方塊圖案,常用于掃描獲取信息。QR碼具有高容錯性和快速讀取的優點,廣泛應用于廣告、支付、物流等領域。通過掃…

利用耦合有限元和神經網絡計算的骨重塑模擬多尺度方法

Multiscale methodology for bone remodelling simulation using coupled finite element and neural network computation 摘要:本文旨在開發一種基于有限元分析(FEA)和神經網絡(NN)計算的多尺度分層混合模型&#xf…

使用異步特征引發的錯誤error[E0195]: lifetime parameters or bounds on method `before_save`

問題描述&#xff1a; 使用SeaOrm保存實體到數據庫時不想每次都設置更新時間&#xff0c;所以想通過實現ActiveModelBehavior在保存實體前統一設置更新時間 impl ActiveModelBehavior for ActiveModel {async fn before_save<C>(self, _db: &C, _insert: bool) -&…

TVS管與ESD保護二極管詳解:原理、區別與應用選型

一、TVS管&#xff08;瞬態電壓抑制二極管&#xff09; 1. 基本定義 TVS管&#xff08;Transient Voltage Suppressor&#xff09; 是一種用于抑制瞬態高壓脈沖的半導體器件&#xff0c;通過雪崩擊穿效應快速鉗位電壓&#xff0c;保護后端電路。 2. 核心特性參數 參數定義公…

Day08 【基于jieba分詞實現詞嵌入的文本多分類】

基于jieba分詞的文本多分類 目標數據準備參數配置數據處理模型構建主程序測試與評估測試結果 目標 本文基于給定的詞表&#xff0c;將輸入的文本基于jieba分詞分割為若干個詞&#xff0c;然后將詞基于詞表進行初步編碼&#xff0c;之后經過網絡層&#xff0c;輸出在已知類別標…

入門-C編程基礎部分:6、常量

飛書文檔https://x509p6c8to.feishu.cn/wiki/MnkLwEozRidtw6kyeW9cwClbnAg C 常量 常量是固定值&#xff0c;在程序執行期間不會改變&#xff0c;可以讓我們編程更加規范。 常量可以是任何的基本數據類型&#xff0c;比如整數常量、浮點常量、字符常量&#xff0c;或字符串字…

第二階段:數據結構與函數

模塊4&#xff1a;常用數據結構 (Organizing Lots of Data) 在前面的模塊中&#xff0c;我們學習了如何使用變量來存儲單個數據&#xff0c;比如一個數字、一個名字或一個布爾值。但很多時候&#xff0c;我們需要處理一組相關的數據&#xff0c;比如班級里所有學生的名字、一本…

【C++算法】61.字符串_最長公共前綴

文章目錄 題目鏈接&#xff1a;題目描述&#xff1a;解法C 算法代碼&#xff1a;解釋 題目鏈接&#xff1a; 14. 最長公共前綴 題目描述&#xff1a; 解法 解法一&#xff1a;兩兩比較 先算前兩個字符串的最長公共前綴&#xff0c;然后拿這個最長公共前綴和后面一個來比較&…

JVM 調優不再難:AI 工具自動生成內存優化方案

在 Java 應用程序的開發與運行過程中&#xff0c;Java 虛擬機&#xff08;JVM&#xff09;的性能調優一直是一項極具挑戰性的任務&#xff0c;尤其是內存優化方面。不合適的 JVM 內存配置可能會導致應用程序出現性能瓶頸&#xff0c;甚至頻繁拋出內存溢出異常&#xff0c;影響業…

紛析云開源財務軟件:企業財務數字化轉型的靈活解決方案

紛析云是一家專注于開源財務軟件研發的公司&#xff0c;自2018年成立以來&#xff0c;始終以“開源開放”為核心理念&#xff0c;致力于通過技術創新助力企業實現財務管理的數字化與智能化轉型。其開源財務軟件憑借高擴展性、靈活部署和全面的功能模塊&#xff0c;成為眾多企業…

【數字圖像處理】數字圖像空間域增強(3)

圖像銳化 圖像細節增強 圖像輪廓&#xff1a;灰度值陡然變化的部分 空間變化&#xff1a;計算灰度變化程度 圖像微分法&#xff1a;微分計算灰度梯度突變的速率 一階微分&#xff1a;單向差值 二階微分&#xff1a;雙向插值 一階微分濾波 1&#xff1a;梯度法 梯度&#xff1…

基于Linux的ffmpeg python的關鍵幀抽取

1.FFmpeg的環境配置 首先強調&#xff0c;ffmpeg-python包與ffmpeg包不一樣。 1) 創建一個虛擬環境env conda create -n yourenv python3.x conda activate yourenv2) ffmpeg-python包的安裝 pip install ffmpeg-python3) 安裝系統級別的 FFmpeg 工具 雖然安裝了 ffmpeg-p…