📜  算法|图最短路径|问题9(1)

📅  最后修改于: 2023-12-03 15:41:09.379000             🧑  作者: Mango

算法 | 图最短路径 | 问题9
问题描述

给定一个有向带权图和一个起点,找出起点到图中所有点的最短路径。如果存在负权边则无法使用Dijkstra算法,需要使用Bellman-Ford算法。

解决方案

Dijkstra算法

Dijkstra算法是基于贪心思想的单源最短路径算法,用于解决无负权边的问题,时间复杂度为O(nlogn)。该算法过程如下:

  1. 初始化起点的距离为0,其余点的距离为正无穷。
  2. 选出当前距离最小的点作为当前点,并标记为已访问。
  3. 遍历当前点的所有邻居,如果经过当前点到达该邻居的距离更短,则更新该邻居的距离。
  4. 重复步骤2和3,直到所有点都被访问。

Bellman-Ford算法

Bellman-Ford算法是基于动态规划的单源最短路径算法,可以解决带负权边的问题。该算法过程如下:

  1. 初始化起点到所有点的距离为正无穷。
  2. 初始化起点到自身的距离为0。
  3. 对图中的所有边进行n-1轮松弛操作,其中n为图中的点数。每轮松弛操作将通过当前点更新其邻居的距离。
  4. 检查是否存在负圈。如果存在负圈,则无法找到最短路径,否则可以得到起点到所有点的最短路径。
代码实现

Dijkstra算法

import heapq

def dijkstra(graph, start):
    distances = {node: float('inf') for node in graph}
    distances[start] = 0
    queue = [(0, start)]

    while queue:
        current_distance, current_node = heapq.heappop(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(queue, (distance, neighbor))

    return distances

Bellman-Ford算法

def bellman_ford(graph, start):
    distances = {node: float('inf') for node in graph}
    distances[start] = 0

    for i in range(len(graph) - 1):
        for u in graph:
            for v, weight in graph[u].items():
                if distances[u] + weight < distances[v]:
                    distances[v] = distances[u] + weight

    for u in graph:
        for v, weight in graph[u].items():
            if distances[u] + weight < distances[v]:
                return None

    return distances
总结

Dijkstra算法适用于无负权边的情况,而Bellman-Ford算法可以处理带负权边的情况。在实际应用中,需要根据具体问题来选择合适的算法。