-
當前位置:首頁 > 創(chuàng)意學院 > 技術 > 專題列表 > 正文
最短路徑算法有哪些(最短路徑算法總結)
大家好!今天讓創(chuàng)意嶺的小編來大家介紹下關于最短路徑算法有哪些的問題,以下是小編對此問題的歸納整理,讓我們一起來看看吧。
開始之前先推薦一個非常厲害的Ai人工智能工具,一鍵生成原創(chuàng)文章、方案、文案、工作計劃、工作報告、論文、代碼、作文、做題和對話答疑等等
只需要輸入關鍵詞,就能返回你想要的內容,越精準,寫出的就越詳細,有微信小程序端、在線網(wǎng)頁版、PC客戶端
官網(wǎng):https://ai.de1919.com。
創(chuàng)意嶺作為行業(yè)內優(yōu)秀的企業(yè),服務客戶遍布全球各地,如需了解SEO相關業(yè)務請撥打電話175-8598-2043,或添加微信:1454722008
本文目錄:
一、權圖中求最短路徑都有哪些算法?
帶權圖也分有向和無向兩種,基本的算法可以看看書咯。
帶權的無向圖的最短路徑又叫最小生成樹,Prim算法和Kruskal算法;
帶權的有向圖的最短路徑算法有迪杰斯特拉算法和佛洛依德算法;
二、最短路徑 | 深入淺出Dijkstra算法(一)
上次我們介紹了神奇的只有 五行的 Floyd-Warshall 最短路算法 ,它可以方便的求得 任意兩點的最短路徑, 這稱為 “多源最短路”。
這次來介紹 指定一個點(源點)到其余各個頂點的最短路徑, 也叫做 “單源最短路徑”。 例如求下圖中的 1 號頂點到 2、3、4、5、6 號頂點的最短路徑。
與 Floyd-Warshall 算法一樣,這里仍然 使用二維數(shù)組 e 來存儲頂點之間邊的關系, 初始值如下。
我們還需要用 一個一維數(shù)組 dis 來存儲 1 號頂點到其余各個頂點的初始路程, 我們可以稱 dis 數(shù)組為 “距離表”, 如下。
我們將此時 dis 數(shù)組中的值稱為 最短路的“估計值”。
既然是 求 1 號頂點到其余各個頂點的最短路程, 那就 先找一個離 1 號頂點最近的頂點。
通過數(shù)組 dis 可知當前離 1 號頂點最近是 2 號頂點。 當選擇了 2 號頂點后,dis[2]的值就已經(jīng)從“估計值”變?yōu)榱恕按_定值”, 即 1 號頂點到 2 號頂點的最短路程就是當前 dis[2]值。
為什么呢?你想啊, 目前離 1 號頂點最近的是 2 號頂點,并且這個圖所有的邊都是正數(shù),那么肯定不可能通過第三個頂點中轉,使得 1 號頂點到 2 號頂點的路程進一步縮短了。 因此 1 號頂點到其它頂點的路程肯定沒有 1 號到 2 號頂點短,對吧 O(∩_∩)O~
既然選了 2 號頂點,接下來再來看 2 號頂點 有哪些 出邊 呢。有 2->3 和 2->4 這兩條邊。
先討論 通過 2->3 這條邊能否讓 1 號頂點到 3 號頂點的路程變短。 也就是說現(xiàn)在來比較 dis[3] 和 dis[2]+e[2][3] 的大小。其中 dis[3]表示 1 號頂點到 3 號頂點的路程,dis[2]+e[2][3]中 dis[2]表示 1 號頂點到 2 號頂點的路程,e[2][3]表示 2->3 這條邊。所以 dis[2]+e[2][3]就表示從 1 號頂點先到 2 號頂點,再通過 2->3 這條邊,到達 3 號頂點的路程。
我們發(fā)現(xiàn) dis[3]=12,dis[2]+e[2][3]=1+9=10,dis[3]>dis[2]+e[2][3],因此 dis[3]要更新為 10。這個過程有個專業(yè)術語叫做 “松弛” 。即 1 號頂點到 3 號頂點的路程即 dis[3],通過 2->3 這條邊 松弛成功。 這便是 Dijkstra 算法的主要思想: 通過 “邊” 來松弛 1 號頂點到其余各個頂點的路程。
同理通過 2->4(e[2][4]),可以將 dis[4]的值從 ∞ 松弛為 4(dis[4]初始為 ∞,dis[2]+e[2][4]=1+3=4,dis[4]>dis[2]+e[2][4],因此 dis[4]要更新為 4)。
剛才我們對 2 號頂點所有的出邊進行了松弛。松弛完畢之后 dis 數(shù)組為:
接下來,繼續(xù)在剩下的 3、4、5 和 6 號頂點中,選出離 1 號頂點最近的頂點。通過上面更新過 dis 數(shù)組,當前離 1 號頂點最近是 4 號頂點。此時,dis[4]的值已經(jīng)從“估計值”變?yōu)榱恕按_定值”。下面繼續(xù)對 4 號頂點的所有出邊(4->3,4->5 和 4->6)用剛才的方法進行松弛。松弛完畢之后 dis 數(shù)組為:
繼續(xù)在剩下的 3、5 和 6 號頂點中,選出離 1 號頂點最近的頂點,這次選擇 3 號頂點。此時,dis[3]的值已經(jīng)從“估計值”變?yōu)榱恕按_定值”。對 3 號頂點的所有出邊(3->5)進行松弛。松弛完畢之后 dis 數(shù)組為:
繼續(xù)在剩下的 5 和 6 號頂點中,選出離 1 號頂點最近的頂點,這次選擇 5 號頂點。此時,dis[5]的值已經(jīng)從“估計值”變?yōu)榱恕按_定值”。對5號頂點的所有出邊(5->4)進行松弛。松弛完畢之后 dis 數(shù)組為:
最后對 6 號頂點的所有出邊進行松弛。因為這個例子中 6 號頂點沒有出邊,因此不用處理。 到此,dis 數(shù)組中所有的值都已經(jīng)從“估計值”變?yōu)榱恕按_定值”。
最終 dis 數(shù)組如下,這便是 1 號頂點到其余各個頂點的最短路徑。
OK,現(xiàn)在來總結一下剛才的算法。 Dijkstra算法的基本思想是:每次找到離源點(上面例子的源點就是 1 號頂點)最近的一個頂點,然后以該頂點為中心進行擴展,最終得到源點到其余所有點的最短路徑。
基本步驟如下:
在 博客 中看到兩個比較有趣的問題,也是在學習Dijkstra時,可能會有疑問的問題。
當我們看到上面這個圖的時候,憑借多年對平面幾何的學習,會發(fā)現(xiàn)在“三角形ABC”中,滿足不了 構成三角形的條件(任意兩邊之和大于第三邊)。 納尼,那為什么圖中能那樣子畫?
還是“三角形ABC”,以A為起點,B為終點,如果按照平面幾何的知識, “兩點之間線段最短”, 那么,A到B的最短距離就應該是6(線段AB),但是,實際上A到B的最短距離卻是3+2=5。這又怎么解釋?
其實,之所以會有上面的疑問,是因為 對邊的權值和邊的長度這兩個概念的混淆, 。之所以這樣畫,也只是為了方便理解(每個人寫草稿的方式不同,你完全可以用別的方式表示,只要便于你理解即可)。
PS:數(shù)組實現(xiàn)鄰接表可能較難理解,可以看一下 這里
參考資料:
Dijkstra算法是一種基于貪心策略的算法。每次新擴展一個路程最短的點,更新與其相鄰的點的路程。當所有邊權都為正時,由于不會存在一個路程更短的沒擴展過的點,所以這個點的路程永遠不會再被改變,因而保證了算法的正確性。
根據(jù)這個原理, 用Dijkstra算法求最短路徑的圖不能有負權邊, 因為擴展到負權邊的時候會產(chǎn)生更短的路徑,有可能破壞了已經(jīng)更新的點路徑不會發(fā)生改變的性質。
那么,有沒有可以求帶負權邊的指定頂點到其余各個頂點的最短路徑算法(即“單源最短路徑”問題)呢?答案是有的, Bellman-Ford算法 就是一種。(我們已經(jīng)知道了 Floyd-Warshall 可以解決“多源最短路”問題,也要求圖的邊權均為正)
通過 鄰接矩陣 的Dijkstra時間復雜度是 。其中每次找到離 1 號頂點最近的頂點的時間復雜度是 O(N),這里我們可以用 優(yōu)先隊列(堆) 來優(yōu)化,使得這一部分的時間復雜度降低到 。這個我們將在后面討論。
三、矩陣乘法求最短路徑
們把求A →E 的最短路分解為四個階段A →B →C→D →E 來求解.每一個階段可以用一個矩陣來表示,這個矩陣稱為權矩陣.相鄰階段的路徑可以用權矩陣的乘積來表示.但這里的矩陣乘法和普通矩陣乘積運算的區(qū)別是:普通矩陣乘積其對應元素是相應元素乘積的代數(shù)和,這里把元素相乘改為相加,元素的代數(shù)和改為取小運算,如果不同層節(jié)點間沒有連接,則視它們之間的距離為無窮大. 如果是求極大,改為取大運算,此時如果不同層節(jié)點間沒有連接,則視它們的距離為0.
如下:
由A地到B地的距離可表示為:A[2 5 8]
由B地到C地的權矩陣可表示為
[3,6,5;7,10,8;4,9,6]
因此由A到C的權矩陣為[2,5,8][3,6,5;7,10,8;4,9,6]=[5,8,7]
因此由A到D的權矩陣為[5,8,7)][7,5;3,4;5,2]=[11 ,9]
由A→E的權矩陣為:[11 ,9][4,2)]=[15,11]
因此從家里到學校的最短距離為11百米,最近的路徑為從A地出發(fā)經(jīng)過B1地C1地D2地到達E地.
下面我們給出基于“矩陣乘法”求解最短路的算法:
第一階段:計算出圖中從起始點到終點最短路的長度.
step1 劃分出該網(wǎng)絡圖中的層次關系(網(wǎng)絡劃分為N 層,起點為第一層,終點為第N 層) ;
step2 依次給出從第i 層到第i + 1 層的權矩陣( i= 1 ,2 , …, N21) ; (若第i 層有m 個頂點;第i + 1 層有n
個頂點, 則從第i 層到第i + 1 層的權矩陣為m *n
階) .
step3 按照我們定義的矩陣乘法計算出最短路的
數(shù)值.
第二階段:尋找最短路所經(jīng)過的中間點.
(利用第一階段中step2 的數(shù)據(jù)) 計算出從第i 層到
終點的最短路, 對比與i21 層到終點的最短路, 從而確
定出第i 層上最短路所經(jīng)過的頂點( i = 2 , …, N21) .
四、最短路徑 - Dijkstra算法
算法每次都查找距離起始點最近的點,那么剩下的點距離起始點的距離一定比當前點大。
1.選定A節(jié)點并初始化,如上述步驟3所示
2.執(zhí)行上述 4、5兩步驟,找出U集合中路徑最短的節(jié)點D 加入S集合,并根據(jù)條件 if ( 'D 到 B,C,E 的距離' + 'AD 距離' < 'A 到 B,C,E 的距離' ) 來更新U集合
3.這時候 A->B, A->C 都為3,沒關系。其實這時候他倆都是最短距離,如果從算法邏輯來講的話,會先取到B點。而這個時候 if 條件變成了 if ( 'B 到 C,E 的距離' + 'AB 距離' < 'A 到 C,E 的距離' ) ,如圖所示這時候A->B距離 其實為 A->D->B
思路就是這樣,往后就是大同小異了
算法結束
(圖片來源于網(wǎng)絡)
Dijkstra算法保證能找到一條從初始點到目標點的最短路徑,只要所有的邊都有一個非負的代價值。在上圖中,粉紅色的結點是初始結點,藍色的是目標點,而類菱形的有色區(qū)域則是Dijkstra算法掃描過的區(qū)域。顏色最淡的區(qū)域是那些離初始點最遠的,因而形成探測過程(exploration)的邊境(frontier)。因而Dijkstra算法可以找到一條最短的路徑,但是效率上并不高。
數(shù)據(jù)結構--Dijkstra算法最清楚的講解
以上就是關于最短路徑算法有哪些相關問題的回答。希望能幫到你,如有更多相關問題,您也可以聯(lián)系我們的客服進行咨詢,客服也會為您講解更多精彩的知識和內容。
推薦閱讀:
普陀區(qū)庭院景觀設計效果圖(普陀區(qū)庭院景觀設計效果圖片)