📜  两个城市之间的单源最短路径(1)

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

两个城市之间的单源最短路径

在计算机科学中,单源最短路径是一种在给定的图形中查找从单个源节点到所有其他节点的最短路径的算法。在实际应用中,这种算法非常有用,例如在计算驾车路线、计算传输最短路径等方面。

实现算法

常用的单源最短路径算法是迪杰斯特拉和贝尔曼-福德算法。

迪杰斯特拉算法

迪杰斯特拉算法是一种广度优先搜索算法。它通过对图中所有节点进行遍历,逐步计算源节点到每个节点的最短距离。它的时间复杂度为 $O(|E|+|V|^2)$,其中 $|E|$ 为边数,$|V|$ 为节点数。

伪代码

  1. 初始将源点 s 的路径长度赋为 0,其余节点的路径长度赋为无穷大。
  2. 将所有节点加入集合 S,S 中的节点为已确定最短路径的节点。
  3. 对于每个 S 中的节点 v,遍历与其相邻的节点 u,计算源点 s 到节点 u 的距离,更新源点 s 到节点 u 的最短距离。
  4. 重复步骤 3,直到 S 中的节点包含所有节点。

代码示例

import heapq

def dijkstra(graph, start):
    distance = {node: float('inf') for node in graph}
    distance[start] = 0
    heap = [(0, start)]
    while heap:
        (dist, curr_node) = heapq.heappop(heap)
        if dist > distance[curr_node]:
            continue
        for neighbor, weight in graph[curr_node].items():
            new_dist = dist + weight
            if new_dist < distance[neighbor]:
                distance[neighbor] = new_dist
                heapq.heappush(heap, (new_dist, neighbor))
    return distance
贝尔曼-福德算法

贝尔曼-福德算法是一种动态规划算法。它通过对图中所有边进行遍历,重复计算节点到源节点的最短距离,直到无法更新距离。它的时间复杂度为 $O(|V||E|)$,其中 $|E|$ 为边数,$|V|$ 为节点数。

伪代码

  1. 初始将所有节点的路径长度赋为无穷大,源点 s 的路径长度赋为 0。
  2. 重复 $|V|-1$ 次以下操作:
    1. 对每条边 $(u, v)$ 进行松弛操作,如果源点 s 到节点 u 的路径长度加上边 $(u, v)$ 的权重小于源点 s 到节点 v 的路径长度,则更新源点 s 到节点 v 的路径长度。
  3. 检查每条边 $(u, v)$ 是否存在松弛操作,如果存在,则说明图中存在负权值回路。

代码示例

def bellman_ford(graph, start):
    distance = {node: float('inf') for node in graph}
    distance[start] = 0
    for i in range(len(graph) - 1):
        for u in graph:
            for v, weight in graph[u].items():
                if distance[u] + weight < distance[v]:
                    distance[v] = distance[u] + weight
    for u in graph:
        for v, weight in graph[u].items():
            if distance[u] + weight < distance[v]:
                print("Graph contains negative weight cycle")
                return {}
    return distance
使用示例

下面是一个简单的示例,展示如何使用迪杰斯特拉算法和贝尔曼-福德算法来计算两个城市之间的最短路径。

假设我们有以下无向有权图被表示为字典:

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 到节点 D 的最短路径。

迪杰斯特拉算法示例
dijkstra(graph, 'A')
# Output: {'A': 0, 'B': 1, 'C': 3, 'D': 4}

来源:Dijkstra and Bellman-Ford Algorithms for Single-Source Shortest Path