matlab練習程序(單源最短路徑Dijkstra)


圖的相關算法也算是自己的一個軟肋了,當年沒選修圖論也是一大遺憾。

圖像處理中,也有使用圖論算法作為基礎的相關算法,比如圖割,這個算法就需要求最大流、最小割。所以熟悉一下圖論算法對於圖像處理還是很有幫助的。

Dijkstra和Bellman-Ford類似,都是解決單源最短路徑問題,不同的是這個方法只能解決邊為非負的問題,實現的好的Dijkstra算法運行時間要快於Bellman-ford。

算法步驟如下:

1.首先設置隊列,所有節點入列,源節點值為0,其他節點值為無窮。

2.然后在隊列中找值最小的節點並出列。

3.計算出列的節點所有后繼節點的距離。

4.松弛方法,如果新計算的距離小於上次計算的距離,那么更新距離,即將后繼節點值設為較小的距離,並將后繼節點的前趨設為當前的出列節點。

5.對剩余的節點隊列繼續找最小值並出列,不斷循環2、3、4步直到隊列中沒有節點了。

步驟是上面沒錯,不過我程序中沒有完全按照上述的步驟實現。不同的地方在於我沒有做出列操作,而是通過標記節點的形式實現的。

運行結果如下,圖(是圖不是圖片)是算法導論367頁上的:

matlab代碼如下,netplot和compresstable2matrix和上一篇使用的一樣:

main.m

clear all;close all;clc
%初始化鄰接壓縮表,1 2 10 表示從節點1到節點2,邊的權重為10
b=[1 2 10;1 4 5;2 3 1;
   2 4 2; 3 5 4;4 2 3;
   4 3 9; 4 5 2;5 1 7;
   5 3 6];

m=max(max(b(:,1:2)));       %壓縮表中最大值就是鄰接矩陣的寬與高
A=compresstable2matrix(b);  %從鄰接壓縮表構造圖的矩陣表示
netplot(A,1)                %形象表示

S=inf(1,m);         %從開始的源點到每一個節點的距離
S(1)=0;             %源點到自己的距離為0
pa=zeros(1,m);      %存儲每個節點的前驅,在松弛過程中賦值
pa(1)=1;       %源點的前趨是自己 
visit
=zeros(1,m); %標記某個節點是否訪問過了 index=1; %從index節點開始搜索 %判斷是否對所有節點都找的最短路徑了。可能會有源點沒有路徑到目標節點的情況,那就無限循環了 while sum(visit)~=m %沒有出隊列操作,不過通過visit來等價的表示了 visit(index)=1; %標記第index節點為已入列的節點 [S pa]=relax(S,pa,A,visit,index,m); %松弛,如果兩個節點間有更短的距離,則用更短的距離 index=extract_min(S,visit,index,m); %使用已訪問的最小的節點作為下一次搜索的開始節點 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) %形象表示

relax.m

%邊緣松弛,使用更短的距離作為節點的值
function [S pa]=relax(S,pa,A,visit,index,m)
   
   i=index;
   for j=1:m
        if A(i,j)~=inf && visit(j)~=1   %搜索沒有標記過的節點
            if S(j)>S(i)+A(i,j)         %將較小的值賦給正在搜尋的節點
                S(j)=S(i)+A(i,j);
                pa(j)=i;
            end
        end        
    end    

end

extract_min.m

%提取隊列中尚未標記的最小的值的序號
function index=extract_min(S,visit,index,m)

    Mi=inf;
    for j=1:m
        if visit(j)~=1
           if S(j)<Mi
                Mi=S(j);
                index=j;
           end
        end
    end    

end

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM