【初識數據結構】CS61B中的最小生成樹問題

本教程總結CS61B 關于圖章節中的最小生成樹(Minimum Spanning Trees, MST)問題,以及對應的的算法

什么是最小生成樹(MST)

考慮這樣一個問題,給你一個無向圖,你能不能找出這個圖中的一組邊,讓其滿足:

  • 連通的
  • 無環的
  • 涉及到了所有的結點
    比如這樣一張圖
    alt text
    這樣的一組邊構成的樹,稱為生成樹
    而讓這個樹中所有的邊權重之和最小即為最小生成樹

如何找到最小生成樹

一個非常有用的性質:割邊屬性(Cut Property)

  • 一個 cut 就是將一個圖中的結點分成兩個非空集合
  • 一個 crossing cut 就是從一個集合結點連接到了另一個集合結點的邊
    割邊屬性是這樣描述的:給定任意一個 cut,最小權重的 crossing edge 一定在最小生成樹中
    alt text
    比如上面這張圖中,所有的紅色邊都是 crossing edge,其中最小的邊一定在最小生成樹中
    我們判斷 crossing edge 只需要看這個邊是否連接了兩個屬于不同集合(也就是不同顏色)的結點即可

通用的尋找 MST 算法

基于割邊屬性,我們可以這樣構造一個算法:
首先一開始MST沒有邊:

  • 找到一個沒有 crossing edge 在MST中的 cut
  • 然后將最小權重的 crossing edge 加入 MST
  • 一直重復到 V-1 條邊

Prim’s Algorithm

相比較最短路徑樹而言,最小生成樹并不需要給出一個起點,在最小生成樹中,只需要給你圖然后說告訴我哪些邊觸及所有頂點且權重之和最小即可。

但是并不代表我們不選取一個起始結點,相對來說,Prim 算法會隨機選擇一個起始結點,這個隨機性并不對最終結果產生影響(我們總要尋找一個結點來入手)

算法流程

從一個隨機結點開始:

  • 將一個一頭連接已經在MST中結點的最短的邊,加入MST,直到 V-1 條邊

alt text
比如在這個圖中,所有符合上述條件的即為紅色的邊:連接了一個在MST中的結點
然后我們選取這些邊中最短的邊,也就是A->B或者E->D

Prim 算法實際上是不斷地使用了割邊屬性

改進的 Prim’s Algorithm

Prim 算法是可以奏效的,但效率太低了,因為你必須考慮大量的穿過這個 cut 的 crossing edge
我們對 Prim 算法進行改進:

  • 將所有結點放入 fringe PQ 中,以結點到樹的距離作為排序標準
  • 重復:將距離樹最近的結點移出,然后將其指出的所有邊進行relaxation,然后對 distTo 和 edgeTo 數組進行更新

alt text
這個圖中我們剛剛把距離樹最近的結點E移出,加入到MST中,然后relax它的所有的邊,同時更新 distTo 和 edgeTo 數組

圖中加粗的邊為MST中的邊,圖中的虛線表示relax出來的邊,作為MST的候選邊,如果在relax中發現這條邊不如之前的邊(比如C->B),或者這條邊被后續的邊所取代(比如下一步的C->F即將被E->F取代),那么這條邊我們甚至不標注為虛線

而如果在MST中的邊被新邊取代,那么我們把新邊加入MST,原來的邊回到最開始的模樣(不加粗,也不標為虛線)

同時我們看到 Fringe 中的結點是按照到樹的距離進行排序的,同時 distTo 數組也變為了到樹的距離

算法實現

public PrimMST{public PrimMST(EdgeWeightedGraph G){edgeTo = new Edge[G.V()];distTo = new double[G.V()];marked = new boolean[G.V()];fringe = new SpecialPQ<Double>[G.V()];distTo[s] = 0.0;setDDistancesToInfinityExceptS(s);insertAllVertices(fringe);while(!fringe.isEmpty()){int v = fringe.delMin();scan(G,v);}} ....private scan(EdgeWeightedGraph G, int v){marked[v] = true;for(Edge e: G.adj(v)){int w = e.other(v);if(marked[w]){continue;}if(e.weight() < distTo[w]){distTo[w] = e.weight();edgeTo[w] = e;pq.decreasePriority(w, distTo[w]);}}}
}

Kruskal’s Algorithm

按照權重順序考慮所有的邊,只要這條邊加入MST后不構成環,那么就將它加入MST中,重復直到 V-1 條邊

Kruskal 算法計算過程中創造出的MST可能是割裂不連續的,但是沒關系,最后會得出正確的結果

我們可以通過維護兩個輔助數據結構來幫助我們實現:

  • WQU 加權快速集合:幫助我們判斷是否有環生成
  • MST :統計最小生成樹的邊

alt text
在這個圖中我們按順序從 Fringe 中取出對應的邊,當我們即將取出E->B這條邊時,WQU告訴我們已經有了一條從E到B的路徑,也就是下一步即將成環,所以我們不考慮E->B這條邊

算法實現

public class KruskalMST{private List<Edge> mst = new ArrayList<Edge>();public KruskalMST(EdgeWeighedGraph G){MinPQ<Edge> pq = new MinPQ<Edge>();for(Edge e: G.edges()){pq.insert(e);}WeighedQuickUnionPC uf = new WeighedQuickUnionPC(G.V());while(!pq.isEmpty()){Edge e = pq.delMin();int v = e.from();int w = e.to();if(!uf.connected(v,w)){uf.union(v,w);mst.add(e);}}}
}

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

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

相關文章

vue apk返回鍵不好使

在 Android 設備上&#xff0c;你可以通過監聽物理返回鍵來實現特定的邏輯。這可以通過在 Vue 組件中添加一個事件監聽器來實現&#xff1a;mounted() {this.$once(hook:beforeDestroy, () > {if (document.removeEventListener) {document.removeEventListener(backbutton,…

Ubuntu 22.04 安裝 MySQL 8.0 完整步驟文檔

1、安裝 1.1、下載 cd /usr/local/在 /usr/local/ 下執行&#xff0c;下載資源包&#xff0c;可以本地下載上傳 wget https://downloads.mysql.com/archives/get/p/23/file/mysql-8.0.32-linux-glibc2.12-x86_64.tar.xz1.2、解壓安裝 tar -Jxvf mysql-8.0.32-linux-glibc2.…

Docker,其他機器下載鏡像并copy到目標機器導入docker鏡像

Docker&#xff0c;其他機器下載鏡像并copy到目標機器導入docker鏡像源機器 【下載鏡像】目標機器slave1 【無法下載鏡像】步驟 1&#xff1a;在網絡正常的機器&#xff08;cg&#xff09;上下載鏡像&#xff0c;導出鏡像到指定路徑# 1. 下載鏡像docker pull ubuntu:20.04# 2.…

基于現代R語言【Tidyverse、Tidymodel】的機器學習方法與案例分析

機器學習已經成為繼理論、實驗和數值計算之后的科研“第四范式”&#xff0c;是發現新規律&#xff0c;總結和分析實驗結果的利器。機器學習涉及的理論和方法繁多&#xff0c;編程相當復雜&#xff0c;一直是阻礙機器學習大范圍應用的主要困難之一&#xff0c;由此誕生了Python…

如何將 git 遠程 URL 從 https 更改為 ssh

在項目開發中&#xff0c;使用 SSH 連接 Git 倉庫可以提高安全性和便利性。本文將指導你如何將 Git 遠程 URL 從 HTTPS 更改為 SSH。操作指南步驟 1: 查看當前遠程 URL首先&#xff0c;確認當前的遠程 URL 使用的是 https。打開終端并輸入以下命令&#xff1a;git remote -v如&…

PyCharm 高效入門指南(核心模塊詳解二)

四、生產力工具集成PyCharm 不僅僅是 Python 編輯器&#xff0c;更是集成了多種開發工具的綜合平臺。通過內置的生產力工具&#xff0c;開發者可以在一個界面內完成數據庫操作、科學計算、遠程開發和測試等全流程工作&#xff0c;避免工具切換帶來的效率損耗。4.1 數據庫工具鏈…

WebkitSpeechRecognition 語音識別

JavaScript WebkitSpeechRecognition:使用語音識別技術增強 Web 應用程序 WebkitSpeechRecognition 是一種 JavaScript API,它可以讓您的 Web 應用程序使用語音識別技術。使用 WebkitSpeechRecognition,您可以讓用戶通過說話來與您的 Web 應用程序進行交互,這可以使您的應…

CUDA C++核心庫(CCCL)

文章目錄CUDA C核心庫&#xff08;CCCL&#xff09;核心庫介紹CUDA C 開發工具的層級范圍各層級工具的具體內容Thrust自動內存管理類型安全自定義分配器&#xff08;頁鎖定內存&#xff09;高級API替代底層操作thrust::transform基本使用幾種執行策略iteratorload_cs高效索引md…

MySQL InnoDB存儲引擎深度解析:從原理到優化

InnoDB的優勢InnoDB之所以成為眾多應用的首選&#xff0c;主要得益于以下幾個顯著優勢&#xff1a;事務支持&#xff1a;InnoDB是MySQL中唯一支持ACID&#xff08;原子性、一致性、隔離性、持久性&#xff09;事務的存儲引擎。它通過日志和鎖機制確保事務的完整性&#xff0c;這…

LLM評測框架Ragas:Natural Language Comparison指標(解決了Ollama推理框架不支持的問題)

Factural Correctness Factural Correctness是事實正確性是評價LLM生成的反饋和reference的事實正確性。該指標用于確定生成的響應與參考文獻的一致程度。Factural Correctness取值在0到1之間,越接近于1結果越好。 為了衡量回應和參考文獻之間的一致性,該指標使用 LLM 首先將…

HTTP 協議常見字段(請求頭/響應頭)

HTTP&#xff08;HyperText Transfer Protocol&#xff09;協議通過 請求頭&#xff08;Request Headers&#xff09; 和 響應頭&#xff08;Response Headers&#xff09; 傳遞元數據。以下是 最常見的 HTTP 字段 及其作用&#xff1a;1. 通用字段&#xff08;請求和響應均可使…

期貨配資軟件開發注意事項?

期貨配資軟件開發 期貨配資軟件開發涉及多個核心模塊&#xff0c;包括資金管理、風險控制、交易接口、用戶權限管理等。此類系統需符合金融監管要求&#xff0c;確保資金安全與數據合規。開發過程中需優先考慮高并發、低延遲及系統穩定性。期貨資管系統平臺搭建方案架構設計 采…

STM32-第十節-DMA直接存儲器存取

一、DMA&#xff1a;1.簡介&#xff1a;DMA&#xff0c;直接存儲區存取DMA可以提供外設和存儲器或存儲器與存儲器見的高速數據傳輸&#xff0c;無需CPU干預。12個通道&#xff1a;DMA1&#xff08;7個通道&#xff09;&#xff0c;DMA2&#xff08;5個通道&#xff09;每個通道…

服務器設置國外IP無法訪問對防御攻擊有用嗎?

將服務器設置為僅允許國外 IP 訪問&#xff0c;限制國內 IP 訪問&#xff0c;確實可以在某些特定場景下提高服務器的抗攻擊能力&#xff0c;但這并不能完全防御攻擊。以下是對這種方法的分析、優缺點以及其他防御攻擊的補充措施。1. 僅允許國外 IP 訪問是否有用&#xff1f;1.1…

八大作業票(一) 動火安全作業證

動火安全作業證 執行標準:GB30871 GSDH——2200001 申報單位 申請人 作業申請時間 年 月 日 時 分 動火內容 動火方式 動火地點 動火類別 特級動火□ 一級動火□ 二級動火□ 作業負責人 監護人 動火…

NumPy庫使用教學,簡單詳細。

NumPy 使用教學NumPy 是 Python 中用于科學計算的基礎庫&#xff0c;它提供了高性能的多維數組對象以及用于處理這些數組的工具。下面將結合多個代碼文件&#xff0c;詳細介紹 NumPy 的各種用法。1. 創建數組1.1 從列表創建數組import numpy as np# 一維數組 list1 [1,2,3,4,5…

vue3:十八、內容管理-實現行內圖片的預覽、審核功能

一、實現效果 實現圖片的顯示,大圖預覽;審核部分的待審核的審核功能 二、圖片預覽實現 1、參考官網 官網-圖片預覽 2、圖片預覽插槽設置 {row,index} 插槽中獲取row行信息、index索引信息(指定行圖片預覽需要用到) style 設置基本樣式寬width高height src 設置圖片的路徑…

Go后端配置文件教程

注&#xff1a;本文為博主&#xff0c;首次接觸項目時的入門級配置實操在 Go 后端中&#xff0c;使用配置文件管理參數&#xff08;如數據庫連接、服務端口等&#xff09;是必備技能。Viper 是 Go 生態中最流行的配置管理庫。支持多種配置文件、環境變量、命令行參數等&#xf…

ubuntu24.04安裝CUDA、VLLM、Pytorch等并部署Qwen3-8B-AWQ【50系顯卡通用】

1. 系統更新與依賴安裝 sudo apt update && sudo apt upgrade -y sudo apt install -y python3-pip python3-venv build-essential git nvidia-driver-575注:RTX 5070 Ti 推薦驅動 ≥550 版本 我是直接官網安裝最新的驅動了,反正向上兼容,驅動安裝教程可以參考我以…

Azure可靠性架構指南:構建云時代的高可用系統

隨著企業加速擁抱數字化轉型&#xff0c;云服務的可靠性已成為業務連續性的核心命題。Microsoft Azure憑借其"可靠性即核心"的設計理念&#xff0c;為企業技術決策者與架構師提供了一個可信賴的數字化底座。本文將系統解析Azure如何通過技術架構、工具鏈與方法論&…