該算法可以用來解決一般(邊的權值為負)的單源最短路徑問題,而dijkstra只能解決權值非負的情況。
此算法使用松弛技術,對每一個頂點,逐步減少源到該頂點的路徑的估計值,直到達到最短的路徑。
算法運算結果:
matlab代碼如下,netplot函數在這里,不過當時函數中表示兩節點沒有路徑用的是0,而現在需要改成inf:
clear all;close all;clc %初始化鄰接壓縮表 b=[1 2 6; 1 4 7 2 3 5; 2 4 8; 2 5 -4; 3 2 -2; 4 3 -3; 4 5 9; 5 1 2; 5 3 7]; m=max(max(b(:,1:2))); %壓縮表中最大值就是鄰接矩陣的寬與高 A=compresstable2matrix(b); %從鄰接壓縮表構造圖的矩陣表示 netplot(A,1) %形象表示 S=inf(1,m); %源到其他節點的最短距離,開始為inf S(1)=0; %源點到自己的距離為0 pa=zeros(1,m); %尋找到的節點的前趨 pa(1)=1; %源點的前趨是自己 pre_pa=ones(1,m); while sum(pre_pa==pa)~=m %終止條件,判斷終止的方法很多,這個應該不是最佳實踐 pre_pa=pa; for k=1:m if pre_pa(k)~=0 %對每一個已搜尋到的節點,從此節點尋找后繼節點 i=k; for j=1:m if A(i,j)~=inf if S(j)>S(i)+A(i,j) S(j)=S(i)+A(i,j); %邊緣松弛,取兩節點間最小權值作為實際權值 pa(j)=i; %尋找前趨 end end end end end end %最終我們需要的就是這兩個值 S %源點到其他每一點的距離 pa %其他每一節點的前趨 %算法到此結束,下面只是為了形象的表示而寫的。 re=[]; for i=2:m re=[re;pa(i) i A(pa(i),i)]; end A=compresstable2matrix(re); %從鄰接壓縮表構造圖的矩陣表示 figure; netplot(A,1) %形象表示
compresstable2matrix.m
function A=compresstable2matrix(b) [n ~]=size(b); m=max(max(b(:,1:2))); A=inf(m,m); for i=1:n A(b(i,1),b(i,2))=b(i,3); end end