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点到其他点的最短距离

- 初始化:将源点a的距离设为0,其他点的距离设为无穷大,并将源点a加入集合S中: \(dist = \{a:0, b:\infty, c:\infty, d:\infty, e:\infty, f:\infty\}\), \(S = \{\}\)。
- 迭代过程:
- 选择距离源点 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 是图中边的数量。

浙公网安备 33010602011771号