简介
Floyd算法又称为插点法,是一种利用动态规划的思想寻找给定的加权图中多源点之间最短路径的算法,与Dijkstra算法类似。该算法名称以创始人之一、1978年图灵奖获得者、斯坦福大学计算机科学系教授罗伯特·弗洛伊德命名。
算法过程及优缺点
1,从任意一条单边路径开始。所有两点之间的距离是边的权,如果两点之间没有边相连,则权为无穷大。
2,对于每一对顶点 u 和 v,看看是否存在一个顶点 w 使得从 u 到 w 再到 v 比已知的路径更短。如果是更新它。
把图用邻接矩阵G表示出来,如果从Vi到Vj有路可达,则G[i][j]=d,d表示该路的长度;否则G[i][j]=无穷大。定义一个矩阵D用来记录所插入点的信息,D[i][j]表示从Vi到Vj需要经过的点,初始化D[i][j]=j。把各个顶点插入图中,比较插点后的距离与原来的距离,G[i][j] = min( G[i][j], G[i][k]+G[k][j] ),如果G[i][j]的值变小,则D[i][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直接相连。
优缺点:
Floyd算法适用于APSP(AllPairsShortestPaths),是一种动态规划算法,稠密图效果最佳,边权可正可负。此算法简单有效,由于三重循环结构紧凑,对于稠密图,效率要高于执行|V|次Dijkstra算法。
优点:容易理解,可以算出任意两个节点之间的最短距离,代码编写简单
缺点:时间复杂度比较高,不适合计算大量数据。
时间复杂度:O(n^3);空间复杂度:O(n^2);
任意节点i到j的最短路径两种可能:
- 直接从i到j;
- 从i经过若干个节点k到j。
实例
120 | 40 | |||
---|---|---|---|---|
120 | 40 | 20 | ||
30 | 20 | 30 | ||
40 | 20 | |||
20 | 30 |
clc,clear; n=5;sb=1;db=5; % sb起点标号,db终点标号 a=zeros(n); a(1,3)=40;a(1,2)=120; a(2,5)=20;a(2,4)=40; a(3,4)=20;a(3,5)=30; a = a+a'; a(a==0)=inf; a([1:n+1:n^2])=0; %对角线元素替换成0 path=zeros(n); for k=1:n for i=1:n for j=1:n if a(i,j)>a(i,k)+a(k,j) a(i,j)=a(i,k)+a(k,j); path(i,j)=k; end end end end %a,path dist=a(sb,db); parent=path(sb,:); parent(parent==0)=sb; mypath=db;t=db; while t~=sb p=parent(t);mypath=[p,mypath]; t=p; end path,mypath
Lingo
1.@text函数
该函数被用在数据部分用来把解输出至文本文件中。它可以输出集成员和集属性值。其语法为
@text([’filename’])
这里filename是文件名,可以采用相对路径和绝对路径两种表示方式。如果忽略filename,那么数据就被输出到标准输出设备(大多数情形都是屏幕)。@text函数仅能出现在模型数据部分的一条语句的左边,右边是集名(用来输出该集的所有成员名)或集属性名(用来输出该集属性的值)。
我们把用接口函数产生输出的数据声明称为输出操作。输出操作仅当求解器求解完模型后才执行,执行次序取决于其在模型中出现的先后。
model: sets: nodes/c1..c5/; link(nodes,nodes):w,path; endsets data: path=0; w=0; @text(mydata1.txt)=@writefor(nodes(i):@writefor(nodes(j):@format(w(i,j),'10.0f')),@newline(1)); @text(mydata1.txt)=@write(@newline(1)); @text(mydata1.txt)=@writefor(nodes(i):@writefor(nodes(j):@format(path(i,j),'10.0f')),@newline(1)); enddata calc: w(1,3)=40;W(1,2)=120; w(2,5)=20;w(2,4)=40; w(3,4)=20;w(3,5)=30; @for(link(i,j):w(i,j)=w(i,j)+w(j,i)); @for(link(i,j):w(i,j)=@if(w(i,j) #eq# 0,1000,w(i,j))); @for(nodes(k):@for(nodes(i):@for(nodes(j): tm=@smin(w(i,j),w(i,k)+w(k,j)); path(i,j)=@if(w(i,j)#gt#tm,k,path(i,j));w(i,j)=tm))); endcalc end
mydata1.txt 内容如下:
C++
#include<fstream> #define Maxm 501 using namespace std; ifstream fin("APSP.in.txt"); ofstream fout("APSP.out.txt"); int p, q, k, m; int Vertex, Line[Maxm]; int Path[Maxm][Maxm], Map[Maxm][Maxm], Dist[Maxm][Maxm]; void Root(int p, int q) { if (Path[p][q] > 0) { Root(p, Path[p][q]); Root(Path[p][q], q); } else { Line[k] = q; k++; } } int main() { memset(Path, 0, sizeof(Path)); memset(Map, 0, sizeof(Map)); memset(Dist, 0, sizeof(Dist)); fin >> Vertex; for (p = 1; p <= Vertex; p++) for (q = 1; q <= Vertex; q++) { fin >> Map[p][q]; Dist[p][q] = Map[p][q]; } for (k = 1; k <= Vertex; k++) for (p = 1; p <= Vertex; p++) if (Dist[p][k] > 0) for (q = 1; q <= Vertex; q++) if (Dist[k][q] > 0) { if (((Dist[p][q] > Dist[p][k] + Dist[k][q]) || (Dist[p][q] == 0)) && (p != q)) { Dist[p][q] = Dist[p][k] + Dist[k][q]; Path[p][q] = k; } } for (p = 1; p <= Vertex; p++) { for (q = p + 1; q <= Vertex; q++) { fout << "\n==========================\n"; fout << "Source:" << p << '\n' << "Target " << q << '\n'; fout << "Distance:" << Dist[p][q] << '\n'; fout << "Path:" << p; k = 2; Root(p, q); for (m = 2; m <= k - 1; m++) fout << "-->" << Line[m]; fout << '\n'; fout << "==========================\n"; } } fin.close(); fout.close(); return 0; }
结果(APSP.out.txt):
========================== Source:1 Target 2 Distance:90 Path:1-->3-->5-->2 ========================== ========================== Source:1 Target 3 Distance:40 Path:1-->3 ========================== ========================== Source:1 Target 4 Distance:60 Path:1-->3-->4 ========================== ========================== Source:1 Target 5 Distance:70 Path:1-->3-->5 ========================== ========================== Source:2 Target 3 Distance:50 Path:2-->5-->3 ========================== ========================== Source:2 Target 4 Distance:40 Path:2-->4 ========================== ========================== Source:2 Target 5 Distance:20 Path:2-->5 ========================== ========================== Source:3 Target 4 Distance:20 Path:3-->4 ========================== ========================== Source:3 Target 5 Distance:30 Path:3-->5 ========================== ========================== Source:4 Target 5 Distance:50 Path:4-->3-->5 ==========================