1、通过一个图的权值矩阵求出它的每两点间的最短路径矩阵。从图的带权邻接矩阵A=a(i,j) nn开始,递归地进行n次更新,即由矩阵D(0)=A,按一个公式,构造出矩阵D(1);又用同样地公式由D(1)构造出D(2);最后又用同样的公式由D(n-1)构造出矩阵D(n)。矩阵D(n)的i行j列元素便是i号顶点到j号顶点的最短路径长度,称D(n)为图的距离矩阵,同时还可引入一个后继节点矩阵path来记录两点间的最短路径。采用的是松弛技术,对在i和j之间的所有其他点进行一次松弛。所以时间复杂度为O(n3);其状态转移方程如下: mapi,j:=minmapi,k+mapk,j,mapi,j mapi,j表
2、示i到j的最短距离 K是穷举i,j的断点 mapn,n初值应该为0,或者按照题目意思来做。当然,如果这条路没有通的话,还必须特殊处理,比如没有mapi,k这条路 2.3、优缺点分析Floyd算法适用于APSP(All Pairs Shortest Paths),是一种动态规划算法,稠密图效果最佳,边权可正可负。此算法简单有效,由于三重循环结构紧凑,对于稠密图,效率要高于执行|V|次Dijkstra算法。优点:容易理解,可以算出任意两个节点之间的最短距离,代码编写简单;缺点:时间复杂度比较高,不适合计算大量数据。三、算法过程把图用邻接矩阵G表示出来,如果从Vi到Vj有路可达,则Gi,j=d,d表
3、示该路的长度;否则Gi,j=空值。定义一个矩阵D用来记录所插入点的信息,Di,j表示从Vi到Vj需要经过的点,初始化Di,j=j。把各个顶点插入图中,比较插点后的距离与原来的距离,Gi,j = min( Gi,j, Gi,k+Gk,j ),如果Gi,j的值变小,则Di,j=k。在G中包含有两点之间最短道路的信息,而在D中则包含了最短通路径的信息。比如,要寻找从V5到V1的路径。根据D,假如D(5,1)=3则说明从V5到V1经过V3,路径为V5,V3,V1,如果D(5,3)=3,说明V5与V3直接相连,如果D(3,1)=1,说明V3与V1直接相连。四、算法实现4.1、c语言程序:#include
4、conio.hstdlib.h#define N 100 /可计算的最大的路由结点数为100double wNN,tempwNN; /w最短径长 tempw临时int rNN,temprNN,i,j,k,m=7; /r转接路由void TestAlgorithm();/测试算法是否正确 double minnb(double k1,double k2);/求最小值void InputTheNet();/输入路由节点及花费 void Initprint();/打印R0 W0 void savesw(); /保存临时值void resultw();/求W矩阵的值void resultr();/求R
5、矩阵的值/-主函- void main() TestAlgorithm();/使用固定的路由花费测试算法是否正确 InputTheNet(); Initprint();/打印初始路由表(R0 W0) savesw();/*保存W R 矩阵的值 for(k=0;km;k+) resultw();/求W矩阵 resultr();/求R矩阵 /保存 R W矩阵的值 printf(n); void InputTheNet() nn请输入节点数: scanf(%d,&m); nn请输入各结点间的路由花费nn for(i=0;ii+) wii=0; for(j=i+1;j第%d节点:,i+1,j+1);%
6、lfwij);for(i=0;i+)/转换成路由花费表 for(j=0;i; wij=wji; /*打印你输入的路由表* void Initprint() nW0矩阵n for(j=0; if(wij=-1) $ else %9.1f,wij);n*n if(wij0) rij=j+1; rij=0;printf(nR0矩阵n for(j=0;%9d,rij);/* /* / 求W矩阵void resultw() printf(n W%d矩阵的值n,k+1);wij=minnb(tempwij,tempwik+tempwkj);else printf(-void resultr() n r%d
7、矩阵的值ni+) if(wij=tempwij) rij=temprij; if(tempwij=-1) rij=k+1; if(wij!=-1)&(wijk2) ret=k2;else ret=k1; return ret; /*测试算法*void TestAlgorithm() /-1为$ 代表无穷double w177= 0, -1, -1,1.2, 9.2, -1, 0.5, -1, 0, -1, 5, -1,3.1, 2 , -1, -1, 0, -1, -1, 4, 1.5, 1.2, 5, -1, 0, 6.7, -1, -1, 9.2, -1, -1,6.7, 0,15.6,
8、-1, -1,3.1, 4,-1,15.6, 0, -1, 0.5, 2,1.5, -1, -1, -1, 0, ;char ch;是否进行算法测试?Y/N do fflush(stdin); / 清除文件缓冲区,文件以写方式打开时将缓冲区内容写入文件 ch=getchar(); while(ch!=ych!YnN if(ch=|ch=) n 已跳过测试程序 ! return ;7; wij=w1ij; /要测试的复制给w1/打印路由表(R0 W0) n以上是要测试的固定的路由花费表nn按任意键进行测试n getch();k+) nn测试完毕,以上是测试结果!nnsystem(pause4.2
9、、Matlab程序及其分析 第一步:function D,R=floyd(A)%用floyd算法实现求任意两点之间的最短路程。%参数D为连通图的权矩阵 A=0 3 inf inf inf inf inf 3 0 2 inf inf 1.5 inf inf 2 0 6 inf 2.5 4 inf inf 6 0 inf inf 3 inf inf inf inf 0 1.5 inf inf 1.5 2.5 inf 1.5 0 1.8 inf inf 4 3 inf 1.8 0 ;D=A;n=length(D);for i=1:n for j=1:n R(i,j)=i;%赋路径初值 endendf
10、or k=1: for i=1: if D(i,k)+D(k,j)D(i,j) D(i,j)=D(i,k)+D(k,j);%更新 D(i,j),说明通过k的路程更短 R(i,j)=R(k,j);%更新R(i,j),需要通过k 第二步:对于第一问在矩阵D中每一行取大得到一列数,再在这列数中取小,m,n=size(D);p=;m p(i)=max(D(i,:);end if p(i)=min(p) disp(i);min(p)运行结果:D,R=floyd() 6ans = 4.8000D = 0 3.0000 5.0000 9.3000 6.0000 4.5000 6.3000 3.0000 0
11、2.0000 6.3000 3.0000 1.5000 3.3000 5.0000 2.0000 0 6.0000 4.0000 2.5000 4.0000 9.3000 6.3000 6.0000 0 6.3000 4.8000 3.0000 6.0000 3.0000 4.0000 6.3000 0 1.5000 3.3000 4.5000 1.5000 2.5000 4.8000 1.5000 0 1.8000 6.3000 3.3000 4.0000 3.0000 3.3000 1.8000 0R = 1 1 2 7 6 2 6 2 2 2 7 6 2 6 2 3 3 3 6 3 3 2 6 4 4 6 7 4 2 6 6 7 5 5 6 2 6 6 7 6 6 6 2 6 7 7 6 7 7结论:在顶点6建立银行,最大服务距离最小,最小是4.8.
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1