赞
踩
Floyd算法又称为插点法,是一种利用动态规划的思想寻找给定的加权图中多源点之间最短路径的算法,与Dijkstra算法类似。该算法名称以创始人之一、1978年图灵奖获得者、斯坦福大学计算机科学系教授罗伯特·弗洛伊德命名。
Floyd算法可以给出网络中任意两个节点之间的最短路径,因此它是比Dijkstra更一般的算法。Floyd算法的思想是将n个节点的网络表示为n行n列的矩阵,而矩阵中的元素(i,j)表示从节点i到节点j的距离dij,如果两点直接没有边相连,则相应的元素就是无穷(∞).
定义n×n的方阵序列D-1, D0 , … Dn-1,
初始化: D-1=C
迭代:设Dk-1已求出,如何得到Dk(0≤k≤n-1)?
因为q的两条子路径i…k和k…j皆是中间点不大于k-1的最短路径,所以从i到j中间点不大于k的最短路径长度为:
Dk[i][j]=min{ Dk-1[i][j], Dk-1[i][k] +Dk-1[k][j] }
注:Floyd算法可以存在负权重
function
Floyd(w,router_direction,MAX)
%w为此图的距离矩阵
%router_direction为路由类型:
0
为前向路由;非
0
为回溯路由
%MAX是数据输入时的∞的实际值
len=length(w);
flag=zeros(
1
,len);
%根据路由类型初始化路由表
R=zeros(len,len);
for
i=
1
:len
if
router_direction==
0
%前向路由
R(:,i)=ones(len,
1
)*i;
else
%回溯路由
R(i,:)=ones(len,
1
)*i;
end
R(i,i)=
0
;
end
disp(
''
);
disp(
'w(0)'
);
dispit(w,
0
);
disp(
'R(0)'
);
dispit(R,
1
);
%处理端点有权的问题
for
i=
1
:len
tmp=w(i,i)/
2
;
if
tmp~=
0
w(i,:)=w(i,:)+tmp;
w(:,i)=w(:,i)+tmp;
flag(i)=
1
;
w(i,i)=
0
;
end
end
%Floyd算法具体实现过程
for
i=
1
:len
for
j=
1
:len
if
j==i || w(j,i)==MAX
continue;
end
for
k=
1
:len
if
k==i || w(j,i)==MAX
continue;
end
if
w(j,i)+w(i,k)<w(j,k) %Floyd算法核心代码
w(j,k)=w(j,i)+w(i,k);
if
router_direction==
0
%前向路由
R(j,k)=R(j,i);
else
%回溯路由
R(j,k)=R(i,k);
end
end
end
end
%显示每次的计算结果
disp([
'w('
,num2str(i),
')'
])
dispit(w,
0
);
disp([
'R('
,num2str(i),
')'
])
dispit(R,
1
);
end
%中心和中点的确定
[Center,index]=min(max(w'));
disp([
'中心是V'
,num2str(index)]);
[Middle,index]=min(sum(w'));
disp([
'中点是V'
,num2str(index)]);
end
function
dispit(x,flag)
%x:需要显示的矩阵
%flag:为
0
时表示显示w矩阵,非
0
时表示显示R矩阵
len=length(x);
s=[];
for
j=
1
:len
if
flag==
0
s=[s sprintf(
'%5.2f\t'
,x(j,:))];
else
s=[s sprintf(
'%d\t'
,x(j,:))];
end
s=[s sprintf(
'\n'
)];
end
disp(s);
disp(
'---------------------------------------------------'
);
end
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。