1. 程式人生 > >Matlab計算最短路徑及路徑的個數

Matlab計算最短路徑及路徑的個數

    最近老闆讓計算最短路徑及路徑個數,找遍了所有工具箱,都沒現成的。急死了,什麼Dijkstra和Floyd都搞不定。最後,想了想,算了吧,自己編吧,反正自己用,又沒有演算法複雜度要求。於是自己就寫了個小程式(本程式僅限無權無向連通圖),演算法複雜度不曉得(偷笑)。

   本人不是計算機出身,就不寫演算法步驟了,直接上圖解。


   我們首先計算的是節點1到所有節點的最短路徑,及個數。s存放節點1到所有節點的最短路徑,p_num存放路徑的個數。

   初始化:s=[0,0,0,0,0,0,0]      p_num=[1,0,0,0,0,0,0]

    第一輪迭代:找節點1的所有鄰居節點2,3,4。則:s([2,3,4])=1

                            在看節點2的鄰居1和5.則: p_num(2)= p_num(1)+ p_num(5)=1+0=1

                            同理:p_num(3)=p_num(4)=1

                            則本輪會得到:s=[0,1,1,1,0,0,0]      p_num=[1,1,1,1,0,0,0]

    第二輪迭代:找節點2,3,4的所有鄰居節點(沒有被找過的節點)5,6。則:s([5,6])=2

                            再看節點5的鄰居2,3和7.則: p_num(5)= p_num(2)+ p_num(3)+ p_num(7)=1+1+0=2

                            同理:p_num(6)=1

                            則本輪會得到:s=[0,1,1,1,2,2,0]      p_num=[1,1,1,1,2,1,0]

    第三輪迭代:找節點5,6的所有鄰居節點(沒有被找過的節點)7。則:s([7])=3

                            在看節點7的鄰居5和6.則: p_num(2)= p_num(5)+ p_num(6)=2+1=3

                            則本輪會得到:s=[0,1,1,1,2,2,3]      p_num=[1,1,1,1,2,1,3]

   找節點7的所有鄰居節點(沒有被找過的節點),沒啦,迭代終止。哈哈節點到所有節點的最短路徑及條數搞定,然後來個迴圈就把任意兩個點的最短路徑及個數搞定。

  哇嘎嘎,簡單粗暴,下面有程式,能力有限。使用前記得要仔細拍錯誤哦哦

function [all_s,all_p_num]=all_node_shortest(w)
    %全聯通無權無向圖
    %輸入鄰接矩陣w
    %all_s為所有節點間的最短距離
    %all_p_num為最短路徑的個數
    %樹狀搜尋(純屬自己想的,沒有優化,可以跑小網路)
    n=length(w);                    %節點的個數
    all_s=zeros(n,n);               %初始化
    all_p_num=zeros(n,n);       %初始化
    for i=1:n
        [s,p_num]=node_shortest(w,i);
        all_s(i,:)=s;
        all_p_num(i,:)=p_num;   
    end


end


function [s,p_num]=node_shortest(w,node)
    %全聯通無權無向圖
    %輸入鄰接矩陣w
    %初始節點 node
    %s為node到所有節點的最短距離
    %p_num為最短路徑的個數
    %樹狀搜尋(純屬自己想的)
    n=length(w);                    %節點的個數
    s=zeros(1,n);                   %初始化
    p_num=zeros(1,n);               %初始化
    p_num(node)=1;                %node到node本身距離為零,個數記為1           
    node_all=zeros(1,n);               
    node_all(node)=1;               %記錄哪些節點被搜尋到,搜尋到的節點記為1,否則為0
    lj=node;                        %lj為當前步到達的節點(到lj的距離都為k)
    k=1;
    while sum(node_all)<n           %搜尋至所有節點停止迭代
        lj=find(sum(w(lj,:),1)>0&node_all==0);      %上一時刻的所有節點的鄰居且沒有被找到過的節點是這一次的鄰居
        s(lj)=k;                                    %記錄時刻即路徑長度               
        p_num(lj)=sum(w(:,lj).*repmat(p_num',[1,length(lj)]),1); %這一時刻的路徑的條數為:這個節點上一時刻已經到達的鄰居的所有路徑和
        node_all(lj)=1;                                          %這些節點在這個時刻已經被找到
        k=k+1;                                                   %下一時刻
    end
end