迪傑斯特拉(Dijkstra)算法是典型最短路徑算法,用於計算一個節點到其他節點的最短路徑。
它的主要特點是以起始點為中心向外層層擴展(廣度優先搜索思想),直到擴展到終點為止。
基本思想
通過Dijkstra計算圖G中的最短路徑時,需要指定起點s(即從頂點s開始計算)。
此外,引進兩個集合S和U。S的作用是記錄已求出最短路徑的頂點(以及相應的最短路徑長度),而U則是記錄還未求出最短路徑的頂點(以及該頂點到起點s的距離)。
初始時,S中只有起點s;U中是除s之外的頂點,並且U中頂點的路徑是"起點s到該頂點的路徑"。然后,從U中找出路徑最短的頂點,並將其加入到S中;接着,更新U中的頂點和頂點對應的路徑。 然后,再從U中找出路徑最短的頂點,並將其加入到S中;接着,更新U中的頂點和頂點對應的路徑。 ... 重復該操作,直到遍歷完所有頂點。
操作步驟
(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),直到遍歷完所有頂點。
MATLAB代碼實現如下:
function [mydistance,mypath]=mydijkstra(a,sb,db); % 輸入:a—鄰接矩陣(aij)是指i到j之間的距離,可以是有向的 % sb—起點的標號, db—終點的標號 % 輸出:mydistance—最短路的距離, mypath—最短路的路徑 n=size(a,1); visited(1:n) = 0; distance(1:n) = inf; % 保存起點到各頂點的最短距離 distance(sb) = 0; parent(1:n) = 0; for i = 1: n-1 temp=distance; id1=find(visited==1); %查找已經標號的點 temp(id1)=inf; %已標號點的距離換成無窮 [t, u] = min(temp); %找標號值最小的頂點 visited(u) = 1; %標記已經標號的頂點 id2=find(visited==0); %查找未標號的頂點 for v = id2 if a(u, v) + distance(u) < distance(v) distance(v) = distance(u) + a(u, v); %修改標號值 parent(v) = u; end end end mypath = []; if parent(db) ~= 0 %如果存在路! t = db; mypath = [db]; while t ~= sb p = parent(t); mypath = [p mypath]; t = p; end end mydistance = distance(db); return