数据结构和算法-最短路径

Dijkstra(迪杰斯特拉算法): 在`有向加权图`中查找最短路径

1. 找出距离起点最近的节点
2. 对于该节点邻居, 检查是否有前往他们的更短路径, 如果有就更新开销
3. 重复以上两步, 直到所有节点运行过
4. 找出最短路径

start A 6
start B 2
B A 5
B end 7
A end 6

1. 找出`start`的邻居节点`A``B`, 其中`B`的花费最少
2. 找出`B`节点的邻居节点`A``end`, 更新到`A节点`的开销
3. 继续对`A节点`进行, 从`A``end`花费最小, 更新`B``end`的开销

实现

``````# -*- coding:utf-8 -*-

'''
Dijkstra算法(最短路径算法)

- 适用于有向有权无环图
- 不适用于负权边的情况
'''

import heapq

class Graph(object):
def __init__(self):
self.graph = {}

def add_edge(self, start: str, end: str, distance: float):
self.graph.setdefault(start, {})
self.graph[start][end] = distance

def dijkstra(start: str, end: str, graph: dict) -> list:
visited = set()  # 存储已经处理过的节点
costs = {start: 0}

queue = [(0, start)]
path = {}  # 用于复原路径

while queue:
dis, min_node = heapq.heappop(queue)
if min_node == end:
break

if min_node not in visited:

neighbors = graph[min_node]
for i, j in neighbors.items():
new_dis = dis + j
if (i not in costs) or (new_dis < costs[i]):
costs[i] = new_dis
heapq.heappush(queue, (new_dis, i))
path[i] = min_node

res = []
key = end
while key != start:
res.append(key)
key = path[key]
res.append(start)
res.reverse()

return res

if __name__ == '__main__':
g1 = Graph()
assert dijkstra('start', 'end', g1.graph) == ['start', 'a', 'end']

g2 = Graph()
assert dijkstra('start', 'end', g2.graph) == ['start', 'b', 'a', 'end']
``````
• 利用最小堆不断找出开销最小的节点
• 当发现有到达某个节点的更短距离是更新该节点的距离

• <<漫画算法>>
• <<数据结构和算法>>

(0)
(0)