狄克斯特拉算法
是由荷兰计算机科学家狄克斯特拉于1959 年提出的。是从一个顶点到其余各顶点的最短路径算法,解决的是有向无环图中最短路径问题,且不能有负权边。
狄克斯特拉算法主要特点是以起始点为中心向外层层扩展,直到扩展到终点为止。
示例:
找出从起点到终点的最短路径
当前起点到各点的花费,选择最小且没有被检查的点
起点至 | 当前花费 | 父节点 |
---|---|---|
B | 5 | start |
C | 1 | start |
D | ? | ? |
E | ? | ? |
fin | ? | ? |
第一步,选择C扩展,更新花费,父节点
起点至 | 当前花费 | 父节点 |
---|---|---|
B | 5 | start |
C | 1 | start |
D | 31 | C |
E | 36 | C |
fin | ? | ? |
第二步,选择B扩展,更新花费,父节点
起点至 | 当前花费 | 父节点 |
---|---|---|
B | 5 | start |
C(已检查) | 1 | start |
D | 20 | B |
E | 25 | B |
fin | ? | ? |
第三步,选择D扩展,更新花费,父节点
起点至 | 当前花费 | 父节点 |
---|---|---|
B(已检查) | 5 | start |
C(已检查) | 1 | start |
D | 20 | B |
E | 25 | B |
fin | 40 | D |
第四步,选择E扩展,更新花费,父节点
起点至 | 当前花费 | 父节点 |
---|---|---|
B(已检查) | 5 | start |
C(已检查) | 1 | start |
D(已检查) | 20 | B |
E | 25 | B |
fin | 35 | E |
第五步,选择fin扩展,更新花费,父节点
起点至 | 当前花费 | 父节点 |
---|---|---|
B(已检查) | 5 | start |
C(已检查) | 1 | start |
D(已检查) | 20 | B |
E(已检查) | 25 | B |
fin | 35 | E |
代码实现:
#无穷大
infinity = float('inf')
#结点图
graph = {}
graph['start'] = {}
graph['start']['B'] = 5
graph['start']['C'] = 1
graph['B'] = {}
graph['B']['D'] = 15
graph['B']['E'] = 20
graph['C'] = {}
graph['C']['D'] = 30
graph['C']['E'] = 35
graph['D'] = {}
graph['D']['fin'] = 20
graph['E'] = {}
graph['E']['fin'] = 10
graph['fin'] = {}
costs = {}
costs['B'] = 5
costs['C'] = 1
costs['D'] = infinity
costs['E'] = infinity
costs['fin'] = infinity
parents = {}
parents['B'] = 'start'
parents['C'] = 'start'
parents['D'] = None
parents['E'] = None
parents['fin'] = None
proessed = []
#找出最小花费结点
def find_lowest_cost_node(costs):
#最小花费初始值为无穷大
lowest_cost = float('inf')
lowest_cost_node = None
#遍历costs,找出最小花费结点
for node in costs:
cost = costs[node]
if cost<lowest_cost and node not in proessed:
lowest_cost = cost
lowest_cost_node = node
return lowest_cost_node
def Dijkstra(costs,graph,parents):
#获得最小花费结点
node = find_lowest_cost_node(costs)
#
while node is not None:
cost = costs[node]
next = graph[node]
for i in next.keys():
new_cost = cost + graph[node][i]
#更新costs 和 parents
if new_cost < costs[i]:
costs[i] = new_cost
parents[i] = node
proessed.append(node)
node = find_lowest_cost_node(costs)
def result(costs,parents):
print("花费:",costs['fin'])
a = 'fin'
res = []
res.append(a)
while True:
a = parents[a]
res.append(a)
if a == 'start':
break
print("路径:",end=' ')
res.reverse()
#print(res)
for i in res:
if i =='fin':
print(i)
else:
print(i,end='->')
if __name__ == '__main__':
Dijkstra(costs, graph, parents)
result(costs,parents)
结果: