-
當(dāng)前位置:首頁 > 創(chuàng)意學(xué)院 > 技術(shù) > 專題列表 > 正文
圖最短路徑算法
大家好!今天讓創(chuàng)意嶺的小編來大家介紹下關(guān)于圖最短路徑算法的問題,以下是小編對此問題的歸納整理,讓我們一起來看看吧。
開始之前先推薦一個非常厲害的Ai人工智能工具,一鍵生成原創(chuàng)文章、方案、文案、工作計劃、工作報告、論文、代碼、作文、做題和對話答疑等等
只需要輸入關(guān)鍵詞,就能返回你想要的內(nèi)容,越精準(zhǔn),寫出的就越詳細(xì),有微信小程序端、在線網(wǎng)頁版、PC客戶端
官網(wǎng):https://ai.de1919.com。
創(chuàng)意嶺作為行業(yè)內(nèi)優(yōu)秀的企業(yè),服務(wù)客戶遍布全球各地,如需了解SEO相關(guān)業(yè)務(wù)請撥打電話175-8598-2043,或添加微信:1454722008
本文目錄:
一、求解:圖論中常見的最短路徑算法有幾種?都是什么?
算法 Algorithm
算法是在有限步驟內(nèi)求解某一問題所使用的一組定義明確的規(guī)則。通俗點說,就是計算機解題的過程。在這個過程中,無論是形成解題思路還是編寫程序,都是在實施某種算法。前者是推理實現(xiàn)的算法,后者是操作實現(xiàn)的算法。
一個算法應(yīng)該具有以下五個重要的特征:
1、有窮性: 一個算法必須保證執(zhí)行有限步之后結(jié)束;
2、確切性: 算法的每一步驟必須有確切的定義;
3、輸入:一個算法有0個或多個輸入,以刻畫運算對象的初始情況,所謂0個輸入是指算法本身定除了初始條件;
4、輸出:一個算法有一個或多個輸出,以反映對輸入數(shù)據(jù)加工后的結(jié)果。沒有輸出的算法是毫無意義的;
5、可行性: 算法原則上能夠精確地運行,而且人們用筆和紙做有限次運算后即可完成。
算法的設(shè)計要求
1)正確性(Correctness)
有4個層次:
A.程序不含語法錯誤;
B.程序?qū)捉M輸入數(shù)據(jù)能夠得出滿足規(guī)格要求的結(jié)果;
C.程序?qū)倪x擇的、典型的、苛刻的、帶有刁難性的幾組輸入數(shù)據(jù)能夠得出滿足規(guī)格要求的結(jié)果;
D.程序?qū)σ磺泻戏ǖ妮斎霐?shù)據(jù)都能產(chǎn)生滿足規(guī)格要求的結(jié)果。
2)可讀性(Readability)
算法的第一目的是為了閱讀和交流;
可讀性有助于對算法的理解;
可讀性有助于對算法的調(diào)試和修改。
3)高效率與低存儲量
處理速度快;存儲容量小
時間和空間是矛盾的、實際問題的求解往往是求得時間和空間的統(tǒng)一、折中。
算法的描述 算法的描述方式(常用的)
算法描述 自然語言
流程圖 特定的表示算法的圖形符號
偽語言 包括程序設(shè)計語言的三大基本結(jié)構(gòu)及自然語言的一種語言
類語言 類似高級語言的語言,例如,類PASCAL、類C語言。
算法的評價 算法評價的標(biāo)準(zhǔn):時間復(fù)雜度和空間復(fù)雜度。
1)時間復(fù)雜度 指在計算機上運行該算法所花費的時間。用“O(數(shù)量級)”來表示,稱為“階”。
常見的時間復(fù)雜度有: O(1)常數(shù)階;O(logn)對數(shù)階;O(n)線性階;O(n^2)平方階
2)空間復(fù)雜度 指算法在計算機上運行所占用的存儲空間。度量同時間復(fù)雜度。
時間復(fù)雜度舉例
(a) X:=X+1 ; O(1)
(b) FOR I:=1 TO n DO
X:= X+1; O(n)
(c) FOR I:= 1 TO n DO
FOR J:= 1 TO n DO
X:= X+1; O(n^2)
“算法”一詞最早來自公元 9世紀(jì) 波斯數(shù)學(xué)家比阿勒·霍瓦里松的一本影響深遠(yuǎn)的著作《代數(shù)對話錄》。20世紀(jì)的 英國 數(shù)學(xué)家 圖靈 提出了著名的圖靈論點,并抽象出了一臺機器,這臺機器被我們稱之為 圖靈機 。圖靈的思想對算法的發(fā)展起到了重要的作用。
算法是 計算機 處理信息的本質(zhì),因為 計算機程序 本質(zhì)上是一個算法,告訴計算機確切的步驟來執(zhí)行一個指定的任務(wù),如計算職工的薪水或打印學(xué)生的成績單。 一般地,當(dāng)算法在處理信息時,數(shù)據(jù)會從輸入設(shè)備讀取,寫入輸出設(shè)備,可能保存起來以供以后使用。
這是算法的一個簡單的例子。
我們有一串隨機數(shù)列。我們的目的是找到這個數(shù)列中最大的數(shù)。如果將數(shù)列中的每一個數(shù)字看成是一顆豆子的大小 可以將下面的算法形象地稱為“撿豆子”:
首先將第一顆豆子(數(shù)列中的第一個數(shù)字)放入口袋中。
從第二顆豆子開始檢查,直到最后一顆豆子。如果正在檢查的豆子比口袋中的還大,則將它撿起放入口袋中,同時丟掉原先的豆子。 最后口袋中的豆子就是所有的豆子中最大的一顆。
下面是一個形式算法,用近似于 編程語言 的 偽代碼 表示
給定:一個數(shù)列“l(fā)ist",以及數(shù)列的長度"length(list)" largest = list[1] for counter = 2 to length(list): if list[counter] > largest: largest = list[counter] print largest
符號說明:
= 用于表示賦值。即:右邊的值被賦予給左邊的變量。
List[counter] 用于表示數(shù)列中的第 counter 項。例如:如果 counter 的值是5,那么 List[counter] 表示數(shù)列中的第5項。
<= 用于表示“小于或等于”。
算法的分類
(一)基本算法 :
1.枚舉
2.搜索:
深度優(yōu)先搜索
廣度優(yōu)先搜索
啟發(fā)式搜索
遺傳算法
(二)數(shù)據(jù)結(jié)構(gòu)的算法
(三)數(shù)論與代數(shù)算法
(四)計算幾何的算法:求凸包
(五)圖論 算法:
1.哈夫曼編碼
2.樹的遍歷
3.最短路徑 算法
4.最小生成樹 算法
5.最小樹形圖
6.網(wǎng)絡(luò)流 算法
7.匹配算法
(六)動態(tài)規(guī)劃
(七)其他:
1.數(shù)值分析
2.加密算法
3.排序 算法
4.檢索算法
5.隨機化算法
二、圖文解析 | Dijkstra單源最短路徑算法
給定 加權(quán)有向圖 G=(V,E,W),每條邊的權(quán)值w為 非負(fù)數(shù) ,表示兩個頂點間的距離。
源點s∈V。
求:從s出發(fā)到其他各個頂點的最短路徑。
如上圖所示,以1為源點,計算到其余各個頂點的最短距離(我已用紅線標(biāo)出)。下面列出了最終解:
S集合 :當(dāng)從s到x(x ∈V )的最短路徑找到時,則x ∈S。當(dāng)所有頂點都進(jìn)入S集合時,算法結(jié)束。
初始:S={s},當(dāng)S=V時算法結(jié)束。
從s到u相對于S的最短路徑 :指從s到u且僅經(jīng)過S中頂點的最短路徑。
dist[u]:從s到u相對于S的最短路徑長度
short[u]:從s到u最短路徑的長度(算法最終解)
dist[u] ≥ short[u]
Dijkstra算法采用貪心算法模式,算法過程就是通過計算dist[u],不斷擴充S集合,同時dist[u]會不斷優(yōu)化改善,直到dist[u] = short[u],并將其放到S中,當(dāng)所有頂點都放入S集合時,算法結(jié)束。
輸入:加權(quán)有向圖G=(V,E,W)
V={1,2,…,n}, s=1
輸出:從s到每個頂點的最短路徑
輸入:G=(V,E,W),源點1
V={1,2,3,4,5,6}
初始S集合只有1,計算直接從1能到達(dá)的頂點的距離,其他不能從1號頂點直接到達(dá)的頂點都記為無窮大。此時從dist[u]里找出最短距離的頂點(6號),并將其放進(jìn)S集合。
S={1}
dist[1] = 0
dist[2] = 10
dist[6 ] = 3
dist[3] = ∞
dist[4] = ∞
dist[5] = ∞
當(dāng)把6號頂點放進(jìn)S集合后,經(jīng)由6號頂點出發(fā)到達(dá)的頂點的最短距離可能會被優(yōu)化更新,因為該算法的思想很“貪心”,誰更短我要誰!比如1->6->2要比1->2距離更短,所以dist[2]被更新為5,從專業(yè)術(shù)語上講,這個“更新”過程叫做松弛,其他點同理。然后從dist[u]里找出最短的路徑的那個頂點(5號),并放進(jìn)S集合里。
S={1,6}
dist[1] = 0
dist[6] = 3
dist[2] = 5
dist[4] = 9
dist[5] = 4
dist[3] = ∞
后面的操作步驟其實就是重復(fù)上面的操作。即當(dāng)S集合里有個新的頂點后,就可能會更新其他點的最短距離,更新一遍后,找出當(dāng)前最短距離的dist[u],并將該頂點放進(jìn)S集合。后面不重復(fù)闡述。
S={1,6,5}
dist[1] = 0
dist[6] = 3
dist[5] = 4
dist[2] = 5
dist[4] = 9
dist[3] = ∞
S={1,6,5,2}
dist[1] = 0
dist[6] = 3
dist[5] = 4
dist[2] = 5
dist[4] = 9
dist[3] = 12
S={1,6,5,2,4}
dist[1] = 0
dist[6] = 3
dist[5] = 4
dist[2] = 5
dist[4] = 9
dist[3] = 12
S={1,6,5,2,4,3}
dist[1] = 0
dist[6] = 3
dist[5] = 4
dist[2] = 5
dist[4] = 9
dist[3] = 12
當(dāng)有向圖中的所有頂點都進(jìn)入了S集合后,算法結(jié)束,此時的dist[u]的值其實就是最初我們找出的那個最終解short[u],所以,算法結(jié)束時,dist[u]=short[u],得到最終解。
三、dijkstra算法是什么?
迪杰斯特拉算法用來解決從頂點v0出發(fā)到其余頂點的最短路徑,該算法按照最短路徑長度遞增的順序產(chǎn)生所以最短路徑。
對于圖G=(V,E),將圖中的頂點分成兩組:第一組S:已求出的最短路徑的終點集合(開始為{v0})。第二組V-S:尚未求出最短路徑的終點集合(開始為V-{v0}的全部結(jié)點)。
堆優(yōu)化
思考
該算法復(fù)雜度為n^2,我們可以發(fā)現(xiàn),如果邊數(shù)遠(yuǎn)小于n^2,對此可以考慮用堆這種數(shù)據(jù)結(jié)構(gòu)進(jìn)行優(yōu)化,取出最短路徑的復(fù)雜度降為O(1);每次調(diào)整的復(fù)雜度降為O(elogn);e為該點的邊數(shù),所以復(fù)雜度降為O((m+n)logn)。
實現(xiàn)
1、將源點加入堆,并調(diào)整堆。
2、選出堆頂元素u(即代價最小的元素),從堆中刪除,并對堆進(jìn)行調(diào)整。
3、處理與u相鄰的,未被訪問過的,滿足三角不等式的頂點
1):若該點在堆里,更新距離,并調(diào)整該元素在堆中的位置。
2):若該點不在堆里,加入堆,更新堆。
4、若取到的u為終點,結(jié)束算法;否則重復(fù)步驟2、3。
四、計算機網(wǎng)絡(luò)的最短路徑算法有哪些?對應(yīng)哪些協(xié)議?
用于解決最短路徑問題的算法被稱做“最短路徑算法”,有時被簡稱作“路徑算法”。最常用的路徑算法有:
Dijkstra算法、A*算法、SPFA算法、Bellman-Ford算法和Floyd-Warshall算法,本文主要介紹其中的三種。
最短路徑問題是圖論研究中的一個經(jīng)典算法問題,旨在尋找圖(由結(jié)點和路徑組成的)中兩結(jié)點之間的最短路徑。
算法具體的形式包括:
確定起點的最短路徑問題:即已知起始結(jié)點,求最短路徑的問題。
確定終點的最短路徑問題:與確定起點的問題相反,該問題是已知終結(jié)結(jié)點,求最短路徑的問題。在無向圖中該問題與確定起點的問題完全等同,在有向圖中該問題等同于把所有路徑方向反轉(zhuǎn)的確定起點的問題。
確定起點終點的最短路徑問題:即已知起點和終點,求兩結(jié)點之間的最短路徑。
全局最短路徑問題:求圖中所有的最短路徑。
Floyd
求多源、無負(fù)權(quán)邊的最短路。用矩陣記錄圖。時效性較差,時間復(fù)雜度O(V^3)。
Floyd-Warshall算法(Floyd-Warshall algorithm)是解決任意兩點間的最短路徑的一種算法,可以正確處理有向圖或負(fù)權(quán)的最短路徑問題。
Floyd-Warshall算法的時間復(fù)雜度為O(N^3),空間復(fù)雜度為O(N^2)。
Floyd-Warshall的原理是動態(tài)規(guī)劃:
設(shè)Di,j,k為從i到j(luò)的只以(1..k)集合中的節(jié)點為中間節(jié)點的最短路徑的長度。
若最短路徑經(jīng)過點k,則Di,j,k = Di,k,k-1 + Dk,j,k-1;
若最短路徑不經(jīng)過點k,則Di,j,k = Di,j,k-1。
因此,Di,j,k = min(Di,k,k-1 + Dk,j,k-1 , Di,j,k-1)。
在實際算法中,為了節(jié)約空間,可以直接在原來空間上進(jìn)行迭代,這樣空間可降至二維。
Floyd-Warshall算法的描述如下:
for k ← 1 to n do
for i ← 1 to n do
for j ← 1 to n do
if (Di,k + Dk,j < Di,j) then
Di,j ← Di,k + Dk,j;
其中Di,j表示由點i到點j的代價,當(dāng)Di,j為 ∞ 表示兩點之間沒有任何連接。
Dijkstra
求單源、無負(fù)權(quán)的最短路。時效性較好,時間復(fù)雜度為O(V*V+E),可以用優(yōu)先隊列進(jìn)行優(yōu)化,優(yōu)化后時間復(fù)雜度變?yōu)?(v*lgn)。
源點可達(dá)的話,O(V*lgV+E*lgV)=>O(E*lgV)。
當(dāng)是稀疏圖的情況時,此時E=V*V/lgV,所以算法的時間復(fù)雜度可為O(V^2) ??梢杂脙?yōu)先隊列進(jìn)行優(yōu)化,優(yōu)化后時間復(fù)雜度變?yōu)?(v*lgn)。
Bellman-Ford
求單源最短路,可以判斷有無負(fù)權(quán)回路(若有,則不存在最短路),時效性較好,時間復(fù)雜度O(VE)。
Bellman-Ford算法是求解單源最短路徑問題的一種算法。
單源點的最短路徑問題是指:給定一個加權(quán)有向圖G和源點s,對于圖G中的任意一點v,求從s到v的最短路徑。
與Dijkstra算法不同的是,在Bellman-Ford算法中,邊的權(quán)值可以為負(fù)數(shù)。設(shè)想從我們可以從圖中找到一個環(huán)
路(即從v出發(fā),經(jīng)過若干個點之后又回到v)且這個環(huán)路中所有邊的權(quán)值之和為負(fù)。那么通過這個環(huán)路,環(huán)路中任意兩點的最短路徑就可以無窮小下去。如果不處理這個負(fù)環(huán)路,程序就會永遠(yuǎn)運行下去。 而Bellman-Ford算法具有分辨這種負(fù)環(huán)路的能力。
SPFA
是Bellman-Ford的隊列優(yōu)化,時效性相對好,時間復(fù)雜度O(kE)。(k< 與Bellman-ford算法類似,SPFA算法采用一系列的松弛操作以得到從某一個節(jié)點出發(fā)到達(dá)圖中其它所有節(jié)點的最短路徑。所不同的是,SPFA算法通過維護(hù)一個隊列,使得一個節(jié)點的當(dāng)前最短路徑被更新之后沒有必要立刻去更新其他的節(jié)點,從而大大減少了重復(fù)的操作次數(shù)。
SPFA算法可以用于存在負(fù)數(shù)邊權(quán)的圖,這與dijkstra算法是不同的。
與Dijkstra算法與Bellman-ford算法都不同,SPFA的算法時間效率是不穩(wěn)定的,即它對于不同的圖所需要的時間有很大的差別。
在最好情形下,每一個節(jié)點都只入隊一次,則算法實際上變?yōu)閺V度優(yōu)先遍歷,其時間復(fù)雜度僅為O(E)。另一方面,存在這樣的例子,使得每一個節(jié)點都被入隊(V-1)次,此時算法退化為Bellman-ford算法,其時間復(fù)雜度為O(VE)。
SPFA算法在負(fù)邊權(quán)圖上可以完全取代Bellman-ford算法,另外在稀疏圖中也表現(xiàn)良好。但是在非負(fù)邊權(quán)圖中,為了避免最壞情況的出現(xiàn),通常使用效率更加穩(wěn)定的Dijkstra算法,以及它的使用堆優(yōu)化的版本。通常的SPFA。
以上就是關(guān)于圖最短路徑算法相關(guān)問題的回答。希望能幫到你,如有更多相關(guān)問題,您也可以聯(lián)系我們的客服進(jìn)行咨詢,客服也會為您講解更多精彩的知識和內(nèi)容。
推薦閱讀:
杭州城市未來規(guī)劃圖(杭州城市未來規(guī)劃圖最新)
抖音怎么查達(dá)人帶貨數(shù)據(jù)(抖音怎么查達(dá)人帶貨數(shù)據(jù)查詢)