弗洛伊德算法(Floyd)
\qquad 上一篇文章介绍了迪杰斯特拉算法(Dijkstra)。具体请看:最短路径算法——简单明了的迪杰斯特拉算法(Dijkstra)。Dijkstra适用于非负权图,并且一次只能从网络中找源点到任何一个节点的最短路径,而Floyd算法的应用更加广泛,可以求网络中任意两点之间的最短路径,而且弗洛伊德算法适用于负权图,这篇文章就用图和表的形式来介绍一下弗洛伊德算法!
1 思想(原理)
\qquad Floyd算法可以给出网络中任意两个节点之间的最短路径,因此它是比Dijkstra更一般的算法。Floyd算法的思想是将 n n n个节点的网络表示为 n n n行 n n n列的矩阵,而矩阵中的元素 ( i , j ) (i,j) (i,j)表示从节点 i i i到节点 j j j的距离 d i j d_{ij} dij,如果两点直接没有边相连,则相应的元素就是无穷 ( ∞ ) (\infty) (∞).
2 步骤
<1> 第0步:定义初始距离矩阵
D
0
D_0
D0、节点序列矩阵
S
0
S_0
S0,如下表。对角线上用”—“表示不需要从自身到自身。
\qquad 这里的节点序列矩阵相当于路线表,如下表, S i j = j S_{ij}={j} Sij=j表示,从节点 i i i到节点 j j j只需经过节点 j j j即可。
令 k = 1 k=1 k=1.
<2> 一般的第k步:令第 k k k行为枢轴行,第 k k k列为枢轴列。对于矩阵 D k − 1 D_{k-1} Dk−1(上一步完成后的矩阵)中对的每一个元素做三重操作。
如果满足条件:
d
i
k
+
d
k
j
<
d
i
j
(
i
≠
k
,
j
≠
k
,
i
≠
j
)
d_{ik}+d_{kj}<d_{ij} \qquad (i≠k,j≠k,i≠j)
dik+dkj<dij(i=k,j=k,i=j)
则进行下面的操作:
<\a> 用
d
i
k
+
d
k
j
d_{ik}+d_{kj}
dik+dkj代替矩阵
D
k
−
1
D_{k-1}
Dk−1中的元素
d
i
j
d_{ij}
dij,从而得到矩阵
D
k
D_k
Dk.
<\b> 用
k
k
k代替矩阵
S
k
−
1
S_{k-1}
Sk−1中的元素
s
i
j
s_{ij}
sij,从而得到矩阵
S
k
S_k
Sk.
<\c> 令
k
=
k
+
1
k=k+1
k=k+1,如果
k
=
n
+
1
k=n+1
k=n+1,停止,否则重复<2>.
3 栗子
\qquad
直接看方法步骤会感觉太抽象,这里用一个例子进行步骤的演示.
\qquad
对下图中的网络,求任意两个节点之间的最短路径,图中弧上给出了相应节点间的距离。弧(3,5)是有向的,其他边都是双边。
迭代0:矩阵
D
0
D_0
D0和
S
0
S_0
S0代表初始的网络。可以看到矩阵
D
0
D_0
D0除了
d
53
=
∞
d_{53}=∞
d53=∞外(因为弧(3,5)是单向弧),
D
0
D_0
D0是对称的。
迭代1:令 k = 1 k=1 k=1. D 0 D_0 D0矩阵中的黄色阴影表示的第1行和第1列为枢轴行和枢轴列。根据三重操作发现可以改进的元素是 d 23 d_{23} d23和 d 32 d_{32} d32,即
(1)
d
21
+
d
13
=
3
+
10
<
∞
d_{21}+d_{13}=3+10<∞
d21+d13=3+10<∞,则在
d
23
d_{23}
d23中用
13
13
13代替
∞
∞
∞,并令
s
23
=
1
s_{23}=1
s23=1.
(2)
d
31
+
d
12
=
10
+
3
<
∞
d_{31}+d_{12}=10+3<∞
d31+d12=10+3<∞,则在
d
32
d_{32}
d32中用
13
13
13代替
∞
∞
∞,并令
s
32
=
1
s_{32}=1
s32=1.
此时得到 D 1 D_1 D1和 S 1 S_1 S1,得到下表
迭代2:令
k
=
2
k=2
k=2.
D
0
D_0
D0矩阵中的黄色阴影表示的第2行和第2列为枢轴行和枢轴列。根据三重操作发现可以改进的元素是
d
14
d_{14}
d14和
d
41
d_{41}
d41,即
(1)
d
21
+
d
42
=
3
+
5
=
8
<
∞
d_{21}+d_{42}=3+5=8<∞
d21+d42=3+5=8<∞,则在
d
41
d_{41}
d41中用
8
8
8代替
∞
∞
∞,并令
s
41
=
2
s_{41}=2
s41=2.
(2)
d
12
+
d
24
=
3
+
5
=
8
<
∞
d_{12}+d_{24}=3+5=8<∞
d12+d24=3+5=8<∞,则在
d
14
d_{14}
d14中用
8
8
8代替
∞
∞
∞,并令
s
14
=
2
s_{14}=2
s14=2.
此时得到
D
2
D_2
D2和
S
2
S_2
S2,得到下表
迭代3:令
k
=
3
k=3
k=3.
D
0
D_0
D0矩阵中的黄色阴影表示的第3行和第3列为枢轴行和枢轴列。根据三重操作发现可以改进的元素是
d
15
d_{15}
d15和
d
25
d_{25}
d25,即
(1)
d
13
+
d
35
=
10
+
15
=
25
<
∞
d_{13}+d_{35}=10+15=25<∞
d13+d35=10+15=25<∞,则在
d
15
d_{15}
d15中用
25
25
25代替
∞
∞
∞,并令
s
15
=
3
s_{15}=3
s15=3.
(2)
d
23
+
d
35
=
13
+
15
=
28
<
∞
d_{23}+d_{35}=13+15=28<∞
d23+d35=13+15=28<∞,则在
d
25
d_{25}
d25中用
28
28
28代替
∞
∞
∞,并令
s
25
=
3
s_{25}=3
s25=3.
此时得到
D
3
D_3
D3和
S
3
S_3
S3,得到下表
迭代4:令
k
=
4
k=4
k=4.
D
0
D_0
D0矩阵中的黄色阴影表示的第4行和第4列为枢轴行和枢轴列。根据三重操作发现可以改进的元素是
d
15
d_{15}
d15、
d
23
d_{23}
d23、
d
25
d_{25}
d25、
d
32
d_{32}
d32、
d
35
d_{35}
d35、
d
51
d_{51}
d51、
d
52
d_{52}
d52、
d
53
d_{53}
d53,即
(1)
d
14
+
d
45
=
8
+
4
=
12
<
25
d_{14}+d_{45}=8+4=12<25
d14+d45=8+4=12<25,则在
d
15
d_{15}
d15中用
12
12
12代替
25
25
25,并令
s
15
=
4
s_{15}=4
s15=4.
(2)
d
24
+
d
43
=
5
+
6
=
11
<
13
d_{24}+d_{43}=5+6=11<13
d24+d43=5+6=11<13,则在
d
23
d_{23}
d23中用
11
11
11代替
13
13
13,并令
s
23
=
4
s_{23}=4
s23=4.
(3)
d
24
+
d
45
=
5
+
4
=
9
<
28
d_{24}+d_{45}=5+4=9<28
d24+d45=5+4=9<28,则在
d
25
d_{25}
d25中用
9
9
9代替
28
28
28,并令
s
25
=
4
s_{25}=4
s25=4.
(4)
d
34
+
d
42
=
6
+
5
=
11
<
13
d_{34}+d_{42}=6+5=11<13
d34+d42=6+5=11<13,则在
d
25
d_{25}
d25中用
11
11
11代替
13
13
13,并令
s
32
=
4
s_{32}=4
s32=4.
(5)
d
34
+
d
45
=
6
+
4
=
10
<
15
d_{34}+d_{45}=6+4=10<15
d34+d45=6+4=10<15,则在
d
35
d_{35}
d35中用
10
10
10代替
15
15
15,并令
s
35
=
4
s_{35}=4
s35=4.
(6)
d
41
+
d
54
=
8
+
4
=
12
<
∞
d_{41}+d_{54}=8+4=12<∞
d41+d54=8+4=12<∞,则在
d
51
d_{51}
d51中用
12
12
12代替
∞
∞
∞,并令
s
51
=
4
s_{51}=4
s51=4.
(7)
d
42
+
d
54
=
5
+
4
=
9
<
∞
d_{42}+d_{54}=5+4=9<∞
d42+d54=5+4=9<∞,则在
d
52
d_{52}
d52中用
9
9
9代替
∞
∞
∞,并令
s
52
=
4
s_{52}=4
s52=4.
(8)
d
43
+
d
54
=
6
+
4
=
10
<
∞
d_{43}+d_{54}=6+4=10<∞
d43+d54=6+4=10<∞,则在
d
53
d_{53}
d53中用
10
10
10代替
∞
∞
∞,并令
s
53
=
4
s_{53}=4
s53=4.
此时得到 D 4 D_4 D4和 S 4 S_4 S4,得到下表
迭代5:令
k
=
5
k=5
k=5.
D
0
D_0
D0矩阵中的黄色阴影表示的第5行和第5列为枢轴行和枢轴列。根据三重操作发现没有可以改进的元素了。
因此,最后得到的矩阵为:
\qquad 这两个矩阵包含了网络中任意两个节点最短路径的所有信息。如从矩阵 D D D中可以看出节点1到节点5的最短路径长度为12.从矩阵 S S S中发现,节点1到节点5的中间节点是节点4,即节点1→节点4→节点5,再看节点1→节点4中间是节点2,即节点1需要通过节点2到达节点4,即节点1→节点2→节点4;而节点4可以直接到节点5,中间没有节点,因此可以得到节点1到节点5的最短路径是节点1→节点2→节点4→节点5.