python 之弗洛伊德算法

本文介绍了弗洛伊德算法,一种用于计算加权图中所有节点对之间最短路径的动态规划方法。文章详细阐述了算法步骤、时间复杂度,并提供了Python代码示例。与Dijkstra和Bellman-Ford算法相比,弗洛伊德算法适合小规模和密集图。
摘要由CSDN通过智能技术生成

介绍

弗洛伊德算法,也称为Floyd-Warshall算法,是一种用于解决图中所有节点对之间的最短路径问题的动态规划算法。它可以处理带有负权边但不含负权环的加权有向图或无向图。该算法以Robert Floyd和Stephen Warshall的名字命名,于1962年分别由他们独立提出。

以下是弗洛伊德算法的详细步骤:

  1. 初始化距离矩阵:创建一个二维数组dist[][],其中dist[i][j]表示节点i到节点j的最短路径长度。如果节点i到节点j有直接连接的边,则dist[i][j]的值为这条边的权重;否则,dist[i][j]的值设为无穷大,表示不可达。

  2. 初始化对角线:将对角线上的元素dist[i][i]设为0,表示每个节点到自身的距离为0。

  3. 动态规划更新:对于每一对节点(i, j),以每个节点k作为中间节点,检查是否存在一条从节点i到节点j的路径,经过节点k可以使得路径长度更短。如果存在这样的路径,则更新dist[i][j]dist[i][k] + dist[k][j],即通过中间节点k的路径长度。如果dist[i][k] + dist[k][j]比当前已知的dist[i][j]更小,则更新dist[i][j]

  4. 重复更新:重复以上步骤,直到所有节点对之间的最短路径都被找到,并且没有更改发生。最终,dist[][]矩阵中的值就是每对节点之间的最短路径长度。

弗洛伊德算法的时间复杂度为O(n^3),其中n是图中的节点数。由于它使用了动态规划的思想,因此适用于解决小规模的图以及密集图。然而,对于大型稀疏图,可能会有更高效的算法,比如Dijkstra算法和Bellman-Ford算法,它们针对单源最短路径问题的性能更好。

代码

以下是使用Python实现弗洛伊德算法的代码示例:

INF = float('inf')

def floyd_warshall(graph):
    # 初始化距离矩阵
    dist = [[INF if i != j else 0 for j in range(len(graph))] for i in range(len(graph))]
    
    # 更新距离矩阵
    for i in range(len(graph)):
        for j in range(len(graph)):
            if graph[i][j] != 0:  # 如果节点i和节点j之间有直接连接的边
                dist[i][j] = graph[i][j]
    
    # 动态规划更新距离矩阵
    for k in range(len(graph)):
        for i in range(len(graph)):
            for j in range(len(graph)):
                if dist[i][k] != INF and dist[k][j] != INF:  # 如果节点i到k和k到节点j之间有路径
                    dist[i][j] = min(dist[i][j], dist[i][k] + dist[k][j])
    
    return dist

# 示例图的邻接矩阵表示
graph = [
    [0, 5, INF, 10],
    [INF, 0, 3, INF],
    [INF, INF, 0, 1],
    [INF, INF, INF, 0]
]

# 打印最短路径距离矩阵
result = floyd_warshall(graph)
for row in result:
    print(row)

这段代码首先定义了一个INF常量,用于表示无穷大。然后实现了floyd_warshall函数,该函数接受一个邻接矩阵表示的图作为输入,并返回所有节点对之间的最短路径距离矩阵。在函数中,首先初始化距离矩阵,然后根据图的邻接矩阵更新直接连接的边的距离,接着使用动态规划的思想逐步更新距离矩阵,直到得到所有节点对之间的最短路径距离矩阵。

蓝桥公园

在这里插入图片描述
在这里插入图片描述

import os
import sys

# 请在此输入您的代码
N, M, Q = map(int, input().split())
weight = [[0 if i == j else sys.maxsize for i in range(N + 1) ] for j in range(N + 1)]  # 领接矩阵
for i in range(M):
    u, v, w = map(int, input().split())
    weight[u][v] = min(weight[u][v], w)
    weight[v][u] = weight[u][v]
for k in range(1, N + 1):  # N次递推
    for i in range(1, N + 1):
        for j in range(i + 1, N + 1):  # 更新最小值
                weight[i][j] = min(weight[i][j], weight[i][k] + weight[k][j])
                weight[j][i] = weight[i][j]

for i in range(Q):
    st, ed = map(int, input().split())
    t = weight[st][ed]
    if t == sys.maxsize:
        print(-1)
    else:
        print(t)


弗洛伊德算法Floyd-Warshall algorithm)是一种用于求解所有点对最短路径的动态规划算法。它可以在有向图或无向图中找出任意两个顶点之间的最短路径。 算法的基本思想是,通过不断更新每对顶点之间的最短路径,从而逐步得到全局最短路径。具体步骤如下: 1. 初始化一个二维数组dist,dist[i][j]表示顶点i到顶点j的最短路径长度。 2. 将dist数组初始化为图中两个顶点之间的直接距离,如果两个顶点之间没有直接边,则距离设置为无穷大。 3. 对于每一对顶点i和j,遍历所有顶点k,如果通过顶点k可以使得路径更短,那么更新dist[i][j]的值为dist[i][k] + dist[k][j]。 4. 重复步骤3直到所有顶点对之间的最短路径长度都更新完毕。 通过这个算法,可以得到任意两个顶点之间的最短路径长度。需要注意的是,如果图中存在负权边或负权环,该算法可能无法正确计算出最短路径。 在Python中,可以使用二维列表来表示dist数组,并使用嵌套的循环来实现算法的步骤。以下是一个简单的Python实现示例: ```python def floyd_warshall(graph): n = len(graph) dist = [[float('inf')] * n for _ in range(n)] for i in range(n): for j in range(n): if i == j: dist[i][j] = 0 elif graph[i][j] != 0: dist[i][j] = graph[i][j] for k in range(n): for i in range(n): for j in range(n): dist[i][j] = min(dist[i][j], dist[i][k] + dist[k][j]) return dist ``` 其中,graph为输入的图,使用邻接矩阵来表示。dist为最终得到的每对顶点之间的最短路径长度。 希望以上信息对你有所帮助!如有任何疑问,请继续提问。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值