Floyd 算法 Python实现

 Floyd算法用于求解最短路问题,求解各点之间的最短距离。

Folyd算法思想是每次更新距离矩阵和路由矩阵,产生递推矩阵序列 W_0,W_1,...,W_n。更新的规则是每次以节点k为中转节点,遍历其他节点i经由节点k去往其他节点j是否会使得W_k(i,j)更小。

距离遍历公式为:W_k(i,j) = \min\{W_{k-1}(i,j),W_{k-1}(i,k)+W_{k-1}(k,j)\}

# 输入距离矩阵,-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

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值