Floyd算法用于求解最短路问题,求解各点之间的最短距离。
Folyd算法思想是每次更新距离矩阵和路由矩阵,产生递推矩阵序列 。更新的规则是每次以节点为中转节点,遍历其他节点经由节点去往其他节点是否会使得更小。
距离遍历公式为:
# 输入距离矩阵,-1表示初始化时两点不可达
matrix = [[0, 50, -1, 40, 25, 10],
[50, 0, 15, 20, -1, 25],
[-1, 15, 0, 10, 20, -1],
[40, 20, 10, 0, 10, 25],
[25, -1, 20, 10, 0, 55],
[10, 25, -1, 25, 55, 0]]
def floyd(W):
# 首先获取节点数
node_number = len(W)
# 初始化路由矩阵 n x n
R = [[0 for i in range(node_number)] for j in range(node_number)]
for i in range(node_number):
for j in range(node_number):
if W[i][j] > 0: # 如果 i+1 与 j+1 两点之间可达
R[i][j] = j+1 # 那么记录 i+1 --> j+1 路由的终点
else: # 如果 两点间不可达
R[i][j] = 0 # 则记录点为0
# 查看初始化的路由矩阵
for row in R:
print(row)
# 循环求W_n和R_n
for k in range(node_number): # 对每个点都作为中转节点更新距离和路由矩阵
for i in range(node_number): # 遍历每个点
for j in range(node_number):
if W[i][k] > 0 and W[k][j] > 0 and (W[i][k] + W[k][j] < W[i][j] or W[i][j] == -1):
W[i][j] = W[i][k] + W[k][j]
R[i][j] = k+1
print("第%d次循环:" % (k+1))
print("距离矩阵:")
for row in W:
print(row)
print("路由矩阵:")
for row in R:
print(row)
#打印路径
for i in range(node_number):
for j in range(node_number):
if R[i][j] != j+1 and R[i][j] != 0:
print(f'{i+1}--{R[i][j]}--{j+1}:{W[i][j]}')
elif R[i][j] == j+1:
print(f'{i+1}--{j+1}:{W[i][j]}')
floyd(matrix)
结果为:
[0, 2, 0, 4, 5, 6]
[1, 0, 3, 4, 0, 6]
[0, 2, 0, 4, 5, 0]
[1, 2, 3, 0, 5, 6]
[1, 0, 3, 4, 0, 6]
[1, 2, 0, 4, 5, 0]
第1次循环:
距离矩阵:
[0, 50, -1, 40, 25, 10]
[50, 0, 15, 20, 75, 25]
[-1, 15, 0, 10, 20, -1]
[40, 20, 10, 0, 10, 25]
[25, 75, 20, 10, 0, 35]
[10, 25, -1, 25, 35, 0]
路由矩阵:
[0, 2, 0, 4, 5, 6]
[1, 0, 3, 4, 1, 6]
[0, 2, 0, 4, 5, 0]
[1, 2, 3, 0, 5, 6]
[1, 1, 3, 4, 0, 1]
[1, 2, 0, 4, 1, 0]
第2次循环:
距离矩阵:
[0, 50, 65, 40, 25, 10]
[50, 0, 15, 20, 75, 25]
[65, 15, 0, 10, 20, 40]
[40, 20, 10, 0, 10, 25]
[25, 75, 20, 10, 0, 35]
[10, 25, 40, 25, 35, 0]
路由矩阵:
[0, 2, 2, 4, 5, 6]
[1, 0, 3, 4, 1, 6]
[2, 2, 0, 4, 5, 2]
[1, 2, 3, 0, 5, 6]
[1, 1, 3, 4, 0, 1]
[1, 2, 2, 4, 1, 0]
第3次循环:
距离矩阵:
[0, 50, 65, 40, 25, 10]
[50, 0, 15, 20, 35, 25]
[65, 15, 0, 10, 20, 40]
[40, 20, 10, 0, 10, 25]
[25, 35, 20, 10, 0, 35]
[10, 25, 40, 25, 35, 0]
路由矩阵:
[0, 2, 2, 4, 5, 6]
[1, 0, 3, 4, 3, 6]
[2, 2, 0, 4, 5, 2]
[1, 2, 3, 0, 5, 6]
[1, 3, 3, 4, 0, 1]
[1, 2, 2, 4, 1, 0]
第4次循环:
距离矩阵:
[0, 50, 50, 40, 25, 10]
[50, 0, 15, 20, 30, 25]
[50, 15, 0, 10, 20, 35]
[40, 20, 10, 0, 10, 25]
[25, 30, 20, 10, 0, 35]
[10, 25, 35, 25, 35, 0]
路由矩阵:
[0, 2, 4, 4, 5, 6]
[1, 0, 3, 4, 4, 6]
[4, 2, 0, 4, 5, 4]
[1, 2, 3, 0, 5, 6]
[1, 4, 3, 4, 0, 1]
[1, 2, 4, 4, 1, 0]
第5次循环:
距离矩阵:
[0, 50, 45, 35, 25, 10]
[50, 0, 15, 20, 30, 25]
[45, 15, 0, 10, 20, 35]
[35, 20, 10, 0, 10, 25]
[25, 30, 20, 10, 0, 35]
[10, 25, 35, 25, 35, 0]
路由矩阵:
[0, 2, 5, 5, 5, 6]
[1, 0, 3, 4, 4, 6]
[5, 2, 0, 4, 5, 4]
[5, 2, 3, 0, 5, 6]
[1, 4, 3, 4, 0, 1]
[1, 2, 4, 4, 1, 0]
第6次循环:
距离矩阵:
[0, 35, 45, 35, 25, 10]
[35, 0, 15, 20, 30, 25]
[45, 15, 0, 10, 20, 35]
[35, 20, 10, 0, 10, 25]
[25, 30, 20, 10, 0, 35]
[10, 25, 35, 25, 35, 0]
路由矩阵:
[0, 6, 5, 5, 5, 6]
[6, 0, 3, 4, 4, 6]
[5, 2, 0, 4, 5, 4]
[5, 2, 3, 0, 5, 6]
[1, 4, 3, 4, 0, 1]
[1, 2, 4, 4, 1, 0]
1--6--2:35
1--5--3:45
1--5--4:35
1--5:25
1--6:10
2--6--1:35
2--3:15
2--4:20
2--4--5:30
2--6:25
3--5--1:45
3--2:15
3--4:10
3--5:20
3--4--6:35
4--5--1:35
4--2:20
4--3:10
4--5:10
4--6:25
5--1:25
5--4--2:30
5--3:20
5--4:10
5--1--6:35
6--1:10
6--2:25
6--4--3:35
6--4:25
6--1--5:35