Dijkstra 最短路算法(只能計算出一條最短路徑,所有路徑用dfs)

上周我們介紹了神奇的只有五行的 Floyd 最短路算法,它可以方便的求得任意兩點的最短路徑,這稱為“多源最短路”。本周來來介紹指定一個點(源點)到其余各個頂點的最短路徑,也叫做“單源最短路徑”。例如求下圖中的 1 號頂點到 2、3、4、5、6 號頂點的最短路徑。

picture7.1

與 Floyd-Warshall 算法一樣這里仍然使用二維數組 e 來存儲頂點之間邊的關系,初始值如下。

picture7.2

我們還需要用一個一維數組 dis 來存儲 1 號頂點到其余各個頂點的初始路程,如下。

picture7.3

我們將此時 dis 數組中的值稱為最短路的“估計值”。

既然是求 1 號頂點到其余各個頂點的最短路程,那就先找一個離 1 號頂點最近的頂點。通過數組 dis 可知當前離 1 號頂點最近是 2 號頂點。當選擇了 2 號頂點后,dis[2]的值就已經從“估計值”變為了“確定值”,即 1 號頂點到 2 號頂點的最短路程就是當前 dis[2]值。為什么呢?你想啊,目前離 1 號頂點最近的是 2 號頂點,并且這個圖所有的邊都是正數,那么肯定不可能通過第三個頂點中轉,使得 1 號頂點到 2 號頂點的路程進一步縮短了。因為 1 號頂點到其它頂點的路程肯定沒有 1 號到 2 號頂點短,對吧 O(∩_∩)O~

既然選了 2 號頂點,接下來再來看 2 號頂點有哪些出邊呢。有 2->3 和 2->4 這兩條邊。先討論通過 2->3 這條邊能否讓 1 號頂點到 3 號頂點的路程變短。也就是說現在來比較 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 號頂點的路程。

我們發現 dis[3]=12,dis[2]+e[2][3]=1+9=10,dis[3]>dis[2]+e[2][3],因此 dis[3]要更新為 10。這個過程有個專業術語叫做“松弛”。即 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 數組為:

picture7.4

接下來,繼續在剩下的 3、4、5 和 6 號頂點中,選出離 1 號頂點最近的頂點。通過上面更新過 dis 數組,當前離 1 號頂點最近是 4 號頂點。此時,dis[4]的值已經從“估計值”變為了“確定值”。下面繼續對 4 號頂點的所有出邊(4->3,4->5 和 4->6)用剛才的方法進行松弛。松弛完畢之后 dis 數組為:

picture7.5

繼續在剩下的 3、5 和 6 號頂點中,選出離 1 號頂點最近的頂點,這次選擇 3 號頂點。此時,dis[3]的值已經從“估計值”變為了“確定值”。對 3 號頂點的所有出邊(3->5)進行松弛。松弛完畢之后 dis 數組為:

picture7.6

繼續在剩下的 5 和 6 號頂點中,選出離 1 號頂點最近的頂點,這次選擇 5 號頂點。此時,dis[5]的值已經從“估計值”變為了“確定值”。對5號頂點的所有出邊(5->4)進行松弛。松弛完畢之后 dis 數組為:

picture7.7

最后對 6 號頂點所有點出邊進行松弛。因為這個例子中 6 號頂點沒有出邊,因此不用處理。到此,dis 數組中所有的值都已經從“估計值”變為了“確定值”。

最終 dis 數組如下,這便是 1 號頂點到其余各個頂點的最短路徑。

picture7.8

OK,現在來總結一下剛才的算法。算法的基本思想是:每次找到離源點(上面例子的源點就是 1 號頂點)最近的一個頂點,然后以該頂點為中心進行擴展,最終得到源點到其余所有點的最短路徑。基本步驟如下:

  • 將所有的頂點分為兩部分:已知最短路程的頂點集合 P 和未知最短路徑的頂點集合 Q。最開始,已知最短路徑的頂點集合 P 中只有源點一個頂點。我們這里用一個 book[ i ]數組來記錄哪些點在集合 P 中。例如對于某個頂點 i,如果 book[ i ]為 1 則表示這個頂點在集合 P 中,如果 book[ i ]為 0 則表示這個頂點在集合 Q 中。
  • 設置源點 s 到自己的最短路徑為 0 即 dis=0。若存在源點有能直接到達的頂點 i,則把 dis[ i ]設為 e[s][ i ]。同時把所有其它(源點不能直接到達的)頂點的最短路徑為設為 ∞。
  • 在集合 Q 的所有頂點中選擇一個離源點 s 最近的頂點 u(即 dis[u]最小)加入到集合 P。并考察所有以點 u 為起點的邊,對每一條邊進行松弛操作。例如存在一條從 u 到 v 的邊,那么可以通過將邊 u->v 添加到尾部來拓展一條從 s 到 v 的路徑,這條路徑的長度是 dis[u]+e[u][v]。如果這個值比目前已知的 dis[v]的值要小,我們可以用新值來替代當前 dis[v]中的值。
  • 重復第 3 步,如果集合 Q 為空,算法結束。最終 dis 數組中的值就是源點到所有頂點的最短路徑。

轉載于:https://www.cnblogs.com/timesdaughter/p/5971087.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/373665.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/373665.shtml
英文地址,請注明出處:http://en.pswp.cn/news/373665.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

JavaScript學習隨記——錯誤類型

錯誤類型: 執行代碼期間可能會發生的錯誤有多種類型。每種錯誤都有對應的錯誤類型,而當錯誤發生時,就會拋出相應類型的錯誤對象。 ECMA-262定義的7種錯誤類型 Error: 是錯誤的基類型,其他錯誤類型都繼承該類型。Error…

多個集合中的共同和獨特元素

本周,我們將暫時中斷較高級別的問題和技術文章,以解決我們中許多人可能面臨的一些代碼問題。 沒什么花哨的或太辛苦的,但是有一天它可能會節省您15分鐘的時間,偶爾回到基礎上也很不錯。 因此,讓我們開始吧。 有時&…

2016給自己一個交代

一、前言 在關于技術上的學習,常常有這樣那樣的計劃,而最終一個都沒有真正的落實。零散的學習,終究需要系統總結,才能使自己有所沉淀。從畢業至今,我一直在忙碌,為公司付出自己的很多很多,卻只不…

洛克人紅色思考型機器人叫什么_稻船敬二新企劃《紅色灰燼》 依然是機器人風格...

稻船敬二離開CAPCOM之后玩家們紛紛感嘆《洛克人》系列將再無續作,不過在單飛的這段時間里,稻船敬二還是創作了諸如《蒼藍雷霆 剛巴爾特》《Mighty No.9》等類似洛克人風格的作品。其名下的團隊comcept的最新作《Mighty No.9》即將于9月18日發售&#xff…

常見對話框

(1)普通對話框 // 點擊按鈕 彈出一個普通對話框public void click1(View v) {// 構建AlertDialogAlertDialog.Builder builder new Builder(this);builder.setTitle("警告");builder.setMessage("世界上最遙遠的距離是沒有網絡");builder.setPositiveButt…

JavaScript學習隨記——面向對象編程(繼承)

Example:基于原型鏈的繼承 <!DOCTYPE HTML> <html><head><meta http-equiv"Content-Type" content"text/html; charsetutf-8" /><title>面向對象編程&#xff08;OOP&#xff09;</title></head> <body>…

NSCharacterSet

先上個例子&#xff1a; NSString * str1 [nameInput.textstringByTrimmingCharactersInSet:[NSCharacterSetwhitespaceAndNewlineCharacterSet]]; NSString * str2 [passwdInput.textstringByTrimmingCharactersInSet:[NSCharacterSetwhitespaceAndNewlineCharacterSet]]; […

Apache Mahout:構建垃圾郵件過濾器服務器

Lucene發生了一些相當有趣的事情。 它最初是作為一個庫&#xff0c;然后其開發人員開始基于它添加新項目。 他們開發了另一個開源項目&#xff0c;該項目將向Lucene添加爬網功能&#xff08;以及其他功能&#xff09;。 Nutch實際上是任何人都可以使用或修改的功能齊全的Web Se…

建模步驟_古建設計 | sketchup建模步驟教程(簡易入門版)

前言本篇教程主要是針對古建建模入門者。小N給大家分享一套我相對簡易的建模步驟。(PS&#xff1a;但是估計有些人可能會感覺我做的東西已經繁瑣了……)因為主要是為了讓大家熟悉、入門和好記憶。所以講的東西&#xff0c;小N我會相對簡單&#xff0c;有些細節的內容不會更多展…

JavaScript模塊化

JavaScript模塊化的實現方式&#xff1a; <!DOCTYPE HTML> <html><head><meta http-equiv"Content-Type" content"text/html; charsetutf-8" /><title>模塊化</title></head> <body><script type&quo…

Linux下面的IO模型

1. Linux下的五種I/O模型 阻塞I/O模型&#xff1a; 一直阻塞 應用程序調用一個IO函數&#xff0c;導致應用程序阻塞&#xff0c;等待數據準備好。 如果數據沒有準備好&#xff0c;一直等待….數據準備好了&#xff0c;從內核拷貝到用戶空間,IO函數返回成功指示。 我們 第一…

改變導航欄上邊的狀態欄顏色

#pragma mark - 改變狀態欄顏色 -(UIStatusBarStyle)preferredStatusBarStyle{ return UIStatusBarStyleLightContent; }轉載于:https://www.cnblogs.com/block123/p/5195203.html

PIT和TestNG突變測試簡介

變異測試是一種技術&#xff0c;它可以發現測試未涵蓋代碼的哪些部分。 它類似于代碼覆蓋范圍 &#xff0c;但變異測試不限于在測試期間執行給定行的事實。 這個想法是修改生產代碼&#xff08;引入突變&#xff09;&#xff0c;這應該改變其行為&#xff08;產生不同的結果&am…

JavaScript內存管理——優化內存占用

使用具備垃圾收集機制的語言編寫程序&#xff0c;開發人員一般不必操心內存管理的問題。但是&#xff0c;JavaScript在進行內存管理及垃圾收集時面臨的問題還是有點與眾不同。其中最主要的一個問題&#xff0c;就是分配給Web瀏覽器的可用內存數量通常要比分配給桌面應用程序的少…

Java 8的烹調方式– Lambda項目

什么是project lambda &#xff1a;Project lambda是用于以Java語言語法啟用lambda表達式的項目。 Lambda表達式是功能編程語言&#xff08;如lisp&#xff09;中的主要語法。 Groovy將是支持lambda表達式&#xff08;也稱為閉包&#xff09;的java的最接近親戚。 那么什么是la…

ffmpeg文檔38-視頻源

38 視頻源 下面是當前有效的視頻源 buffer 緩沖視頻幀&#xff0c;其可以作為濾鏡鏈圖的環節 它通常用于編程&#xff0c;特別是通過libavfilter/vsrc_buffer.h的接口。 接受如下參數&#xff1a; video_size 指定視頻尺寸&#xff0c;(同時指定width 和 height)。語法同于ffmp…

系統架構的演變 -----自 羅文浩

轉自&#xff1a;https://my.oschina.net/lwhmdj0823/blog/617713版權聲明&#xff1a;羅文浩所有摘要: 一個成熟的大型網站&#xff08;如淘寶、京東等&#xff09;的系統架構并不是開始設計就具備完整的高性能、高可用、安全等特性&#xff0c;它總是隨著用戶量的增加&#x…

前端請求接口post_前端如何優雅地模擬接口請求?(給你的代碼加點小意外)

前言&#xff1a;作為一名前端開發程序猿&#xff0c;每天都被產品經理催著開發&#xff0c;項目一啟動&#xff0c;產品就過來了。噓寒問暖&#xff1a;大胸弟&#xff0c;你啥時開始做啊&#xff1f;一般我們都會直接告訴TA&#xff0c;你先找接口解決數據問題。而我們也會經…

cron表達式詳解

Cron表達式是一個字符串&#xff0c;字符串以5或6個空格隔開&#xff0c;分為6或7個域&#xff0c;每一個域代表一個含義&#xff0c;Cron有如下兩種語法格式&#xff1a; Seconds Minutes Hours DayofMonth Month DayofWeek Year或 Seconds Minutes Hours DayofMonth Month …

將Ehcache添加到Openxava應用程序

介紹 本文介紹如何在Openxava應用程序上快速啟用Ehcache&#xff0c;從而提高性能。 查看實體及其圖時&#xff0c;將加載關系。 添加第二級緩存可加快關聯元素的檢索速度&#xff0c;因為已加載的元素是從緩存而不是數據庫中檢索的。 最終&#xff0c;該頁面解釋了分鐘項目如…