dijkstra算法

  Dijkstra算法是用于计算图中单源最短路径的经典算法,其核心思想是贪心算法,通过不断选择当前距离源点最近的节点,更新源点到其他节点的距离,直到所有节点都被访问过。

算法步骤

  • 初始化:
    • 设源点为 s,定义一个数组 dist[] 来存储从源点 s 到各个顶点的最短距离,初始时,源点 s 到自身的距离 dist[s] = 0,到其他顶点的距离设为无穷大(通常用一个很大的数表示)。
    • 定义一个集合 S 来存储已经找到最短路径的顶点,初始时 S 为空。
  • 迭代过程:
    • 从不在集合 S 中的顶点中,选择一个距离源点 s 最近的顶点 u,将其加入集合 S。
    • 对于顶点 u 的所有邻接顶点 v,更新 dist[v] 的值。如果通过顶点 u 到达顶点 v 的距离(即 dist[u] + 边(u, v)的权重)小于当前 dist[v] 的值,那么更新 dist[v] 为这个更小的值。

重复上述步骤,直到集合 S 包含了图中的所有顶点。

  首先我们看下面这个例子:求a点到其他点的最短距离

img

  1. 初始化:将源点a的距离设为0,其他点的距离设为无穷大,并将源点a加入集合S中: \(dist = \{a:0, b:\infty, c:\infty, d:\infty, e:\infty, f:\infty\}\)\(S = \{\}\)
  2. 迭代过程:
    • 选择距离源点 s 最近的顶点 a,将其加入集合 S, \(S = \{a\}\)。对于a的邻接点b, c,更新它们的距离:\(dist = \{a:0, b:2, c:5, d:\infty, e:\infty, f:\infty\}\)
    • 选择距离源点 s 最近的顶点 b,将其加入集合 S, \(S = \{a, b\}\)。对于b的邻接点c, d,更新它们的距离:\(dist = \{a:0, b:2, c:3, d:5, e:\infty, f:\infty\}\)
    • 选择距离源点 s 最近的顶点 c,将其加入集合 S, \(S = \{a, b, c\}\)。对于c的邻接点d, e, f,更新它们的距离:\(dist = \{a:0, b:2, c:3, d:5, e:7, f:4\}\)
    • 选择距离源点 s 最近的顶点 f,将其加入集合 S, \(S = \{a, b, c, f\}\)。对于d的邻接点e, f,更新它们的距离:\(dist = \{a:0, b:2, c:3, d:5, e:7, f:4\}\)
    • 选择距离源点 s 最近的顶点 d,将其加入集合 S, \(S = \{a, b, c, f, d\}\)。对于d的邻接点e, f,更新它们的距离:\(dist = \{a:0, b:2, c:3, d:5, e:6, f:4\}\)
    • 至此,所有顶点都已加入集合 S,算法结束。最终得到的 \(dist = \{a:0, b:2, c:3, d:5, e:6, f:4\}\) 即为从源点 a 到其他各点的最短距离。
def dijkstra(graph, start):
    # 初始化距离数组,将源点到自身的距离设为0,其他点设为无穷大
    dist = {vertex: float('inf') for vertex in graph}
    dist[start] = 0

    # 初始化已访问节点集合
    visited = set()

    while len(visited) < len(graph):
        # 选择当前距离源点最近的未访问节点
        current = min((d, v) for v, d in dist.items() if v not in visited)[1]
        visited.add(current)
        # 更新当前节点的邻接节点的距离
        for neighbor, weight in graph[current].items():
            if neighbor not in visited:
                new_dist = dist[current] + weight
                if new_dist < dist[neighbor]:
                    dist[neighbor] = new_dist

    return dist

时间复杂度

Dijkstra算法的时间复杂度取决于图的表示方式和算法的实现方式。在邻接矩阵表示下,Dijkstra算法的时间复杂度为 \(O(V^2)\),其中 V 是图中顶点的数量。在邻接表表示下,Dijkstra算法的时间复杂度为 \(O((V+E)logV)\),其中 E 是图中边的数量。

posted @ 2025-01-09 11:09  codersgl  阅读(116)  评论(0)    收藏  举报