算法12--最短路径--弗洛伊德(Floyd)算法

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

12
5.算法实现
• 图用邻接矩阵存储 • edge[ ][ ]存放最短路径长度 • path[i][j]是从Vi到Vj的最短路径上Vj前一顶点序号
void floyd ( ){
for ( int i = 0; i < n; i++ ) //矩阵dist与path初始化
for ( int j = 0; j < n; j++ ) { //置A(-1)
路径: BCA
BC
CA CAB
9

6
A4B
11
3
2
C
初始: length=
0 4 11 60 2 3 0
加入A: length=
0 4 11 60 2 3 70
加入B: length=
046 602 370
path=
011 202 300
path=
011 202 310
path=
012 202 3 10
1.第一次,判别( Vi, V0 )和( V0,Vj ),即判别 (Vi, V0 , Vj)是否存在,若存在,则比较( Vi, Vj )和 (Vi, V0 , Vj)的长度,取长度较短的为从Vi到Vj的中间 顶点序号不大于0的最短路径。
2. 第二次,再加一个顶点V1,如果(Vi, … , V1) 和(V1, … , Vj)分别是当前找到的中间顶点序号不 大于0的最短路径,那么(Vi, … , V1, … , Vj )就有 可能是从Vi到Vj的中间顶点序号不大于1的最短路 径。将它和已经得到的从Vi到Vj之间顶点序号不大 于0的最短路径相比较,取较短者为从Vi到Vj的中 间顶点序号不大于1的最短路径。
0 0 1 4 0 1 4 0 1 10 3 0 1 10 3 0 1 9 3 1 0 9 2 0 9 2 0 9 2 12 0 9 2 11 0 8 2 2 35 08 34 0 7 3 4 0 6 3 4 0 6 3 40 6 3 6 0 6 0 6 0 9 10 6 0 9 10 6 0
Path(-1)
Path(0)
Path(1)
Path(2)
Path(3)
01 23 01 2 3 0 1 2 3 0 1 2 3 0 12 3
0 00 00 00 0 0 0 0 1 1 0 0 1 1 0 03 1 1 00 11 00 1 1 0 0 1 1 2 0 1 1 2 03 1 2 22 02 20 0 0 2 0 0 1 2 0 0 1 2 00 1 3 00 30 00 3 0 0 0 3 0 2 0 3 0 2 03 0
dist[i][j] = Edge[i][j];
path[i][j] = -1; } // 初始不经过任何顶点
for ( int k = 0; k < n; k++ ) //产生dist(k)及path(k)
for ( i = 0; i < n; i++ )
for ( j = 0; j < n; j++ )
1.问题的提出:已知一个各边权值均大于0的带权有向
图,对每一对顶点 vi vj,要求求出vi 与vj之间的
最短路径和最短路径长度。
2.解决办法
▪ 方法一:每次以一个顶点为源点,重复执行
Dijkstra算法n次—— T(n)=O(n³)
▪ 方法二:弗洛伊德(Floyd)算法
1
3. Floyd算法思想:逐个顶点试探法
3>,<3, 2>,<2, 0>。
16
3. 第三次,再加一个顶点V2,继续进行试探。
6 V2 8 V3
8
0123 0124 0
3
4 5
2
D(0-1) )==
8
0092 3 45 0 87
1 2
9
V0
V1
8
8
0160 3
1
D(-1)为有向网的邻接矩阵
第一步:以D(-1)为基础,以V0为中间顶点,求从Vi到
Vj的最短路径。该路径或者为从Vi到Vj的边, 或者为
8
0092 3 45 0 687
1 2
9
V0
V1
8
8
0160 3
1
以D(0)为基础,以V1为中间顶点,求从Vi,到Vj的最短
路径。该路径或者为从Vi到Vj的边, 或者为从Vi开始通 过V0或V1到达Vj的最短路径 。
D(1) [i][j] = min{D(0) [i][j], D(0) [i][1]+D(0) [1][j]}
6
0123
V2 8 V3
8
0 1 120 43 0
3
4 52
ADA(((-1201)))==
8
102 0 9 2 3 45 0 687
1 2
9
V0
V1
8
8
90 110 6 0 3
1
以D(1)为基础,以V2为中间顶点,求从Vi,到Vj的最短
路径。或者为从Vi到Vj的边, 或者为从Vi开始通过 V0,V1, V2到达Vj的最短路径 。
证明:归纳证明,始归纳于s (上角标);
(1) 归纳基础:当s=-1 时, A(-1) [i][j]= Edge[i][j], vi 到vj , 不经过任何顶点的边,是最短路径。
(2)归纳假设:当s<k时, A(s) [i][j]是从顶点vi 到vj ,
中间顶点的序号不大于s的最短路径的长度; (3)当s=k时,
例题:
6 A4 3 11
C
初始:
0 6
4 0
11 2
3 0 B
路径: BA CA
AB AC BC
2 0 4 11
加入A: 6 0 2 37 0
ห้องสมุดไป่ตู้
AB AC
路径: BA
BC
CA CAB
04 6 加入B: 6 0 2
37 0
AB ABC
路径: BA
BC
CA CAB
04 6 加入C: 5 0 2
37 0
AB ABC
if (dist[i][k] + dist[k][j] < dist[i][j] ) {
dist[i][j] = dist[i][k] + dist[k][j];
path[i][j] = k; }//缩短路径, 绕过 k 到 j
} // floyd
13
6.算法分析: 设最内层循环体为基本操作,算法有三层循环,
1
以D(2)为基础,以V3为中间顶点,求从Vi,到Vj的最短
路径。或者为从Vi到Vj的边, 或者为从Vi开始通过 V0,V1, V2,V3到达Vj的最短路径 。
D(3) [i][j] = min{D(2) [i][j], D(2) [i][3]+D(2) [3][j]}
D(3) [i][j] 即为从Vi到Vj的最短路径长度.
11
A(k-1) [i][k]
k
A(k-1) [k][j]
i
j
A(k-1) [i][j]
因为:A(k) [i][j] = min { A(k-1)[i][j], A(k-1)[i][k] + A(k-1)[k][j] }
由归纳假设知:
A(k-1)[i][j] :是i到j的最短路径(标号不高于k-1); A(k-1)[i][k] :是i到k的最短路径(标号不高于k-1); A(k-1)[k][j] :是k到j的最短路径(标号不高于k-1); 所以: A(k) [i][j] 是i到j的最短路径(标号不高于k)。
(Vi,V0)+(V0,Vj) 。
D(0) [i][j] = min{D(-1) [i][j], D(-1) [i][0]+D(-1) [0][j]}
D(0) [i][j] 为从Vi到Vj的中间顶点序号不大于0的最短路径长度.
6
0123
V2 8 V3
8
0 1 120 43 0
3
4 52
AD(((-101)))==
加入C: length=
046 502 3 70
path=
012 30 2 310
10
4. 论点:A(-1) [i][j]是从顶点vi 到vj , 中间顶点是 v1的最短路径的长度,A(k) [i][j]是从顶点vi 到vj , 中间顶点的序号不大于k的最短路径的长度, A(n-1)[i][j]是从顶点vi 到vj 的最短路径长度。
D(2) [i][j] = min{D(1) [i][j], D(1) [i][2]+D(1) [2][j]}
6
0123
V2 8 V3
8
0 1 1920 43 0
3
4 52
ADA(((-32101)))==
8
11021 0 98 2 3 45 0 687
1 2
9
V0
V1
8
8
90 110 6 0 3
以 Path(3)为例,对最短路径的读法加以说明。从A(3)知,顶点1 到0的最短路径长度为a[1][0] = 11, 其最短路径看 path[1][0] = 2,path[1][2] = 3,path [1][3] = 1, 表示 顶点0 顶点2 顶点3 顶点1;从顶点1到顶点0最短路径为<1,
–求最短路径步骤 •初始时设置一个n阶方阵,令其对角线元素为0 ,若存在弧<Vi,Vj>,则对应元素为权值;否则 为 •逐步试着在原直接路径中增加中间顶点,若加 入中间点后路径变短,则修改之;否则,维持 原值 •所有顶点试探完毕,算法结束
2
从图的带权邻接矩阵G.arcs出发,假设求顶点 Vi到Vj的最短路径。如果从Vi到Vj有弧,则从Vi 到Vj存在一条长度为G.arcs[i][j]的路径,但该路 径是否一定是最短路径,还需要进行n次试探。
每层循环n次,所以T(n)=O(n3)
14
A(-1)
A(0)
A(1)
A(2)
A(3)
01 23 01 2 3 0 1 2 3 0 1 2 3 0 12 3
0 0 1 4 0 1 4 0 1 10 3 0 1 10 3 0 1 9 3
1 0 9 2 0 9 2 0 9 2 12 0 9 2 11 0 8 2
2 35 08 34 0 7 3 4 0 6 3 4 0 6 3 40 6
3 6 0 6 0 6 0 9 10 6 0 9 10 6 0
Path(-1)
Path(0)
Path(1)
Path(2)
Path(3)
01 23 01 2 3 0 1 2 3 0 1 2 3 0 12 3
0 00 00 00 0 0 0 0 1 1 0 0 1 1 0 03 1
1 00 11 00 1 1 0 0 1 1 2 0 1 1 2 03 1
2 22 02 20 0 0 2 0 0 1 2 0 0 1 2 00 1
3 00 30 00 3 0 0 0 3 0 2 0 3 0 2 03 0
15
A(-1)
A(0)
A(1)
A(2)
A(3)
01 23 01 2 3 0 1 2 3 0 1 2 3 0 12 3
相关文档
最新文档