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