加权图与狄克斯特拉算法的python实现
1. 加权图
加权图通过python可以用字典很简单实现, 还是拿这张图举例子(改为了有向图)
每一个点对应着他的邻居们,而他的邻居们也用字典对应所在边的长度
graph = {'s': {'a': 1, 'd': 2},
'a': {'b': 1, 'c': 2},
'b': {'t': 10},
'c': {'t': 1},
'd': {'c': 10},
't': {}}
这样, 一条边的长度表示也可以很清晰的表示graph['s']['a'] == 1
,同时想得到全部邻居可以list(graph['s'].keys())
或者直接 for i in graph['s']
2. 狄克斯特拉算法
狄克斯特拉算法是专门用于有向,无环,无负数值边的加权图的算法, 可以求出某两点之间的最短距离。
算法的思想是: 在当前已知的距离中,如果某距离不是最短距离,那这个距离只能由已知的更短的距离经过几个新邻居得到
现在,我们用这个算法求出s到t的最短距离
代码实现
#首先我们需要三个字典来储存数据
graph = {'s': {'a': 1, 'd': 2}, #储存加权图,<注意终点也要一个空字典>
'a': {'b': 1, 'c': 2},
'b': {'t': 10},
'c': {'t': 1},
'd': {'c': 10},
't': {}}
costs = {'a':999,'b':999,'c':999,'d':999,'s':999,'t':999,} #储存起点到某个点的最短距离, <注意每条边都要赋初值>
for i in graph['s']:
costs[i] = graph['s'][i]
parents[i] = 's'
parents = {}#记录每个点走最短路径时的父节点, 再求最短路径的时候有用
def lowest (costs):#得到除了已经处理过的点以外的离起点最近的点
Min = 999
name = None
for i in costs:
if Min > costs[i] and i not in processed:
Min = costs[i]
name = i
if name:
processed[name] = 1
return name
processed = {} #处理过的点储存在这个字典里
low = lowest(costs)
while low: #直到每个元素都被处理过了一次
for i in graph[low]:#对于最近点的所有邻居
if costs[low] + graph[low][i] < costs[i]:#如果走这条路的距离比已知最短距离更短
costs[i] = costs[low] + graph[low][i]#更新最短距离
parents[i] = low#更新父节点
low = lowest(costs) #直到每个元素都被处理过了一次
print(graph['t'])