深入理解迪傑斯特拉演算法

2022-04-04 01:04:11 字數 2060 閱讀 2323

** 

這裡需要乙個很好的例子,這裡先拿網上流傳的例子作為反例。

問題1:不符合勾股定理

ac=3,cb=2,ab=6

難道這樣真的無傷大雅嗎?假設你的起點是a,終點是b,難道不應該是兩點之間線段最短嗎?、

問題2:完美地掃到了每個點

按照他的思維邏輯來,確實每個點都可以掃到,但是事實上,我們應該充分考慮沒掃到的情況之後是怎樣的,這樣才能真正理解dijkstra演算法。

這個圖會很容易發現,按照dijkstra的演算法,當前點走動的方向是如圖所示的。但是走到e點會發現此路不通,因為沒被訪問的點剩下了f,g,但是他們之間又是無窮遠的。如果讀者是這樣想的,那就進入思維誤區了。

正確思考:(設u是未走到過的集合,初始u=)

第一次,bcdefg都是無窮遠,設為1000好了,發現a和f、b是相連的,所以用a去更新f、b。

第二次,到達b,u中去除b,剩下cdefg。到了b,發現dc是可達的,更新dc。發現d更短,去往d。

第三次,到達d,把d從u中去除,剩下cefg。與d相連的有ec(另外的已訪問過所以不再考慮),這裡得出e為10,小於1000(無窮遠),可以被更新。但是看向c點,卻發現9>7.5更新不了。那麼a到c的最短路徑依然是abc而不是abdc。

到達e,這個時候u中剩下f,g。發現7.5+4大於10,還是更新不了,所以a到e還是abde最短。

這裡就回到了我們之前的關鍵點了。走dijkstra演算法,不是靠走的,而是靠從u集合中取的!

所以這裡取出的是f,成功使用f更新了g,g被更新為7,fd 6+5>7更新不了。

其實a你也可以認為是0。

此外,剛才選取的時候,我們怎麼知道應該選取f而不是g?假設我們選的是g,但是他自己沒有被更新過,所以他也不能更新另外的值。所以我們需要加乙個判斷,當前值是被更新過的才能去更新另外的值。換個角度,不加判斷其實也行。因為如果你取到了乙個沒有被更新過的數,那麼就是1000,1000去更新另外的,只有可能比1000要大,所以他更新誰都不會成功,如果你加個判斷,等於是進行了一點點的優化。

梳理下流程,不斷從u中去取,然後不斷更新,直到u中被取完,這樣我們就得出了起點到達每個點的最短距離。

但是最短路徑怎麼求呢?之前我們到達e點斷掉了,說明靠走肯定不行,說明直接求最短路徑也肯定求不出來。所以我們和之前一樣,我們怎麼把最短路徑長度維護給每個點的,就怎麼把最短路徑交給每個點去維護。我們需要開乙個二維陣列,以更新路徑的形式即可。

優化:採用優先佇列去優化。意思就是當你在a的時候,發現ab=3.5,af=6,另外的1000,都更新他們,再把他們都丟進優先佇列,而優先佇列會自動替你把這一串,由小到大排好序。所以你只需要取佇列的隊首元素就可以了,省去了你找到最小值的過程。我們使用優先佇列就是節省了排序的時間。此外你可以用vector或者鄰接表,不用像二維陣列一樣開乙個矩陣,會更快。

原理:也就是為什麼我們要選取u中的最小值來更新而不是任意乙個大小的值?因為只有這樣,你才能保證你每個點都能被更新成最小值。假設之前你用乙個較大的值而沒有用最小值去更新,那麼就之後就可能會出現,你這個較大的值後來被更新了,但是一開始被你這個較大的值所更新的值並沒有被更新到。具體舉個例子,看最後一幅圖,假如我們一開始取的是f點,那麼我們就會把g點更新成7,那麼假如之後,發現一條更短的路徑到f,我們f點會被更新,但是g點卻不會被更新了啊,所以資料就失真了。那麼為什麼我們從最小的點開始取不會出現這個情況呢?舉個例子,我們根據選取最小值來選,ab=3.5,af=6。那麼自然是選ab。然後由b去更新後面的值。這裡我們思考一下上面的那個問題,有沒有可能發現一條到達b更短的路,從而使得被b更新的最小值全部失效了?肯定就沒有了。那為什麼上面那個情況有?其實上面那個例子舉的不太好,不過講到這裡大家應該也都能明白是為什麼了。

迪傑斯特拉演算法

if object id t test is not null drop table t test gocreate table dbo t test id int identity 1,1 not null primary key,自增字段,無意義 header varchar 500 第一點的名...

迪傑斯特拉演算法

dijkstra 迪傑斯特拉 演算法是典型的最短路徑路由演算法,用於計算乙個節點到其他所有節點的最短路徑。主要特點是以起始點為中心向外層層擴充套件,直到擴充套件到終點為止。dijkstra演算法 能得出最短路徑的最優解,但由於它遍歷計算的節點很多,所以效率低。dijkstra演算法是很有代表性的最短...

迪傑斯特拉演算法

迪傑斯特拉演算法用來計算圖中某一點到其他點的最短距離,這個圖可以是加權,也可以是無權的,距離指的是從一點到其它點所經過的邊的權重和 假設現在有乙個加權無向圖,我們要求節點1到其他點的最短距離 初始化圖arr 用乙個鄰接矩陣來表示一張圖,矩陣元素 初始化一維向量d,這個向量儲存的是其他點的最短距離,初...