最短路径算法——Dijkstra介绍

2023-05-16

个人心得体会:理解这种或这类算法,可以先从小规模的问题入手,并逐渐推广到问题变复杂的情况,这样理解起来也可以更方便和透彻。——和数学归纳法很相似。


图简介

以使用地图APP为例,假设你想前往某个目的地,此间有很多条线路可以选,如地铁、不同的公交换乘方案。而不同的方案所需换乘的次数不同。那么怎么才能选出换乘次数最少的方案呢?

有向图:节点和节点之间的连接是有方向的。

无向图:节点和节点之间相互联系。

上文提到的最优换乘方案选择,即可以用有向图进行抽象(总不能在同样的两个公交站之间来回换乘吧)。根据这个图,可以做的事:1. 观察是否有从“双子峰”前往“金门大桥”的路径,2. 最短路径是哪条。

此时图是为无权重的,即去每条路线的cost都相同。那么当考虑加权呢,即乘坐不同公交耗费时间不同,怎么来寻找前往目的地的最短时间?就需要适用于加权图的搜索算法出场,接下来介绍Dijkstra算法。


Dijkstra

主要解决的问题是给定起点S和目标点E,如何得出S到E的最短路径。算法主要思想是

带权的有向图

为什么不能处理负权边?

可能出现这样一种情况:因为dijktra算法每次都先寻找前往节点的最小值(正数),并将节点加入已访问集合之中,之后不再对其进行更新。

举个例子,目标:寻找A-C的最短路径。使用Dijkstra算法时,比较从A->B和A->C的开销,显然A->C的更小,于是选择到C的路径,并将C处理成处理过的节点。到这里发现了什么问题呢,A->B->C不是更短吗?就是负权边的情况。

Dijkstra算法实现步骤

  1. 寻找某点开始,相邻的最短路径;
  2. 选另一条路径,比较同样前往此节点的,更新开销最小的,并更新路径;
  3. 重复此步骤,直到最后一个节点;
  4. 计算最终路径。

示例

使用的数据结构:

  1. graph:键值对,保存路径的长短信息
  2. costs:数组,保存到达当前节点的最短路径
  3. parent:键值对,保存最短路径
# coding: utf-8
# 以《图解算法》7.5中的图为例

def graph_gen():
    graph = {}
    graph['start'] = {}
    graph['start']['a'] = 6
    graph['start']['b'] = 2
    graph['b'] = {}
    graph['b']['a'] = 3
    graph['b']['end'] = 5
    graph['a'] = {}
    graph['a']['end'] = 1
    graph['end'] = {}
    return graph

def cost_gen():
    inifity = float('inf')
    costs = {}
    costs['a'] = 6
    costs['b'] = 2
    costs['end'] = inifity
    return costs

def parent_gen():
    parent = {}
    parent['a'] = 'start'
    parent['b'] = 'start'
    parent['end'] = None
    return parent

def find_lowest_cost_node(costs, processed):
    lowest_cost = float('inf')
    lowest_node = None
    for key in costs.keys():
        if key not in processed and lowest_cost > costs[key]:
                lowest_cost = costs[key]
                lowest_node = key
    return lowest_node

def Dijkstra(graph, costs, relation):
    processed = []
    node = find_lowest_cost_node(costs, processed)
    while node is not None:
        cost = costs[node]
        neighbors = graph[node]
        for n in neighbors.keys():
            new_cost = cost + neighbors[n]
            if costs[n] > new_cost:
                costs[n] = new_cost
                relation[n] = node
        processed.append(node)
        node = find_lowest_cost_node(costs, processed)
    return relation

def output(realtion):
    begin = relation['end']
    str_ = 'end--'

    while begin is not None:
        for key, value in relation.items():
            if key == begin:
                str_ += begin + '__'
                begin = value
                break
        else:
            begin = None
    print str_ + 'start'

relation = Dijkstra(graph_gen(), cost_gen(), parent_gen())
# print relation
output(relation)
NodeParent    --->NodeParent
astartab
bbstart
endenda

 

结果输出:因Dijkstra算法是从末尾指向头的key value类型,倒着就是最短路径

end--a__b__start

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

最短路径算法——Dijkstra介绍 的相关文章

  • WEEK(7)作业——最短路专题(Floyd、Dijkstra、SPFA、负权环路)

    A TT的魔法猫 题目描述 众所周知 xff0c TT 有一只魔法猫 这一天 xff0c TT 正在专心致志地玩 猫和老鼠 游戏 xff0c 然而比赛还没开始 xff0c 聪明的魔法猫便告诉了 TT 比赛的最终结果 TT 非常诧异 xff0
  • 机器人路径规划之Dijkstra算法

    在机器人路径规划之动态窗口法文中 xff0c 介绍了一种局部路径规划方法 动态窗口法 xff0c 本文将介绍一种全局路径规划方法 Dijkstra算法 狄克斯特拉算法 Dijkstra算法是从一个顶点到其余各顶点的最短路径算法 xff0c
  • 数据结构——迪杰斯特拉(Dijkstra)算法

    迪杰斯特拉算法又叫狄克斯特拉算法 是从一个顶点到其余各顶点的最短路径算法 解决的是有权图中最短路径问题 迪杰斯特拉算法主要特点是从起始点开始 采用贪心算法的策略 每次遍历到始点距离最近且未访问过的顶点的邻接节点 直到扩展到终点为止 以下是数
  • 深入分析 (迪杰斯特拉算法) Dijkstra 算法实现原理

    迪杰斯特拉 Dijkstra 算法是典型最短路径算法 用于计算一个节点到其他节点的最短路径 它的主要特点是以起始点为中心向外层层扩展 广度优先搜索思想 直到扩展到终点为止 基本思想 通过Dijkstra计算图G中的最短路径时 需要指定起点s
  • 【复赛模拟试题】收费站(二分答案+Dijkstra)

    问题描述 在某个遥远的国家里 有n个城市 编号为1 2 3 n 这个国家的政府修建了m条双向的公路 每条公路连接着两个城市 沿着某条公路 开车从一个城市到另一个城市 需要花费一定的汽油 开车每经过一个城市 都会被收取一定的费用 包括起点和终
  • 迪杰斯特拉(Dijkstra)算法 Java实现(最短路径)

    基本思想 通过Dijkstra计算图G中的最短路径时 需要指定起点vs 即从顶点vs开始计算 此外 引进两个集合S和U S的作用是记录已求出最短路径的顶点 而U则是记录还未求出最短路径的顶点 以及该顶点到起点vs的距离 初始时 S中只有起点
  • 1345:香甜的黄油(Dijkstra)---信息学奥赛一本通

    题目描述 农夫John发现做出全威斯康辛州最甜的黄油的方法 糖 把糖放在一片牧场上 他知道N 1 N 500 只奶牛会过来舔它 这样就能做出能卖好价钱的超甜黄油 当然 他将付出额外的费用在奶牛上 农夫John很狡猾 像以前的巴甫洛夫 他知道
  • 天梯题集——紧急救援(Dijkstra+倒序打印分析)

    Dijkstra算法 用于求单源到其他点的最短路径 紧急救援 该题与 Dijkstra模板题 的不同之处在于该题需要记录更多信息 主要思路从局部最优到整体最优 类似dp的思想 include
  • CUDA dijkstra 算法 [关闭]

    很难说出这里问的是什么 这个问题模棱两可 含糊不清 不完整 过于宽泛或言辞激烈 无法以目前的形式合理回答 如需帮助澄清此问题以便重新打开 访问帮助中心 是否有人针对给定的稀疏矩阵 cuSPARSE 图实现了 Dijkstra 算法的 CUD
  • 如何从多路径 Dijkstra 重建路径?

    我目前正在编写一个用于图形的 PHP 库 我已经成功实现了单路径 Dijkstra 算法 但现在在路径重建阶段很难实现多路径版本 取下图 为了简单起见 该图只有从顶点 A 到 J 的路径 经过多个其他顶点 这些顶点的成本都是相等的 即每条路
  • 带优先级队列的 Dijkstra 算法

    在我的 Dijkstra 算法的实现中 我有 1 个包含所有节点的数组和 1 个包含所有节点的优先级队列 每当一个节点出队时 我都会用新的距离和它的来源更新所有相邻节点 这样我就可以回溯路径 优先级队列中的节点将更新为新距离 数组中的节点将
  • 针对某些图操作的最简单算法的建议

    这个项目的截止日期很快就到了 我没有太多时间来处理剩下的事情 因此 我不是寻找最好的 可能更复杂 耗时 算法 而是寻找最简单的算法来实现图结构上的一些操作 我需要做的操作如下 列出给定距离 X 的图网络中的所有用户 列出给定距离 X 和关系
  • Dijkstra 算法是确定性的吗?

    我认为 Dijkstra 算法是确定的 因此如果您选择相同的起始顶点 您将得到相同的结果 到每个其他顶点的距离相同 但我不认为它是确定性的 它为每个操作定义了以下操作 因为这意味着它不必首先搜索最短距离 我对么 如果我错了 你能解释一下为什
  • 让Boost Dijkstra算法在到达目的节点时停止

    我正在使用 boost graph 及其 Dijkstra 实现 当有人使用Dijkstra算法时 可能是为了知道图中2个节点之间的最短路径 但是 由于您需要检查图中的所有节点以找到最短路径 通常 如 boost 算法 Dijkstra 会
  • Dijkstra最短路径算法

    以下是我们教授给我们的算法摘要 步骤 3 中提到的图中节点的父节点是什么 我有点困惑 因为我认为节点只有邻居而没有父节点 我的第二个问题是关于第 3 步 拾取堆栈中的第索引条记录 由于堆栈只允许您查看顶部 所以我不确定拾取第索引记录意味着什
  • 如果广度优先搜索 (BFS) 可以更快地完成同样的事情,为什么还要使用 Dijkstra 算法呢?

    两者都可用于从单一源查找最短路径 BFS运行在O E V 而 Dijkstra 运行O V E log V 另外 我见过 Dijkstra 在路由协议中的使用很像 因此 如果 BFS 可以更快地完成同样的事情 为什么还要使用 Dijkstr
  • 如何在 QuickGraph Dijkstra 或 A* 中设置目标顶点

    我使用的是 QuickGraph 3 6 版 我找到了函数 SetRootVertex 但没有 SetTagretVertex 我需要这个 因为我正在巨大的图中搜索短路径 这会大大加快程序速度 有问题的类是 DijkstraShortest
  • 具有固定边数的最短路径

    在高效的时间内找到通过图形的最短路径 并附加该路径必须完全包含的约束n nodes 我们有一个有向加权图 它可能包含也可能不包含循环 我们可以使用 Dijkstra 算法轻松找到最短路径 但 Dijkstra 算法不保证边的数量 我们能想到
  • Dijkstra 谈“软件工程”[关闭]

    很难说出这里问的是什么 这个问题是含糊的 模糊的 不完整的 过于宽泛的或修辞性的 无法以目前的形式得到合理的回答 如需帮助澄清此问题以便重新打开 访问帮助中心 help reopen questions 埃兹格 迪杰斯特拉 Edsger D
  • AStar-名称解释

    我正在寻找 AStar A 算法为何被称为 AStar 的解释 所有类似的 最短路径问题 算法通常都以其开发者的名字命名 那么 AStar 代表什么 有称为 A1 和 A2 的算法 后来证明A2是最优的 实际上也是可能的最好算法 所以他给它

随机推荐