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