狄克斯特拉算法 / 带权图的最短路径 / python实现

本文深入探讨了狄克斯特拉算法和贝尔曼·福德算法的工作原理,前者擅长解决带权图中从一点到其他各点的最短路径问题,尤其适用于有向无环且无负权重的图;后者则能处理可能存在负权重的图,并通过多次松弛操作检测负循环。文章详细阐述了两种算法的步骤和应用场景。
摘要由CSDN通过智能技术生成
简述

狄克斯特拉算法用于找到带权图中,某点到其他各点的最短路径(BFS用于找出无权图中的最短路径)

只适用于

  1. 有向无环图
  2. 无负权重图,因为狄克斯特拉算法在处理节点时候采用贪心思想,即某节点一旦被处理了,就说明不存在到达该节点更小开销的路径
    (存在负权重可以采用贝尔曼·福德算法)
"""
贝尔曼·福德算法
1) 初始化时起点到其他点的距离为对应权重,无法直接到达的点则初始化为∞
2) 起点到自身的距离为0 (D[起点] = 0)
3) 对每条边进行v-1次松弛(v为节点个数)
"""
for i in range(v-1):
    # 每条边的起点froms与终点tos
	for froms, tos in edges:
        # 其中D[i]为起点到i点的距离,graph[froms][tos]为这条边的权重
        if D[froms] + graph[froms][tos] < D[tos]:
            D[tos] = D[froms] + graph[froms][tos]
            
# 基本重复上述过程,检查是否存在负循环
for i in range(v-1):
	for froms, tos in edges:
        # 表示存在负循环
        if D[froms] + graph[froms][tos] < D[tos]:
            D[tos] = float("-inf")
算法过程
  1. 每次找出起点到该点开销最小的结点
  2. 以1中找到的结点作为“跳板”,遍历“跳板”结点的邻居结点,检查是否能更新到达这些邻居结点的更小开销
  3. 重复1、2两步,直到对图中所有结点都这样做了
costs = {"点": "起点到该点的距离"}
neighbors = {"点": "该点的邻居结点"}
# 图
graph = []


# 在未处理的结点中找出开销最小的
def find_lowest_cost_node(costs):
    lowest_cost = float("inf")
    lowest_cost_node = None
    for node in costs:
        cost = costs[node]
        if cost < lowest_cost and node not in processed:
            lowest_cost = costs
            lowest_cost_node = node
    return lowest_cost_node


node = find_lowest_cost_node(costs)
# 存储已经处理过的结点
processed = set()
while node:
    # 起点到“跳板”结点的开销
    cost = costs[node]
    # 遍历“跳板”结点的邻居
    for neighbor in neighbors[node]:
        # 检查是否需要更新
        new_cost = cost + graph[node][neighbor]
        if new_cost < costs[neighbor]:
            costs[neighbor] = new_cost
    processed.add(node)
    node = find_lowest_cost_node(costs)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值