python使用狄克斯特拉算法,实现带有权重的最优路径的选择

在这里插入图片描述
如上图,要找到从A点到D点,最便宜的路径。
代码如下:

from collections import deque

# 定义children表,用来记录每个节点的孩子节点是谁
children = dict()
children['a'] = ['b', 'e']
children['b'] = ['c', 'f']
children['e'] = ['c', 'f']
children['c'] = ['d']
children['f'] = ['d']
children['d'] = []

# 定义farthers表,用来记录每个节点的爸爸节点是谁
farthers = dict()
farthers['a'] = [['a', 0]]
farthers['b'] = [['a', 5]]
farthers['e'] = [['a', 0]]
farthers['c'] = [['b', 15], ['e', 30]]
farthers['f'] = [['b', 20], ['e', 35]]
farthers['d'] = [['c', 20], ['f', 10]]

infinity = float('inf')
# 定义最低费用表,用来记录从起点到每个点的最低费用是多少。这个表是狄克斯特拉算法的关键所在。
# 它的元素的值是一个列表,列表的第一个值记录这个节点花费最便宜的爸爸节点的名字,第二个值记录从起点到这个节点最便宜的费用
lowest_cost = dict()

# 定义队列my_deque,用来记录从起点到终点依次要计算的点
my_deque = deque()
start = 'a'
finish = 'd'
my_deque += start
# 定义距终点费用最便宜的爸爸节点为自己,费用为0
lowest_cost[start] = [start, 0]
# 暂定距终点费用最便宜的爸爸节点为none,费用为无穷大。
lowest_cost[finish] = ['none', infinity]

searched = []
# 只要列表不为空,就一直往下计算费用
while my_deque:
    location = my_deque.popleft()
    if location not in searched:
        my_deque += children[location]
        # 定义costs,是用来记录当前节点的所有父亲节点的名字和费用
        costs = []
        for farther in farthers[location]:
            name = farther[0]
            # 费用 = 它爸爸到它的费用 + 它爸爸到起点的费用
            cost = farther[1] + lowest_cost[name][1]
            costs.append([name, cost])
        # 按照费用对列表内的父亲节点进行排序
        costs.sort(key=lambda node: node[1])
        # 取费用最低的父亲节点,写进最低费用表
        lowest_cost[location] = costs[0]
        # 如果当前节点为终点,则打印最低费用,并退出循环
        if location == finish:
            print('最低费用为', lowest_cost[finish][1])
            break

# 定义path,用来记录最低费用的路径
path = []
# 从终点开始往前回溯,直到起点
while finish != start:
    baba = lowest_cost[finish][0]
    finish = baba
    # 这里path记录的值,是从终点到起点的路径
    path.append(baba)
# 将path反转,使其元素依次为从起点到终点的路径,符合人的习惯
path.reverse()
print('路径依次为:', path)


运行结果如下:
在这里插入图片描述

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值