狄克斯特拉算法的基础关系模型如下:
它解决的是从起点到终点的最佳路线问题。
如果把上图的数字代表耗时,那就是要找到耗时最短的路径。
由于本人较懒,先将源代码给出来,之后有时间再解释代码的意思。
下面代码针对的关系模型如下:
# 数据关系模型用字典嵌套字典的形式来表达。
graph = {
'start': {'a': 3, 'b': 6, 'c': 4},
'a': {"d": 8},
"b": {'d': 10, "e": 5},
'c': {"e": 6},
"d": {"f": 2, 'g': 7, "e": -2},
'e': {'g': 3, 'h': 6},
'f': {'fina': 9},
'g': {'fina': 8},
"h": {'fina': 7},
'fina': {}
}
# 定义耗时的字典。
costs = {}
costs["start"] = 0
# 存储父节点的字典。
parents = {}
def find_lowest_cost_node(node, node_cost):
"""找到start下一级节点,并更新costs里的值,和parents里面的值"""
# 获取当前节点的所有下一级节点和其权重值。
for next_node in graph[node].keys():
# 判断next_node是否在costs里存在。
if next_node in costs.keys():
if graph[node][next_node] + node_cost < costs[next_node]:
costs[next_node] = graph[node][next_node] + node_cost
parents[next_node] = node
else:
continue
else:
costs[next_node] = graph[node][next_node] + node_cost
parents[next_node] = node
def find_path(node):
"""利用递归算法,获取parents里面的父节点"""
super_node = parents[node]
print(super_node)
if super_node is not 'start':
super_node= find_path(super_node)
return super_node
else:
return 'start'
def main():
"""主函数部分"""
# 给出起点的节点
node = "start"
while node is not "fina":
# 找到costs里面最小值的键,将其从costs里面剔除
node = min(costs, key=costs.get)
node_cost = costs[node]
del costs[node]
if graph[node]:
find_lowest_cost_node(node, node_cost)
else:
# 如果没有下一级节点,就继续找下一个最小的节点
continue
# parents里面打印出来的,就可以从终点开始追溯其父节点,最终就会追溯到起点。
print(parents)
# 获取父节点。并打印出来。
finally_node = 'fina'
print(finally_node)
find_path(finally_node)
if __name__ == '__main__':
main()
大体的思路如下:
每次获取costs里面最小的节点,并把最小节点从costs里面删除,然后找到该节点的下一级节点。
如果下一级节点已经在costs里存在,则需要对值进行比较。
如果经由该节点达到下一级节点的值要小,就需要更新下一级节点的cost,并更新其父节点为当前节点。
如果找到了最终的节点‘fina’,并且其cost在costs里面是最小的。就结束循环。
程序运行的结果如下: