弗洛伊德(Floyd)算法python实现

弗洛伊德(Floyd)算法

1.算法原理

算法使用距离矩阵和路由矩阵。

距离矩阵是一个n×n矩阵,以图Gn个节点为行和列。记为W=[wij]n×nwij表示图Gvivj两点之间的路径长度。接点则记录最后一个)。

路由矩阵是一个n×n矩阵,以图Gn个节点为行和列。记为R=[rij]n×n ,其中rij表示vivj经过的转接点(中间节点)。

算法的思路是首先写出初始的W阵和R阵,接着按顺序依次将节点集中的各个节点作为中间节点,计算此点距其他各点的径长,每次计算后都以求得的与上次相比较小的径长去更新前一次较大径长,若后求得的径长比前次径长大或相等则不变。以此不断更新和,直至W中的数值收敛。

2.实现流程

  1. 写出图G初始距离矩阵W0=[wij0]n×n,其中

wij0={dijvivj,dij(i,j)vivj0i=j

  1. 写出图G初始路由矩阵R0=[rij0]n×n,其中

rij0={jwij0<0wij0=i=j

  1. 循环变量k初始值为1
  2. k为中间节点时,求第k次修改距离矩阵Wk=[wijk]n×n,其中

wijk=min{wijk1,wikk1+wkjk1}

  1. k为中间节点时,求第k次修改路由矩阵Rk=[rijk]n×n,其中

rijk={kwijk1>wikk1+wkjk1,wijrijk1wijk1<wikk1+wkjk1,wij

  1. 循环直至k=n结束

3.举个例子

如图:

  1. 首先根据图得出初始化距离矩阵:

W0=(01.29.20.5053.12041.51.2506.79.26.7015.63.1415.600.521.50)

并由此得出初始路由矩阵:

R0=(0004507000406700000671200500100406002305001230000)

路由矩阵表示,初始时,v1可以直接到达v4v5v7v2可以直接到达v4v6v7v3可以直接到达v6v7;…………

  1. 然后,把v1作为转节点,因为v1能到达v4v5v7,那么v2v7的这6个点中,能够到达v1的点就能够通过v1再到达v4v5v7,由此我们可以对距离矩阵W0进行更新:
    • v4v1的距离是1.2,v1再到v5的距离是9.2,所以v4经过v1再到v5的距离是10.4,但v4直接到v5的距离是6.7,比10.4小,所以不用改;而v4经过v1再到v7的距离是1.2+0.5=1.7,比小,需要进行修改w471=1.7
    • v5v1的距离是9.2,v5经过v1再到v7的距离是9.2+0.5=9.7,比小,需要进行修改w571=9.7
    • 同理w741=1.7w751=9.7

于是得到:

W1=(01.29.20.5053.12041.51.2506.71.79.26.7015.69.73.1415.600.521.51.79.70)()

对于路由矩阵,v4v7经过了转节点v1,故r471=1v5v7经过了转节点v1,故r571=1;同理r741=1r751=1

R1=(0004507000406700000671200501100406102305001231100)()

  1. v2作为转节点,重复上面的步骤,可以得到

距离矩阵:

W2=(01.29.20.5053.12041.51.2506.78.11.79.26.7015.69.73.148.115.605.10.521.51.79.75.10)()

路由矩阵:

R2=(0004507000406700000671200521100406102325021231120)()

  1. v3作为转节点,发现并没有要修改的值

距离矩阵:

W3=(01.29.20.5053.12041.51.2506.78.11.79.26.7015.69.73.148.115.605.10.521.51.79.75.10)

路由矩阵:

R3=(0004507000406700000671200521100406102325021231120)

  1. v4作为转接点

距离矩阵:

W4=(06.21.27.99.30.56.20511.73.12041.51.2506.78.11.77.911.76.7014.88.49.33.148.114.805.10.521.51.78.45.10)()

路由矩阵:

R4=(0404447400446700000671200521440404442324021231420)

  1. v5作为转接点,无需修改

距离矩阵:

W5=(06.21.27.99.30.56.20511.73.12041.51.2506.78.11.77.911.76.7014.88.49.33.148.114.805.10.521.51.78.45.10)

路由矩阵:

R5=(0404447400446700000671200521440404442324021231420)

  1. v6作为转接点

距离矩阵:

W6=(06.213.31.27.99.30.56.207.1511.73.1213.37.1012.118.841.51.2512.106.78.11.77.911.718.86.7014.88.49.33.148.114.805.10.521.51.78.45.10)

路由矩阵:

R6=(0464447406446766066671260521446404442324021231420)

  1. v7作为转接点

距离矩阵:

W7=(02.521.27.95.60.52.503.53.710.43.1223.503.29.941.51.23.73.206.76.81.77.910.49.96.7013.58.45.63.146.813.505.10.521.51.78.45.10)

路由矩阵:

R7=(0774477707776777077671770577477407472377021231420)

W7R7可以找到任何节点间最短径的径长和路由。

4.实现代码

matrix = [[0, -1, -1, 1.2, 9.1, -1, 0.5],
          [-1, 0, -1, 5, -1, 3.1, 2],
          [-1, -1, 0, -1, -1, 4, 1.5],
          [1.2, 5, -1, 0, 6.7, -1, -1],
          [9.2, -1, -1, 6.7, 0, 15.6, -1],
          [-1, 3.1, 4, -1, 15.6, 0, -1],
          [0.5, 2, 1.5, -1, -1, -1, 0]]


def floyd(W):
    # 首先获取节点数
    node_number = len(W)

    # 初始化路由矩阵
    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:
                R[i][j] = j+1
            else:
                R[i][j] = 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)


floyd(matrix)

5.输出结果

"""
[0, 0, 0, 4, 5, 0, 7]
[0, 0, 0, 4, 0, 6, 7]
[0, 0, 0, 0, 0, 6, 7]
[1, 2, 0, 0, 5, 0, 0]
[1, 0, 0, 4, 0, 6, 0]
[0, 2, 3, 0, 5, 0, 0]
[1, 2, 3, 0, 0, 0, 0]
第1次循环:
距离矩阵:
[0, -1, -1, 1.2, 9.1, -1, 0.5]
[-1, 0, -1, 5, -1, 3.1, 2]
[-1, -1, 0, -1, -1, 4, 1.5]
[1.2, 5, -1, 0, 6.7, -1, 1.7]
[9.2, -1, -1, 6.7, 0, 15.6, 9.7]
[-1, 3.1, 4, -1, 15.6, 0, -1]
[0.5, 2, 1.5, 1.7, 9.6, -1, 0]
路由矩阵:
[0, 0, 0, 4, 5, 0, 7]
[0, 0, 0, 4, 0, 6, 7]
[0, 0, 0, 0, 0, 6, 7]
[1, 2, 0, 0, 5, 0, 1]
[1, 0, 0, 4, 0, 6, 1]
[0, 2, 3, 0, 5, 0, 0]
[1, 2, 3, 1, 1, 0, 0]
第2次循环:
距离矩阵:
[0, -1, -1, 1.2, 9.1, -1, 0.5]
[-1, 0, -1, 5, -1, 3.1, 2]
[-1, -1, 0, -1, -1, 4, 1.5]
[1.2, 5, -1, 0, 6.7, 8.1, 1.7]
[9.2, -1, -1, 6.7, 0, 15.6, 9.7]
[-1, 3.1, 4, 8.1, 15.6, 0, 5.1]
[0.5, 2, 1.5, 1.7, 9.6, 5.1, 0]
路由矩阵:
[0, 0, 0, 4, 5, 0, 7]
[0, 0, 0, 4, 0, 6, 7]
[0, 0, 0, 0, 0, 6, 7]
[1, 2, 0, 0, 5, 2, 1]
[1, 0, 0, 4, 0, 6, 1]
[0, 2, 3, 2, 5, 0, 2]
[1, 2, 3, 1, 1, 2, 0]
第3次循环:
距离矩阵:
[0, -1, -1, 1.2, 9.1, -1, 0.5]
[-1, 0, -1, 5, -1, 3.1, 2]
[-1, -1, 0, -1, -1, 4, 1.5]
[1.2, 5, -1, 0, 6.7, 8.1, 1.7]
[9.2, -1, -1, 6.7, 0, 15.6, 9.7]
[-1, 3.1, 4, 8.1, 15.6, 0, 5.1]
[0.5, 2, 1.5, 1.7, 9.6, 5.1, 0]
路由矩阵:
[0, 0, 0, 4, 5, 0, 7]
[0, 0, 0, 4, 0, 6, 7]
[0, 0, 0, 0, 0, 6, 7]
[1, 2, 0, 0, 5, 2, 1]
[1, 0, 0, 4, 0, 6, 1]
[0, 2, 3, 2, 5, 0, 2]
[1, 2, 3, 1, 1, 2, 0]
第4次循环:
距离矩阵:
[0, 6.2, -1, 1.2, 7.9, 9.299999999999999, 0.5]
[6.2, 0, -1, 5, 11.7, 3.1, 2]
[-1, -1, 0, -1, -1, 4, 1.5]
[1.2, 5, -1, 0, 6.7, 8.1, 1.7]
[7.9, 11.7, -1, 6.7, 0, 14.8, 8.4]
[9.299999999999999, 3.1, 4, 8.1, 14.8, 0, 5.1]
[0.5, 2, 1.5, 1.7, 8.4, 5.1, 0]
路由矩阵:
[0, 4, 0, 4, 4, 4, 7]
[4, 0, 0, 4, 4, 6, 7]
[0, 0, 0, 0, 0, 6, 7]
[1, 2, 0, 0, 5, 2, 1]
[4, 4, 0, 4, 0, 4, 4]
[4, 2, 3, 2, 4, 0, 2]
[1, 2, 3, 1, 4, 2, 0]
第5次循环:
距离矩阵:
[0, 6.2, -1, 1.2, 7.9, 9.299999999999999, 0.5]
[6.2, 0, -1, 5, 11.7, 3.1, 2]
[-1, -1, 0, -1, -1, 4, 1.5]
[1.2, 5, -1, 0, 6.7, 8.1, 1.7]
[7.9, 11.7, -1, 6.7, 0, 14.8, 8.4]
[9.299999999999999, 3.1, 4, 8.1, 14.8, 0, 5.1]
[0.5, 2, 1.5, 1.7, 8.4, 5.1, 0]
路由矩阵:
[0, 4, 0, 4, 4, 4, 7]
[4, 0, 0, 4, 4, 6, 7]
[0, 0, 0, 0, 0, 6, 7]
[1, 2, 0, 0, 5, 2, 1]
[4, 4, 0, 4, 0, 4, 4]
[4, 2, 3, 2, 4, 0, 2]
[1, 2, 3, 1, 4, 2, 0]
第6次循环:
距离矩阵:
[0, 6.2, 13.299999999999999, 1.2, 7.9, 9.299999999999999, 0.5]
[6.2, 0, 7.1, 5, 11.7, 3.1, 2]
[13.299999999999999, 7.1, 0, 12.1, 18.8, 4, 1.5]
[1.2, 5, 12.1, 0, 6.7, 8.1, 1.7]
[7.9, 11.7, 18.8, 6.7, 0, 14.8, 8.4]
[9.299999999999999, 3.1, 4, 8.1, 14.8, 0, 5.1]
[0.5, 2, 1.5, 1.7, 8.4, 5.1, 0]
路由矩阵:
[0, 4, 6, 4, 4, 4, 7]
[4, 0, 6, 4, 4, 6, 7]
[6, 6, 0, 6, 6, 6, 7]
[1, 2, 6, 0, 5, 2, 1]
[4, 4, 6, 4, 0, 4, 4]
[4, 2, 3, 2, 4, 0, 2]
[1, 2, 3, 1, 4, 2, 0]
第7次循环:
距离矩阵:
[0, 2.5, 2.0, 1.2, 7.9, 5.6, 0.5]
[2.5, 0, 3.5, 3.7, 10.4, 3.1, 2]
[2.0, 3.5, 0, 3.2, 9.9, 4, 1.5]
[1.2, 3.7, 3.2, 0, 6.7, 6.8, 1.7]
[7.9, 10.4, 9.9, 6.7, 0, 13.5, 8.4]
[5.6, 3.1, 4, 6.8, 13.5, 0, 5.1]
[0.5, 2, 1.5, 1.7, 8.4, 5.1, 0]
路由矩阵:
[0, 7, 7, 4, 4, 7, 7]
[7, 0, 7, 7, 7, 6, 7]
[7, 7, 0, 7, 7, 6, 7]
[1, 7, 7, 0, 5, 7, 1]
[4, 7, 7, 4, 0, 7, 4]
[7, 2, 3, 7, 7, 0, 2]
[1, 2, 3, 1, 4, 2, 0]
"""

本文作者:听风者628

本文链接:https://www.cnblogs.com/shuang-fan/p/16294228.html

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   听风者628  阅读(938)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
💬
评论
📌
收藏
💗
关注
👍
推荐
🚀
回顶
收起
  1. 1 404 not found REOL
404 not found - REOL
00:00 / 00:00
An audio error has occurred.