成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

詳談Dijkstra算法

開發 后端 算法
Dijkstra算法是典型的最短路徑算法,用于計算一個節點到其他所有節點的最短路徑。主要特點是以起始點為中心向外層層擴展,直到擴展到終點為止。Dijkstra算法能得出最短路徑的最優解,但由于它遍歷計算的節點很多,所以效率低。

本文由單源最短路徑路徑問題開始,而后描述Bellman-Ford算法,到具體闡述Dijkstra算法,闡述詳細剖析Dijkstra算法的每一個步驟,教你徹底理解此Dijkstra算法。

一、單源最短路徑問題

我們知道,單源最短路徑問題:已知圖G=(V,E),要求找出從某個定源頂點s<-V,到每個v<-V的最短路徑。簡單來說,就是一個圖G中,找到一個定點s,然后以s為起點,要求找出s到圖G中其余各個點的最短距離或路徑。

此單源最短路徑問題有以下幾個變形:

I、  單終點最短路徑問題: 每個頂點v到指定終點t的最短路徑問題。即單源最短路徑問題的相對問題。

II、 單對頂點最短路徑問題:給定頂點u和v,找出從u到v的一條最短路徑。

III、每對頂點間最短路徑問題:

針對任意每倆個頂點u和v,找出從u到v的最短路徑。最簡單的想法是,將每個頂點作為源點,運行一次單源算法即可以解決這個問題。當然,還有更好的辦法。 

二、Bellman-Ford 算法

1、回路問題

一條最短路徑不能包含負權回路,也不能包含正權回路。一些最短路徑的算法,如Dijkstra 算法,要求圖中所有的邊的權值都是非負的,如在公路地圖上,找一條從定點s到目的頂點v的最短路徑問題。

2、Bellman-Ford 算法

而Bellman-Ford 算法,則允許輸入圖中存在負權邊,只要不存在從源點可達的負權回路,即可。簡單的說,圖中可以存在負權邊,但此條負權邊,構不成負權回路,不影響回路的形成。且,Bellman-Ford 算法本身,便是可判斷圖中是否存在從源點可達的負權回路,若存在負權回路,算法返回FALSE,若不存在,返回TRUE。

Bellman-Ford 算法的具體描述

BELLMAN-FORD(G, w, s)

  1. INITIALIZE-SINGLE-SOURCE(G, s)   //對每個頂點初始化 ,O(V)   
  2. for i ← 1 to |V[G]| - 1  
  3.   do for each edge (u, v) ∈ E[G]  
  4. do RELAX(u, v, w)    //針對每個頂點(V-1個),都運用松弛技術O(E),計為O((v-1)*E))  
  5. for each edge (u, v) ∈ E[G]  
  6. do if d[v] > d[u] + w(u, v)  
  7. then return FALSE     //檢測圖中每條邊,判斷是否包含負權回路,  
  8.                                     //若d[v]>d[u]+w(u,v),則表示包含,返回FALSE,  
  9. return TRUE                      //不包含負權回路,返回TRUE  

 

Bellman-Ford 算法的時間復雜度,由上可得為O(V*E)。

3、關于判斷圖中是否包含負權回路的問題:

根據定理,我們假定,u是v的父輩,或父母,那么,當G(V,E)是一個有向圖或無向圖(且不包含任何負權回路),s<-V,s為G的任意一個頂點,則對任意邊(u,v)<-V,有     

d[s,v] <= d[s,u]+1

此定理的詳細證明,可參考算法導論一書上,第22章中引理22.1的證明。或者根據第24章中通過三角不等式論證Bellman-Ford算法的正確性,也可得出上述定理的變形。

即假設圖G中不包含負權回路,可證得

  1. d[v]=$(s,u)  
  2.       <=$(s,u)+w(u,v)  //根據三角不等式  
  3.       =d[u]+w[u,v] 

所以,在不包含負權回路的圖中,是可以得出d[v]<=d[u]+w(u,v)。

于是,就不難理解,在上述Bellman-Ford 算法中, if d[v] > d[u]+w(u,v),=> 包含負權回路,返回FASLE

 else if =>不包含負權回路,返回TRUE。

ok,咱們,接下來,立馬切入Dijkstra 算法。

三、深入淺出,徹底解剖Dijkstra 算法

I、松弛技術RELAX的介紹

Dijkstra 算法使用了松弛技術,對每個頂點v<-V,都設置一個屬性d[v],用來描述從源點s到v的最短路徑上權值的上界,
稱為最短路徑的估計。

首先,得用O(V)的時間,來對最短路徑的估計,和對前驅進行初始化工作。

  1. INITIALIZE-SINGLE-SOURCE(G, s)  
  2.  for each vertex v ∈ V[G]  
  3.   do d[v] ← ∞  
  4.    π[v] ← NIL      //O(V)  
  5. d[s] 0  
  6.  
  7. RELAX(u, v, w)  
  8. if d[v] > d[u] + w(u, v)  
  9.  then d[v] ← d[u] + w(u, v)  
  10.   π[v] ← u        //O(E)圖。 

 

II、Dijkstra 算法

此Dijkstra 算法分三個步驟,INSERT (第3行), EXTRACT-MIN (第5行), 和DECREASE-KEY(第8行的RELAX,調用此減小關鍵字的操作)。

  1. DIJKSTRA(G, w, s)  
  2.  INITIALIZE-SINGLE-SOURCE(G, s)    //對每個頂點初始化 ,O(V)   
  3.  S ← Ø  
  4.  Q ← V[G]            //INSERT,O(1)  
  5.  while Q ≠ Ø  
  6.    do u ← EXTRACT-MIN(Q)        //簡單的O(V*V);二叉/項堆,和FIB-HEAP的話,則都為O(V*lgV)。      
  7.  S ← S ∪{u}  
  8.      for each vertex v ∈ Adj[u]  
  9.           do RELAX(u, v, w)      //簡單方式:O(E),二叉/項堆,E*O(lgV),FIB-HEAP,E*O(1)。 

 

四、Dijkstra 算法的運行時間

在繼續闡述之前,得先聲明一個問題,DIJKSTRA(G,w,s)算法中的第5行,EXTRACT-MIN(Q),最小優先隊列的具體實現。而Dijkstra 算法的運行時間,則與此最小優先隊列的采取何種具體實現,有關。

最小優先隊列三種實現方法:

1、利用從1至|V| 編好號的頂點,簡單地將每一個d[v]存入一個數組中對應的第v項,如上述DIJKSTRA(G,w,s)所示,Dijkstra 算法的運行時間為O(V^2+E)。

2、如果是二叉/項堆實現最小優先隊列的話,EXTRACT-MIN(Q)的運行時間為O(V*lgV),所以,Dijkstra 算法的運行時間為O(V*lgV+E*lgV),若所有頂點都是從源點可達的話,O((V+E)*lgV)=O(E*lgV)。當是稀疏圖時,則E=O(V^2/lgV),此Dijkstra 算法的運行時間為O(V^2)。

3、采用斐波那契堆實現最小優先隊列的話,EXTRACT-MIN(Q)的運行時間為O(V*lgV),所以,此Dijkstra 算法的運行時間即為O(V*lgV+E)。

綜上所述,此最小優先隊列的三種實現方法比較如下:

當|V|<<|E|時,采用DIJKSTRA(G,w,s)+ FIB-HEAP-EXTRACT-MIN(Q),即斐波那契堆實現最小優先隊列的話,
優勢就體現出來了。

五、Dijkstra 算法 + FIB-HEAP-EXTRACT-MIN(H),斐波那契堆實現最小優先隊列

由以上內容,我們已經知道,用斐波那契堆來實現最小優先隊列,可以將運行時間提升到O(VlgV+E)。|V|個EXTRACT-MIN 操作,每個平攤代價為O(lgV),|E|個DECREASE-KEY操作的每個平攤時間為O(1)。

下面,重點闡述DIJKSTRA(G, w, s)中,斐波那契堆實現最小優先隊列的操作。

由上,我們已經知道,DIJKSTRA算法包含以下的三個步驟:

INSERT (第3行), EXTRACT-MIN (第5行), 和DECREASE-KEY(第8行的RELAX)。

先直接給出Dijkstra 算法 + FIB-HEAP-EXTRACT-MIN(H)的算法:

  1. DIJKSTRA(G, w, s)  
  2.  INITIALIZE-SINGLE-SOURCE(G, s)  
  3.  S ← Ø  
  4.  Q ← V[G]   //第3行,INSERT操作,O(1)  
  5.  while Q ≠ Ø  
  6.    do u ← EXTRACT-MIN(Q)   //第5行,EXTRACT-MIN操作,V*lgV  
  7.        S ← S ∪{u}  
  8.        for each vertex v ∈ Adj[u]  
  9.           do RELAX(u, v, w)  //第8行,RELAX操作,E*O(1)  
  10.  
  11. FIB-HEAP-EXTRACT-MIN(H)  //平攤代價為O(lgV)  
  12.   z ← min[H]  
  13.   if z ≠ NIL  
  14.      then for each child x of z  
  15.               do add x to the root list of H  
  16.                  p[x] ← NIL  
  17.           remove z from the root list of H  
  18.           if z = right[z]  
  19.              then min[H] ← NIL  
  20.             else min[H] ← right[z]  
  21.                  CONSOLIDATE(H)     
  22.          n[H] ← n[H] - 1  
  23. return z 

 

六、Dijkstra 算法 +fibonacci堆各項步驟的具體分析 

ok,接下來,具體分步驟闡述以上各個操作:

第3行的INSERT操作:

  1. FIB-HEAP-INSERT(H, x)   //平攤代價,O(1).  
  2.   degree[x] ← 0  
  3.   p[x] ← NIL  
  4.   child[x] ← NIL  
  5.   left[x] ← x  
  6.   right[x] ← x  
  7.   mark[x] ← FALSE  
  8.   concatenate the root list containing x with root list H  
  9.   if min[H] = NIL or key[x] < key[min[H]]  
  10.      then min[H] ← x  
  11.  n[H] ← n[H] + 1 

 

第5行的EXTRACT-MIN操作:

  1. FIB-HEAP-EXTRACT-MIN(H)  //平攤代價為O(lgV)  
  2.   z ← min[H]  
  3.   if z ≠ NIL  
  4.     then for each child x of z  
  5.              do add x to the root list of H  
  6.                 p[x] ← NIL  
  7.         remove z from the root list of H  
  8.         if z = right[z]  
  9.            then min[H] ← NIL  
  10.           else min[H] ← right[z]  
  11.               CONSOLIDATE(H)   //CONSOLIDATE算法在下面,給出。  
  12.         n[H] ← n[H] - 1  
  13. return z  

 

下圖是FIB-HEAP-EXTRACT-MIN 的過程示意圖:

 

  1. CONSOLIDATE(H)  
  2.  for i ← 0 to D(n[H])  
  3.       do A[i] ← NIL  
  4.  for each node w in the root list of H  
  5.       do x ← w  
  6.          d ← degree[x]        //子女數  
  7.          while A[d] ≠ NIL  
  8.              do y ← A[d]        
  9.                 if key[x] > key[y]  
  10.                  then exchange x <-> y  
  11.               FIB-HEAP-LINK(H, y, x)  //下面給出。  
  12.              A[d] ← NIL  
  13.              d ← d + 1  
  14.         A[d] ← x  
  15.  min[H] ← NIL  
  16.  for i ← 0 to D(n[H])  
  17.     do if A[i] ≠ NIL  
  18.          then add A[i] to the root list of H  
  19.               if min[H] = NIL or key[A[i]] < key[min[H]]  
  20.               then min[H] ← A[i]  
  21.  
  22. FIB-HEAP-LINK(H, y, x)   //y鏈接至 x。  
  23. remove y from the root list of H  
  24. make y a child of x, incrementing degree[x]  
  25.  mark[y] ← FALSE 

 

第8行的RELAX的操作,已上已經給出:

  1. RELAX(u, v, w)  
  2.  if d[v] > d[u] + w(u, v)  
  3.    then d[v] ← d[u] + w(u, v)  
  4.       π[v] ← u        //O(E) 

 

一般來說,在Dijkstra 算法中,DECREASE-KEY的調用次數遠多于EXTRACT-MIN的調用,
所以在不增加EXTRACT-MIN 操作的平攤時間前提下,盡量減小DECREASE-KEY操作的平攤時間,都能獲得對比二叉堆更快的實現。

以下,是二叉堆,二項堆,斐波那契堆的各項操作的時間復雜度的比較:

操作                  二叉堆(最壞)       二項堆(最壞)     斐波那契堆(平攤)

MAKE-HEAP        Θ(1)                  Θ(1)                Θ(1)
INSERT               Θ(lg n)              O(lg n)            Θ(1)
MINIMUM           Θ(1)                  O(lg n)             Θ(1)
EXTRACT-MIN     Θ(lg n)              Θ(lg n)            O(lg n)
UNION               Θ(n)                  O(lg n)            Θ(1)
DECREASE-KEY   Θ(lg n)             Θ(lg n)              Θ(1)
DELETE              Θ(lg n)              Θ(lg n)             O(lg n)

斐波那契堆,日后會在本BLOG內,更進一步的深入與具體闡述。且同時,此文,會不斷的加深與擴展。

原文鏈接:http://blog.csdn.net/v_JULY_v/archive/2011/02/13/6182419.aspx

【編輯推薦】

  1. Dijkstra 算法初探
  2. 當今世界最受人們重視的十大經典算法
  3. 在C/C++算法設計中使用任意位寬
  4. 14.8 數值算法的力量(邊欄)
責任編輯:于鐵 來源: CSDN
相關推薦

2011-05-17 14:11:06

Dijkstra

2021-03-10 09:50:15

算法Dijkstra短路問題

2009-11-17 15:13:28

PHP數組

2009-11-19 11:12:13

Oracle LogM

2012-02-06 13:52:32

HibernateJava

2013-01-04 13:22:42

OpenFlowSDN

2023-10-25 09:00:00

算法Dijkstra算法

2021-01-28 10:55:31

算法可視化數據

2009-11-18 11:02:40

Oracle對象特權

2011-08-01 13:57:20

iPhone 網絡

2010-06-07 08:55:50

Hadoop云計算

2010-08-06 12:40:14

Linux NFS

2009-11-18 14:11:10

PHP數組變量

2023-07-10 16:01:17

云數據庫存儲

2010-03-24 13:56:41

云計算

2010-07-27 15:09:31

2010-09-27 10:19:09

DHCP工作流程

2010-09-15 10:29:33

無線Mesh接入技術

2010-04-02 10:43:02

云計算

2013-05-28 10:22:03

點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 羞羞视频网页 | 91在线| 日韩免费视频一区二区 | 国产精品福利在线观看 | 中文字幕精品一区二区三区在线 | 国产在线观看不卡一区二区三区 | 男人的天堂在线视频 | 欧美最猛黑人xxxx黑人 | 一级欧美日韩 | 亚洲不卡在线观看 | 日韩精品久久久久 | 日韩一区二区av | 在线观看欧美一区 | 日韩a级片| 日日骚av| 午夜专区 | 亚洲精品乱码久久久久久按摩观 | 亚洲在线免费观看 | 国产一区二区在线播放视频 | 国产精品一区一区三区 | 999久久久久久久久 国产欧美在线观看 | 国产精品大片在线观看 | 黄色三级毛片 | 久久久久久久久久久久亚洲 | 91精品国产麻豆 | 久久精品一 | 久久免费观看视频 | 亚洲国产乱码 | av免费在线观看网站 | 日日夜夜精品免费视频 | 美人の美乳で授乳プレイ | 97精品国产97久久久久久免费 | 天天搞天天操 | 91精品国产91久久久久久吃药 | 超碰免费观看 | 99精品国产在热久久 | 人人操日日干 | 国产精品高潮呻吟久久 | 91色网站 | 欧美一区二区三区在线播放 | 婷婷一级片 |