首页 > 编程语言 >算法详解——Dijkstra算法

算法详解——Dijkstra算法

时间:2024-03-18 17:03:35浏览次数:27  
标签:路径 Dijkstra 最短 算法 详解 顶点 起点

  Dijkstra算法的目的是寻找单起点最短路径,其策略是贪心加非负加权队列

一、单起点最短路径问题

  单起点最短路径问题:给定一个加权连通图中的特定起点,目标是找出从该起点到图中所有其他顶点的最短路径集合。需要明确的是,这里关心的不仅仅局限于寻找一条从起点出发到任一其他顶点的单一最短路径;单起点最短路径问题要求的是一组路径,每条路径都从起点出发通向图中的一个不同顶点,当然,其中某些路径可能具有公共边。

二、Dijkstra算法原理

  Dijkstra算法是一种高效地找出图中从一个给定起点到所有其他顶点最短路径的方法。它按照距离起点的远近顺序,逐步确定到各个顶点的最短路径。具体来说,算法首先找到距离起点最近的顶点,并确定它们之间的最短路径;然后,它接着寻找下一个最近的顶点,依此类推。在第 i i i 次迭代之前,算法已经确定了到达最近的 i − 1 i-1 i−1个顶点的最短路径,这些顶点及其路径构成了原图的一个子图,形成一棵以起点为根的树。

  重要的是,由于图中所有边的权重都为非负,算法能够保证每次迭代找到的是当前可达顶点中距离起点最近的一个。这些待选顶点,称为“边缘顶点”,位于已构建的子树的外围。理论上,图中的所有其他顶点也可以被视为边缘顶点,但它们与树中顶点的连接权重被假设为无限大。

  为了求出下一个最接近起点的顶点,Dijkstra算法计算每个边缘顶点至其最近的树内顶点的距离(即该边的权重),并将此距离与从起点到该树内顶点的已知最短路径长度相加。在所有这些候选顶点中,算法选择总和最小的顶点作为下一个最近顶点。Dijkstra算法的核心在于,通过仅对这些特定的候选路径进行比较,就可以有效地找到最短路径。

三、Dijkstra算法应用

  为了简化算法的实施过程,我们为每个顶点引入两个辅助标记。第一个标记是一个数值标记 d d d,它记录了从算法开始到当前为止,从起点到该顶点的最短路径长度。随着算法的进行,当新的顶点被加入到树中时, d d d 的值更新为从起点到这个新顶点的最短路径长度。第二个标记则记录了该路径上的倒数第二个顶点,即当前构建的树中该顶点的父节点(对于起点以及那些尚未与树中的顶点直接相连的顶点,这个标记不必指定)。有了这两个标记后,寻找下一个最近顶点 u ∗ u^{ *} u∗ 变得相对直接:我们仅需在所有边缘顶点中找到具有最小 d d d 值的顶点即可,而这个查找过程的顺序并不重要。这样,这两个标记极大地简化了算法的步骤,使得确定最短路径的过程更加高效和直观。

在确定了加入树中的顶点u*以后,还需要做两个操作:

  • 把 u ∗ u^{ *} u∗ 从边缘集合移到树顶点集合中。

  • 对于余下的每一个边缘顶点 u u u,如果通过权重为 w ( u ∗ , u ) w(u^{ *}, u) w(u∗,u) 的边和 u ∗ u^{ *} u∗ 相连,当 d u ∗ + w ( u ∗ , u ) < d u d_{u^{*}} +w(u^{*},u)<d_{u} du∗​+w(u∗,u)<du​时,把 u u u 的标记分别更新为 u ∗ u^{ *} u∗ 和 d u ∗ + w ( u ∗ , u ) d_{u^{*}} +w(u^{*},u) du∗​+w(u∗,u)。

在这里插入图片描述
  最短的路径(从左列中的目标项点根据非数字标记向起点回溯,来确定最短路径)和它们的长度(由树中数字标记给出)如下:

  • 从 a a a 到 b b b : a − b a-b a−b, 长度为3

  • 从 a a a 到 d d d : a − b − d a-b-d a−b−d, 长度为5

  • 从 a a a 到 c c c ; a − b − c a-b-c a−b−c, 长度为7

  • 从 a a a 到 e e e : a − b − d − e a-b-d-e a−b−d−e,长度为9

Dijkstra(G, s)
# 单起点最短路径的Dijkstra算法
# 输入: 带有非负权重的连通图G=<V, E>以及起点顶点s
# 输出: 对于V中的每个顶点v,从s到v的最短路径长度d[v],
# 以及路径上的倒数第二个顶点p[v]

Initialize(Q)  # 将顶点优先队列初始化为空
for v in V:
    d[v] ← ∞
    p[v] ← None
    Insert(Q, v, d[v])  # 初始化优先队列中顶点的优先级

d[s] ← 0
Decrease(Q, s, d[s])  # 更新s的优先级为d[s]
p[s] ← None

for i from 0 to |V| - 1 do:
    u ← DeleteMin(Q)  # 删除优先级最小的元素
    for 每一个与u相邻的顶点u' do:
        if d[u] + w(u, u') < d[u']:
            d[u'] ← d[u] + w(u, u')
            p[u'] ← u
            Decrease(Q, u', d[u'])

标签:路径,Dijkstra,最短,算法,详解,顶点,起点
From: https://blog.csdn.net/python_plus/article/details/136813327

相关文章

  • 代码随想录算法训练营第23天|669. 修剪二叉搜索树|108.将有序数组转换为二叉搜索树|53
    代码随想录算法训练营第23天|669.修剪二叉搜索树|108.将有序数组转换为二叉搜索树|538.把二叉搜索树转换为累加树|总结篇669.修剪二叉搜索树这道题目比较难,比添加增加和删除节点难的多,建议先看视频理解。题目链接/文章讲解:https://programmercarl.com/0669.%E4%BF%A......
  • 代码随想录算法训练营第27天|39. 组合总和|40.组合总和II|131.分割回文串
    代码随想录算法训练营第27天|39.组合总和|40.组合总和II|131.分割回文串详细布置39.组合总和本题是集合里元素可以用无数次,那么和组合问题的差别其实仅在于startIndex上的控制题目链接/文章讲解:https://programmercarl.com/0039.%E7%BB%84%E5%90%88%E6%80%BB%E5%9......
  • ThreadLocal详解
    今天学到了ThreadLocal,这是一个重要的知识点,面试也会问到ThreadLocal是一个线程局部变量。它可以在每个线程中存储特定于该线程的数据,并且这些数据对其他线程不可见。ThreadLocal提供了一种线程封闭(Threadconfinement)的机制,使得每个线程都可以拥有自己的变量副本,从而避免了......
  • java数据结构与算法刷题-----LeetCode45. 跳跃游戏 II
    java数据结构与算法刷题目录(剑指Offer、LeetCode、ACM)-----主目录-----持续更新(进不去说明我没写完):https://blog.csdn.net/grd_java/article/details/123063846文章目录解题思路:时间复杂度O(n......
  • java数据结构与算法刷题-----LeetCode55. 跳跃游戏
    java数据结构与算法刷题目录(剑指Offer、LeetCode、ACM)-----主目录-----持续更新(进不去说明我没写完):https://blog.csdn.net/grd_java/article/details/123063846文章目录解题思路:时间复杂度O(n......
  • AES算法:加密通信的新选择
    AES算法起源:AES(AdvancedEncryptionStandard)算法是一种对称密钥加密算法,由比利时密码学家JoanDaemen和VincentRijmen设计,于2001年被美国国家标准技术研究所(NIST)确定为新的数据加密标准。AES算法取代了DES算法,成为当前最流行的对称加密算法之一。AES算法原理:密钥扩展:根......
  • 代码随想录算法训练营第五十天 | 123. 买卖股票的最佳时机 III,188. 买卖股票的最佳时
    123.买卖股票的最佳时机III 已解答困难 相关标签相关企业 给定一个数组,它的第 i 个元素是一支给定的股票在第 i 天的价格。设计一个算法来计算你所能获取的最大利润。你最多可以完成 两笔 交易。注意:你不能同时参与多笔交易(你必须在再次购......
  • 详解GaussDB(DWS)中3个防过载检查项
    本文分享自华为云社区《【防过载检查项】》,作者:譡里个檔。1.GUC参数检查目的:针对不同版本建议设定不同的参数值,当前先检查出来,后续diagnosis会给出建议值SELECTsplit_part((substring(version()from'\((.*)\)')),'',2)ASversion,(EXISTS(SELECT1FROM(S......
  • 讲解贪心算法
    贪心算法是一种基于贪心策略的算法,它在每一步选择中都采取最优的选择,希望最终能够达到全局最优的结果。贪心算法通常用来求解最优化问题,如最短路径问题、最小生成树问题等。贪心算法的核心思想是每一步都选择当前情况下的最优解,而不考虑过去或将来的情况。这意味着贪心算法不......
  • 讲解动态规划算法
    动态规划(DynamicProgramming,简称DP)是一种通过将问题分解为子问题来求解复杂问题的优化算法。它一般用于在有重叠子问题的情况下,通过存储已求解的子问题结果来避免重复计算,从而大大提高算法的效率。动态规划算法的基本思想是将原问题划分为多个子问题,先求解子问题,再由子问题的......