-
當(dāng)前位置:首頁(yè) > 創(chuàng)意學(xué)院 > 技術(shù) > 專(zhuān)題列表 > 正文
經(jīng)過(guò)所有點(diǎn)的最短路徑算法(經(jīng)過(guò)所有的點(diǎn)求最短的路線)
大家好!今天讓創(chuàng)意嶺的小編來(lái)大家介紹下關(guān)于經(jīng)過(guò)所有點(diǎn)的最短路徑算法的問(wèn)題,以下是小編對(duì)此問(wèn)題的歸納整理,讓我們一起來(lái)看看吧。
開(kāi)始之前先推薦一個(gè)非常厲害的Ai人工智能工具,一鍵生成原創(chuàng)文章、方案、文案、工作計(jì)劃、工作報(bào)告、論文、代碼、作文、做題和對(duì)話答疑等等
只需要輸入關(guān)鍵詞,就能返回你想要的內(nèi)容,越精準(zhǔn),寫(xiě)出的就越詳細(xì),有微信小程序端、在線網(wǎng)頁(yè)版、PC客戶端
官網(wǎng):https://ai.de1919.com。
創(chuàng)意嶺作為行業(yè)內(nèi)優(yōu)秀的企業(yè),服務(wù)客戶遍布全球各地,如需了解SEO相關(guān)業(yè)務(wù)請(qǐng)撥打電話175-8598-2043,或添加微信:1454722008
本文目錄:
一、數(shù)據(jù)結(jié)構(gòu)之圖:求所有節(jié)點(diǎn)之間的最短路徑,用什么算法時(shí)間復(fù)雜度?。壳蟠鸢概c解釋
兩者時(shí)間復(fù)雜度一般都是O(n3),但對(duì)于稀疏圖來(lái)說(shuō)重復(fù)使用Dijkstra方法比較好!
Dijkstra算法時(shí)間復(fù)雜度為O(V*V+E),可以用優(yōu)先隊(duì)列進(jìn)行優(yōu)化,優(yōu)化后時(shí)間復(fù)雜
度變?yōu)?(v*lgn)。
源點(diǎn)可達(dá)的話,O(V*lgV+E*lgV)=>O(E*lgV)。
當(dāng)是稀疏圖的情況時(shí),此時(shí)E=V*V/lgV,所以算法的時(shí)間復(fù)雜度可為O(V^2) ??梢杂脙?yōu)先隊(duì)列進(jìn)行優(yōu)化,優(yōu)化后時(shí)間復(fù)雜度變?yōu)?(v*lgn)。
具體詳細(xì)解釋你可以看看這個(gè)http://blog.chinaunix.net/uid-27164517-id-3287891.html。
二、最短路徑 | 深入淺出Dijkstra算法(一)
上次我們介紹了神奇的只有 五行的 Floyd-Warshall 最短路算法 ,它可以方便的求得 任意兩點(diǎn)的最短路徑, 這稱(chēng)為 “多源最短路”。
這次來(lái)介紹 指定一個(gè)點(diǎn)(源點(diǎn))到其余各個(gè)頂點(diǎn)的最短路徑, 也叫做 “單源最短路徑”。 例如求下圖中的 1 號(hào)頂點(diǎn)到 2、3、4、5、6 號(hào)頂點(diǎn)的最短路徑。
與 Floyd-Warshall 算法一樣,這里仍然 使用二維數(shù)組 e 來(lái)存儲(chǔ)頂點(diǎn)之間邊的關(guān)系, 初始值如下。
我們還需要用 一個(gè)一維數(shù)組 dis 來(lái)存儲(chǔ) 1 號(hào)頂點(diǎn)到其余各個(gè)頂點(diǎn)的初始路程, 我們可以稱(chēng) dis 數(shù)組為 “距離表”, 如下。
我們將此時(shí) dis 數(shù)組中的值稱(chēng)為 最短路的“估計(jì)值”。
既然是 求 1 號(hào)頂點(diǎn)到其余各個(gè)頂點(diǎn)的最短路程, 那就 先找一個(gè)離 1 號(hào)頂點(diǎn)最近的頂點(diǎn)。
通過(guò)數(shù)組 dis 可知當(dāng)前離 1 號(hào)頂點(diǎn)最近是 2 號(hào)頂點(diǎn)。 當(dāng)選擇了 2 號(hào)頂點(diǎn)后,dis[2]的值就已經(jīng)從“估計(jì)值”變?yōu)榱恕按_定值”, 即 1 號(hào)頂點(diǎn)到 2 號(hào)頂點(diǎn)的最短路程就是當(dāng)前 dis[2]值。
為什么呢?你想啊, 目前離 1 號(hào)頂點(diǎn)最近的是 2 號(hào)頂點(diǎn),并且這個(gè)圖所有的邊都是正數(shù),那么肯定不可能通過(guò)第三個(gè)頂點(diǎn)中轉(zhuǎn),使得 1 號(hào)頂點(diǎn)到 2 號(hào)頂點(diǎn)的路程進(jìn)一步縮短了。 因此 1 號(hào)頂點(diǎn)到其它頂點(diǎn)的路程肯定沒(méi)有 1 號(hào)到 2 號(hào)頂點(diǎn)短,對(duì)吧 O(∩_∩)O~
既然選了 2 號(hào)頂點(diǎn),接下來(lái)再來(lái)看 2 號(hào)頂點(diǎn) 有哪些 出邊 呢。有 2->3 和 2->4 這兩條邊。
先討論 通過(guò) 2->3 這條邊能否讓 1 號(hào)頂點(diǎn)到 3 號(hào)頂點(diǎn)的路程變短。 也就是說(shuō)現(xiàn)在來(lái)比較 dis[3] 和 dis[2]+e[2][3] 的大小。其中 dis[3]表示 1 號(hào)頂點(diǎn)到 3 號(hào)頂點(diǎn)的路程,dis[2]+e[2][3]中 dis[2]表示 1 號(hào)頂點(diǎn)到 2 號(hào)頂點(diǎn)的路程,e[2][3]表示 2->3 這條邊。所以 dis[2]+e[2][3]就表示從 1 號(hào)頂點(diǎn)先到 2 號(hào)頂點(diǎn),再通過(guò) 2->3 這條邊,到達(dá) 3 號(hào)頂點(diǎn)的路程。
我們發(fā)現(xiàn) dis[3]=12,dis[2]+e[2][3]=1+9=10,dis[3]>dis[2]+e[2][3],因此 dis[3]要更新為 10。這個(gè)過(guò)程有個(gè)專(zhuān)業(yè)術(shù)語(yǔ)叫做 “松弛” 。即 1 號(hào)頂點(diǎn)到 3 號(hào)頂點(diǎn)的路程即 dis[3],通過(guò) 2->3 這條邊 松弛成功。 這便是 Dijkstra 算法的主要思想: 通過(guò) “邊” 來(lái)松弛 1 號(hào)頂點(diǎn)到其余各個(gè)頂點(diǎn)的路程。
同理通過(guò) 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)。
剛才我們對(duì) 2 號(hào)頂點(diǎn)所有的出邊進(jìn)行了松弛。松弛完畢之后 dis 數(shù)組為:
接下來(lái),繼續(xù)在剩下的 3、4、5 和 6 號(hào)頂點(diǎn)中,選出離 1 號(hào)頂點(diǎn)最近的頂點(diǎn)。通過(guò)上面更新過(guò) dis 數(shù)組,當(dāng)前離 1 號(hào)頂點(diǎn)最近是 4 號(hào)頂點(diǎn)。此時(shí),dis[4]的值已經(jīng)從“估計(jì)值”變?yōu)榱恕按_定值”。下面繼續(xù)對(duì) 4 號(hào)頂點(diǎn)的所有出邊(4->3,4->5 和 4->6)用剛才的方法進(jìn)行松弛。松弛完畢之后 dis 數(shù)組為:
繼續(xù)在剩下的 3、5 和 6 號(hào)頂點(diǎn)中,選出離 1 號(hào)頂點(diǎn)最近的頂點(diǎn),這次選擇 3 號(hào)頂點(diǎn)。此時(shí),dis[3]的值已經(jīng)從“估計(jì)值”變?yōu)榱恕按_定值”。對(duì) 3 號(hào)頂點(diǎn)的所有出邊(3->5)進(jìn)行松弛。松弛完畢之后 dis 數(shù)組為:
繼續(xù)在剩下的 5 和 6 號(hào)頂點(diǎn)中,選出離 1 號(hào)頂點(diǎn)最近的頂點(diǎn),這次選擇 5 號(hào)頂點(diǎn)。此時(shí),dis[5]的值已經(jīng)從“估計(jì)值”變?yōu)榱恕按_定值”。對(duì)5號(hào)頂點(diǎn)的所有出邊(5->4)進(jìn)行松弛。松弛完畢之后 dis 數(shù)組為:
最后對(duì) 6 號(hào)頂點(diǎn)的所有出邊進(jìn)行松弛。因?yàn)檫@個(gè)例子中 6 號(hào)頂點(diǎn)沒(méi)有出邊,因此不用處理。 到此,dis 數(shù)組中所有的值都已經(jīng)從“估計(jì)值”變?yōu)榱恕按_定值”。
最終 dis 數(shù)組如下,這便是 1 號(hào)頂點(diǎn)到其余各個(gè)頂點(diǎn)的最短路徑。
OK,現(xiàn)在來(lái)總結(jié)一下剛才的算法。 Dijkstra算法的基本思想是:每次找到離源點(diǎn)(上面例子的源點(diǎn)就是 1 號(hào)頂點(diǎn))最近的一個(gè)頂點(diǎn),然后以該頂點(diǎn)為中心進(jìn)行擴(kuò)展,最終得到源點(diǎn)到其余所有點(diǎn)的最短路徑。
基本步驟如下:
在 博客 中看到兩個(gè)比較有趣的問(wèn)題,也是在學(xué)習(xí)Dijkstra時(shí),可能會(huì)有疑問(wèn)的問(wèn)題。
當(dāng)我們看到上面這個(gè)圖的時(shí)候,憑借多年對(duì)平面幾何的學(xué)習(xí),會(huì)發(fā)現(xiàn)在“三角形ABC”中,滿足不了 構(gòu)成三角形的條件(任意兩邊之和大于第三邊)。 納尼,那為什么圖中能那樣子畫(huà)?
還是“三角形ABC”,以A為起點(diǎn),B為終點(diǎn),如果按照平面幾何的知識(shí), “兩點(diǎn)之間線段最短”, 那么,A到B的最短距離就應(yīng)該是6(線段AB),但是,實(shí)際上A到B的最短距離卻是3+2=5。這又怎么解釋?zhuān)?/p>
其實(shí),之所以會(huì)有上面的疑問(wèn),是因?yàn)?strong> 對(duì)邊的權(quán)值和邊的長(zhǎng)度這兩個(gè)概念的混淆, 。之所以這樣畫(huà),也只是為了方便理解(每個(gè)人寫(xiě)草稿的方式不同,你完全可以用別的方式表示,只要便于你理解即可)。
PS:數(shù)組實(shí)現(xiàn)鄰接表可能較難理解,可以看一下 這里
參考資料:
Dijkstra算法是一種基于貪心策略的算法。每次新擴(kuò)展一個(gè)路程最短的點(diǎn),更新與其相鄰的點(diǎn)的路程。當(dāng)所有邊權(quán)都為正時(shí),由于不會(huì)存在一個(gè)路程更短的沒(méi)擴(kuò)展過(guò)的點(diǎn),所以這個(gè)點(diǎn)的路程永遠(yuǎn)不會(huì)再被改變,因而保證了算法的正確性。
根據(jù)這個(gè)原理, 用Dijkstra算法求最短路徑的圖不能有負(fù)權(quán)邊, 因?yàn)閿U(kuò)展到負(fù)權(quán)邊的時(shí)候會(huì)產(chǎn)生更短的路徑,有可能破壞了已經(jīng)更新的點(diǎn)路徑不會(huì)發(fā)生改變的性質(zhì)。
那么,有沒(méi)有可以求帶負(fù)權(quán)邊的指定頂點(diǎn)到其余各個(gè)頂點(diǎn)的最短路徑算法(即“單源最短路徑”問(wèn)題)呢?答案是有的, Bellman-Ford算法 就是一種。(我們已經(jīng)知道了 Floyd-Warshall 可以解決“多源最短路”問(wèn)題,也要求圖的邊權(quán)均為正)
通過(guò) 鄰接矩陣 的Dijkstra時(shí)間復(fù)雜度是 。其中每次找到離 1 號(hào)頂點(diǎn)最近的頂點(diǎn)的時(shí)間復(fù)雜度是 O(N),這里我們可以用 優(yōu)先隊(duì)列(堆) 來(lái)優(yōu)化,使得這一部分的時(shí)間復(fù)雜度降低到 。這個(gè)我們將在后面討論。
三、圖遍歷算法之最短路徑Dijkstra算法
最短路徑問(wèn)題是圖論研究中一個(gè)經(jīng)典算法問(wèn)題,旨在尋找圖中兩節(jié)點(diǎn)或單個(gè)節(jié)點(diǎn)到其他節(jié)點(diǎn)之間的最短路徑。根據(jù)問(wèn)題的不同,算法的具體形式包括:
常用的最短路徑算法包括:Dijkstra算法,A 算法,Bellman-Ford算法,SPFA算法(Bellman-Ford算法的改進(jìn)版本),F(xiàn)loyd-Warshall算法,Johnson算法以及Bi-direction BFS算法。本文將重點(diǎn)介紹Dijkstra算法的原理以及實(shí)現(xiàn)。
Dijkstra算法,翻譯作戴克斯特拉算法或迪杰斯特拉算法,于1956年由荷蘭計(jì)算機(jī)科學(xué)家艾茲赫爾.戴克斯特拉提出,用于解決賦權(quán)有向圖的 單源最短路徑問(wèn)題 。所謂單源最短路徑問(wèn)題是指確定起點(diǎn),尋找該節(jié)點(diǎn)到圖中任意節(jié)點(diǎn)的最短路徑,算法可用于尋找兩個(gè)城市中的最短路徑或是解決著名的旅行商問(wèn)題。
問(wèn)題描述 :在無(wú)向圖 中, 為圖節(jié)點(diǎn)的集合, 為節(jié)點(diǎn)之間連線邊的集合。假設(shè)每條邊 的權(quán)重為 ,找到由頂點(diǎn) 到其余各個(gè)節(jié)點(diǎn)的最短路徑(單源最短路徑)。
為帶權(quán)無(wú)向圖,圖中頂點(diǎn) 分為兩組,第一組為已求出最短路徑的頂點(diǎn)集合(用 表示)。初始時(shí) 只有源點(diǎn),當(dāng)求得一條最短路徑時(shí),便將新增頂點(diǎn)添加進(jìn) ,直到所有頂點(diǎn)加入 中,算法結(jié)束。第二組為未確定最短路徑頂點(diǎn)集合(用 表示),隨著 中頂點(diǎn)增加, 中頂點(diǎn)逐漸減少。
以下圖為例,對(duì)Dijkstra算法的工作流程進(jìn)行演示(以頂點(diǎn) 為起點(diǎn)):
注:
01) 是已計(jì)算出最短路徑的頂點(diǎn)集合;
02) 是未計(jì)算出最短路徑的頂點(diǎn)集合;
03) 表示頂點(diǎn) 到頂點(diǎn) 的最短距離為3
第1步 :選取頂點(diǎn) 添加進(jìn)
第2步 :選取頂點(diǎn) 添加進(jìn) ,更新 中頂點(diǎn)最短距離
第3步 :選取頂點(diǎn) 添加進(jìn) ,更新 中頂點(diǎn)最短距離
第4步 :選取頂點(diǎn) 添加進(jìn) ,更新 中頂點(diǎn)最短距離
第5步 :選取頂點(diǎn) 添加進(jìn) ,更新 中頂點(diǎn)最短距離
第6步 :選取頂點(diǎn) 添加進(jìn) ,更新 中頂點(diǎn)最短距離
第7步 :選取頂點(diǎn) 添加進(jìn) ,更新 中頂點(diǎn)最短距離
示例:node編號(hào)1-7分別代表A,B,C,D,E,F,G
(s.paths <- shortest.paths(g, algorithm = "dijkstra"))輸出結(jié)果:
(s.paths <- shortest.paths(g,4, algorithm = "dijkstra"))輸出結(jié)果:
示例:
找到D(4)到G(7)的最短路徑:
[1] 維基百科,最短路徑問(wèn)題: https://zh.wikipedia.org/wiki/%E6%9C%80%E7%9F%AD%E8%B7%AF%E9%97%AE%E9%A2%98 ;
[2]CSDN,Dijkstra算法原理: https://blog.csdn.net/yalishadaa/article/details/55827681 ;
[3]RDocumentation: https://www.rdocumentation.org/packages/RNeo4j/versions/1.6.4/topics/dijkstra ;
[4]RDocumentation: https://www.rdocumentation.org/packages/igraph/versions/0.1.1/topics/shortest.paths ;
[5]Pypi: https://pypi.org/project/Dijkstar/
四、最短路Dijkstra算法怎么求起點(diǎn)到終點(diǎn)經(jīng)過(guò)的路程,就是把經(jīng)過(guò)的每個(gè)點(diǎn)都顯示出來(lái),用c和c++都可,大牛來(lái)吧
是要怎么顯示,你的源程序里面已經(jīng)可以顯示經(jīng)過(guò)的所有點(diǎn)了
以上就是關(guān)于經(jīng)過(guò)所有點(diǎn)的最短路徑算法相關(guān)問(wèn)題的回答。希望能幫到你,如有更多相關(guān)問(wèn)題,您也可以聯(lián)系我們的客服進(jìn)行咨詢(xún),客服也會(huì)為您講解更多精彩的知識(shí)和內(nèi)容。
推薦閱讀:
從廣州到杭州的高鐵(從廣州到杭州的高鐵有經(jīng)過(guò)武漢的嗎)
平臺(tái)未經(jīng)過(guò)本人同意退款(平臺(tái)未經(jīng)過(guò)本人同意退款違法嗎)
從杭州到上海都經(jīng)過(guò)哪些站(從杭州到上海都經(jīng)過(guò)哪些站臺(tái))
武漢餐飲品牌設(shè)計(jì)分析(武漢餐飲品牌設(shè)計(jì)分析論文)
猜你喜歡
谷歌網(wǎng)頁(yè)版網(wǎng)址(谷歌網(wǎng)頁(yè)網(wǎng)址是什么)
怎么查看以前看過(guò)的網(wǎng)站(怎么查看以前看過(guò)的網(wǎng)站記錄)
購(gòu)買(mǎi)電腦系統(tǒng)(購(gòu)買(mǎi)電腦系統(tǒng)多少錢(qián))
谷歌是哪個(gè)國(guó)家的企業(yè)(谷歌是哪個(gè)國(guó)家的企業(yè)公司)
電腦網(wǎng)頁(yè)打開(kāi)很慢是怎么解決(電腦網(wǎng)頁(yè)打開(kāi)很慢是怎么解決呢)
百度數(shù)據(jù)平臺(tái)(百度數(shù)據(jù)平臺(tái)怎么兼職)