图论:最短路径——Floyd(弗洛伊德)算法

求任意两点间的最短路径

思路——动态规划

  1. 假设一个邻接矩阵 M,初始时刻,任意两个节点之间的距离就是邻接矩阵,因此将 dp 矩阵初始化为邻接矩阵,也就是边界条件。定义一个 path 矩阵记录任意两个节点之间的第一个中转节点,path 矩阵的初始值是终点节点自身。
  2. 然后每次选择一个节点加入路径作为中转节点,并更新 dp 矩阵,状态转移方程为:M[i][j] = min(M[i][j], M[i][k] + M[k][i])。将 dp 矩阵中路径值发生变化的两个节点的 path 更新为 : path[i][j] = path[i][k]。
  3. 直到最后选择完所有节点加入路径作为中转节点,最后的 dp 矩阵就是任意两点间的最短路径,path 矩阵就是任意两个节点之间的第一个中转节点。
  4. 想要知道两个节点 u 和 v 之间最短路径上的节点,可以通过 path 矩阵。
    4.1 首先查询 path 矩阵中,节点 u 和节点 v 之间的第一个中转节点 path[u][v] = k,加入栈。
    4.2 然后查询该中转节点 k 和节点 v 之间的中转节点 path[k][v],加入栈。
    4.3 重复查询中转节点,直到找到终点节点 j,加入栈。
    4.4 最后栈底到栈顶就是节点 u 到节点 v 的最短路径上的节点。

python代码

import copy
import math


def floyd(graph):
    node_num = len(graph)
    dist = copy.deepcopy(graph)
    path = [[i for i in range(node_num)] for _ in range(node_num)]
    for k in range(node_num):
        for i in range(node_num):
            for j in range(node_num):
                temp, dist[i][j] = dist[i][j], min(dist[i][j], dist[i][k] + dist[k][j])
                if dist[i][j] != temp:
                    path[i][j] = path[i][k]

    return dist, path


if __name__ == '__main__':
    graph = [[0, 3, 4],
             [3, 0, math.inf],
             [4, math.inf, 0]]
    dist, path = floyd(graph)
  • 7
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值