Python實現迪傑斯特拉演算法

2021-09-12 18:22:50 字數 2496 閱讀 9031

一、 迪傑斯特拉演算法思想

dijkstra演算法主要針對的是有向圖的單元最短路徑問題,且不能出現權值為負的情況!dijkstra演算法類似於貪心演算法,其應用根本在於最短路徑的最優子結構性質。

最短路徑的最優子結構性質:

如果p(i,j)=是從頂點i到j的最短路徑,k和s是這條路徑上的乙個中間頂點,那麼p(k,s)必定是從k到s的最短路徑。

證明:

假設p(i,j)=是從頂點i到j的最短路徑,則有p(i,j)=p(i,k)+p(k,s)+p(s,j)。而p(k,s)不是從k到s的最短距離,那麼必定存在另一條從k到s的最短路徑p(k,s),那麼p(i,j)=p(i,k)+p(k,s)+p(s,j)因此,dijkstra演算法描述如下:

dijikstra演算法描述如下:

假設存在g=,源頂點為v0,s=,distance[i]記錄v0到i的最短距離,matrix[i][j]記錄從i到j的邊的權值,即兩點之間的距離。

1)從v-s中選擇使dist[i]值最小的頂點i,將i加入到u中;

2)更新與i直接相鄰頂點的dist值。dist[j]=min

3)直到s=v,所有頂點都包含進來了,演算法停止。

二、 具體操作步驟

根據其演算法思想,確立操作步驟如下:

(1) 初始時,s只包含起點s;u包含除s外的其他頂點,且u中頂點的距離為"起點s到該頂點的距離"[例如,u中頂點v的距離為(s,v)的長度,然後s和v不相鄰,則v的距離為∞]。

(2) 從u中選出"距離最短的頂點k",並將頂點k加入到s中;同時,從u中移除頂點k。

(3) 更新u中各個頂點到起點s的距離。之所以更新u中頂點的距離,是由於上一步中確定了k是求出最短路徑的頂點,從而可以利用k來更新其它頂點的距離;例如,(s,v)的距離可能大於(s,k)+(k,v)的距離。

(4) 重複步驟(2)和(3),直到遍歷完所有頂點。

三、 python原始碼

圖使用鄰接矩陣儲存,本部分**改編自巫澤俊《挑戰程式設計競賽第2版》

# _*_ encoding:utf-8 _*_

# 輔助資訊

# 圖中的頂點數

v = 7

# 標記陣列:used[v]值為false說明改頂點還沒有訪問過,在s中,否則在u中!

used = [false for _ in range(v)]

# 距離陣列:distance[i]表示從源點s到i的最短距離,distance[s]=0

distance = [float('inf') for _ in range(v)]

# cost[u][v]表示邊e=(u,v)的權值,不存在時設為inf

cost = [[float('inf') for _ in range(v)] for _ in range(v)]

def dijkstra(s):

distance[s] = 0

while true:

# v在這裡相當於是乙個哨兵,對包含起點s做統一處理!

v = -1

# 從未使用過的頂點中選擇乙個距離最小的頂點

for u in range(v):

if not used[u] and (v == -1 or distance[u] < distance[v]):

v = u

if v == -1:

# 說明所有頂點都維護到s中了!

break

# 將選定的頂點加入到s中, 同時進行距離更新

used[v] = true

# 更新u中各個頂點到起點s的距離。之所以更新u中頂點的距離,是由於上一步中確定了k是求出最短路徑的頂點,從而可以利用k來更新其它頂點的距離;例如,(s,v)的距離可能大於(s,k)+(k,v)的距離。

for u in range(v):

distance[u] = min(distance[u], distance[v] + cost[v][u])

if __name__ == '__main__':

for _ in range(12):

v, u, w = list(map(int, input().split()))

cost[v][u] = w

s = int(input('請輸入乙個起始點:'))

dijkstra(s)

print(distance)

四、 原始碼分析

資料結構:cost鄰接矩陣儲存的是圖中邊的資訊;distance距離陣列維護的是從源起點s到其他頂點的最短距離,是乙個頻繁變動的資料結構;used布林陣列標記了頂點有沒有使用過,即used陣列中值為true的頂點元素加入到了s中,值為false的頂點元素加入到了u中,最後所有頂點加入到s中即used的所有元素值為false。同時初始化是將cost所有邊權重初始化為無窮大,float(『inf』

頂點編號為0,1,2…v-1,為了對包括起點在內的所有頂點統一處理,設定了乙個哨兵v(初始化為-1),哨兵v代表每次篩選出來的要加入到s中的距離最小的頂點元素,同時,如果所有頂點都加入到s中後,v的值仍為-1,可以做為迴圈結束的標記!

迪傑斯特拉演算法

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,這個向量儲存的是其他點的最短距離,初...