Python实现Dijkstra和Floyd算法

1. Dijkstra算法

Dijkstra算法用于寻找单源最短路径,即从一个节点到所有其他节点的最短路径。它的基本思想是每次选择未处理节点中距离起点最近的节点,并更新其邻居的最短路径。

1.1. 算法步骤:
  1. 初始化:设定起点到起点的距离为0,其他节点到起点的距离为无穷大。将所有节点标记为未处理。
  2. 选择未处理节点中距离起点最近的节点,记为当前节点。
  3. 更新当前节点的邻居节点的最短路径。
  4. 将当前节点标记为已处理。
  5. 重复步骤2-4,直到所有节点都被处理。
1.2. Python实现Dijkstra算法
import heapq

def dijkstra(graph, start):
    # 创建一个字典来存储从起点到每个节点的最短路径距离
    distances = {node: float('infinity') for node in graph}
    # 起点到起点的距离为0
    distances[start] = 0
    # 创建一个优先队列来处理节点
    priority_queue = [(0, start)]
    
    while priority_queue:
        current_distance, current_node = heapq.heappop(priority_queue)
        
        if current_distance > distances[current_node]:
            continue
        
        for neighbor, weight in graph[current_node].items():
            distance = current_distance + weight
            
            if distance < distances[neighbor]:
                distances[neighbor] = distance
                heapq.heappush(priority_queue, (distance, neighbor))
    
    return distances

# 示例图表示为邻接表
graph = {
    'A': {'B': 1, 'C': 4},
    'B': {'A': 1, 'C': 2, 'D': 5},
    'C': {'A': 4, 'B': 2, 'D': 1},
    'D': {'B': 5, 'C': 1}
}

# 从节点 'A' 出发
print(dijkstra(graph, 'A'))

2. Floyd算法

Floyd算法,又称Floyd-Warshall算法,用于寻找任意两点之间的最短路径。它的基本思想是通过不断更新节点之间的最短路径,最终得到任意两点之间的最短路径。

2.1. 算法步骤:
  1. 初始化:创建一个矩阵,记录图中所有节点间的距离,初始值为节点间的边的权重,如果两节点间没有直接边则设为无穷大。
  2. 对于每一对节点 (i, j),检查通过每个可能的中间节点 k 是否能找到更短的路径。如果能,更新路径距离。
  3. 重复上述过程,直到所有节点对的最短路径被找到。
2.2. Python实现Floyd算法
def floyd_warshall(graph):
    # 初始化距离矩阵
    distance = [[float('infinity')] * len(graph) for _ in range(len(graph))]
    
    # 自己到自己的距离为0
    for i in range(len(graph)):
        distance[i][i] = 0
    
    # 设置直接边的距离
    for i in range(len(graph)):
        for j in range(len(graph)):
            if graph[i][j] != 0:
                distance[i][j] = graph[i][j]
    
    # 逐个检查每个可能的中间节点 k
    for k in range(len(graph)):
        for i in range(len(graph)):
            for j in range(len(graph)):
                if distance[i][j] > distance[i][k] + distance[k][j]:
                    distance[i][j] = distance[i][k] + distance[k][j]
    
    return distance

# 示例图表示为邻接矩阵
graph = [
    [0, 3, float('infinity'), 5],
    [2, 0, float('infinity'), 4],
    [float('infinity'), 1, 0, float('infinity')],
    [float('infinity'), float('infinity'), 2, 0]
]

print(floyd_warshall(graph))

这两个算法分别解决了单源最短路径和任意两点之间的最短路径问题。Dijkstra算法适用于边权重非负的情况,而Floyd算法则可以处理有向图和负权重的边,但不能处理负权重环。

  • 6
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
Dijkstra算法Floyd算法都是图论中的经典算法,用于解决最短路径问题。下面分别介绍它们的算法模拟过程和算法实现。 1. Dijkstra算法 Dijkstra算法是一种贪心算法,用于求有向图的单源最短路径。算法流程如下: (1)初始化:将起点s到各个顶点的距离dist[i]初始化为无穷大,将起点s到自身的距离dist[s]初始化为0; (2)遍历所有顶点:从未确定最短路径的顶点集合S中选取距离起点s最近的顶点u,确定它的最短路径,并将其加入已确定最短路径的顶点集合T中; (3)更新距离:以u为中间点,更新起点s到未确定最短路径的顶点v的距离dist[v]。如果新的路径比原路径短,则更新dist[v],否则不变; (4)重复步骤(2)和(3),直到所有顶点都已加入已确定最短路径的顶点集合T。 算法实现: 以下是Dijkstra算法Python实现,其中graph表示有向图的邻接矩阵,start表示起点: ```python def dijkstra(graph, start): n = len(graph) dist = [float('inf')] * n # 初始化距离 dist[start] = 0 visited = set() # 已确定最短路径的顶点集合 while len(visited) < n: u = min((v for v in range(n) if v not in visited), key=lambda x: dist[x]) visited.add(u) for v in range(n): if graph[u][v] > 0 and v not in visited: new_dist = dist[u] + graph[u][v] if new_dist < dist[v]: dist[v] = new_dist return dist ``` 2. Floyd算法 Floyd算法是一种动态规划算法,用于求有向图的多源最短路径。算法流程如下: (1)初始化:将任意两个顶点之间的距离dist[i][j]初始化为它们之间的边的权值,如果不存在边,则初始化为无穷大; (2)遍历所有顶点:对于每个顶点k,遍历所有顶点i和j,如果从i到j的路径经过顶点k比不经过顶点k的路径更短,则更新dist[i][j]; (3)重复步骤(2),直到所有顶点都已经遍历过。 算法实现: 以下是Floyd算法Python实现,其中graph表示有向图的邻接矩阵: ```python def floyd(graph): n = len(graph) dist = [[graph[i][j] for j in range(n)] for i in range(n)] for k in range(n): for i in range(n): for j in range(n): if dist[i][k] != float('inf') and dist[k][j] != float('inf') and dist[i][k] + dist[k][j] < dist[i][j]: dist[i][j] = dist[i][k] + dist[k][j] return dist ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

闲人编程

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值