登录/注册

dijkstra算法

更多

好的,我们用中文来解释 Dijkstra 算法

Dijkstra 算法是什么?

Dijkstra 算法(迪杰斯特拉算法)是一种用于在 带权有向图带权无向图 中,寻找 单个源点所有其他顶点 的最短路径的 贪心算法。这里的“权”通常指边的长度、花费、时间等非负值。

核心思想:

  1. 出发点: 从源点出发。
  2. 逐步扩展: 每一步都确定一个距离源点 最近 且尚未被确认找到最短路径的顶点(我们称之为“当前最近点”)。
  3. 更新邻居: 基于这个“当前最近点”,更新它所有邻居顶点到源点的 估计最短距离。如果通过“当前最近点”到达某个邻居的路径比之前已知的路径更短,就更新这个邻居的距离估计值。这个过程称为 松弛操作
  4. 标记确定: 将“当前最近点”标记为 已找到最短路径(它的最短距离值此时就是最终确定值)。
  5. 重复: 重复步骤 2-4,直到所有顶点都被标记为已找到最短路径,或者没有可到达的顶点为止。

为什么需要“贪心”? 在每一步,它都 只关注当前看起来最优(距离源点最近)的那个未确定顶点,认为从源点到它的最短路径已经找到(基于当前已知的所有局部信息),并利用这个信息去更新其他点的距离。这种“当前最优”的选择策略就是贪心思想的体现。

关键要求:图中不能有负权边!

算法步骤详解(手动模拟理解):

  1. 初始化:

    • 创建一个数组 dist,记录每个顶点到源点的 当前估计最短距离。源点的 dist 设为 0,其他所有顶点的 dist 设为 无穷大 (∞),表示尚未找到路径。
    • 创建一个集合 S (或标记数组),用于存放 已找到最短路径 的顶点。开始时 S 为空。
    • 创建一个集合 Q (或优先队列),包含所有顶点(或者所有未确定最短路径的顶点)。
  2. 进入主循环:

    • 步骤 A:选择当前最近点 - 从集合 Q 中找出 dist 值最小的顶点 u。这个 u 就是本轮确定的“当前最近点”。
    • 步骤 B:标记确定 - 将 uQ 中移除(或标记为已访问),并加入集合 S。这意味着顶点 u 到源点的最短路径已被最终确认,其值就是 dist[u]
    • 步骤 C:松弛操作(更新邻居) - 遍历 u 的所有 未在 S 的邻居顶点 v(即尚未确定最短路径的邻居):
      • 计算 从源点经 uv 的路径长度dist[u] + weight(u, v) (其中 weight(u, v) 是边 (u, v) 的权重)。
      • 将这个计算值 dist[u] + weight(u, v)v 当前记录的 dist[v] 进行比较。
      • 如果 dist[u] + weight(u, v) < dist[v]
        • 更新 dist[v] = dist[u] + weight(u, v)
        • (可选:记录 v 的前驱节点为 u,用于最终回溯路径)。
  3. 终止条件: 重复步骤 A-C,直到满足以下条件之一:

    • 集合 Q 变为空(所有顶点都已处理)。
    • 或者,只剩下那些 dist 值为无穷大 (∞) 的顶点(表示它们无法从源点到达)。

最终结果:

时间复杂度:

空间复杂度: O(V)(用于存储 dist、前驱、访问标记等)或 O(V + E)(存储图结构本身)。

图解比喻:

想象你(源点)站在一个城市中心。你有一张地图(图),上面标明了所有路口(顶点)和道路(边)的长度(权重,非负)。你想知道去每个路口的最短距离。

  1. 你(源点)到自己的距离是 0。
  2. 你看周围的路口(邻居),记录下直接能走到的距离(更新邻居的 dist)。
  3. 确定 最近的那个路口(A)的距离就是最短路径(加到 S)。
  4. 站在路口 A,你看 A 能直接到达的其他路口(B, C)。计算 “你 -> A -> B” 和 “你 -> A -> C” 的距离。
  5. 如果 “你 -> A -> B” 比你之前(可能直接从你那里或通过其他点)知道的到 B 的距离更短,就更新记录到 B 的最短估计距离(松弛)。
  6. 在所有 未确定最短路径 的路口中(包括你直接从中心看到的邻居和从 A 看到的邻居),再次找出离你 估计距离最近 的那个路口(假设是 C),确定 它的距离就是最终最短路径(加到 S)。
  7. 站在路口 C,重复步骤 4-6:更新 C 的邻居们的估计距离...
  8. 如此反复,直到所有路口都确定了最短距离,或者确认某些路口永远无法到达。

关键点总结:

  1. 单源最短路径: 从一个起点出发,计算到其他所有点的最短距离。
  2. 非负权边: 图中边的权重不能是负数。
  3. 贪心策略: 每一步都优先处理当前距离源点最近的未确定顶点。
  4. 松弛操作: 核心步骤,利用新确定的点去优化其邻居的距离估计。
  5. 逐步确定: 顶点一旦被加入 S 集合,其 dist 值就不再改变,即为最终的最短路径长度。

Dijkstra vs BFS:

为什么不能有负权边?

假设源点为 S,目标点为 T。

  1. S 有两条边:S->A (权 1), S->B (权 2)。
  2. A 到 T 有一条边:A->T (权 4)。此时 S->A->T 总权为 5。
  3. B 到 A 有一条 负权边:B->A (权 -3)。S->B->A 的权是 2 + (-3) = -1。
  4. 那么 S->B->A->T 的权是 -1 + 4 = 3,比最初的 5 更短。
  5. 如果 Dijkstra 先确定了 A 的最短路径为 S->A (权 1),并标记 A 为已完成。那么当它后续处理 B 时,即使发现 S->B->A 权为 -1,它也不会再去更新已经“完成”的 A 点(因为算法假设已完成点的距离不会再变小)。这就导致了错误,因为实际上通过 B 到 A 再到 T 的路径 (权 3) 比最初确定的 S->A->T (权 5) 更短。
  6. 存在负权边时,已经“确定”的点可能通过包含负权边的路径变得更短,破坏了 Dijkstra 算法的基础假设。这种情况下就需要使用能处理负权边的算法,如 Bellman-Ford 算法

简单示例(无负权):

      (B)
    1/   \2
   (A)   (D)
    3\   /1
      (C)

结论: Dijkstra 算法是解决 单源、非负权图最短路径问题 的最经典、最高效算法之一。理解其贪心本质(每一步选择当前最近点)、松弛操作以及负权边的限制至关重要。

中国铁路网的Dijkstra算法实现案例

该项目分别在DE1-SOC开发板的FPGA和HPS上实现了Dijkstra算法,能在中国铁路网中找到两站之间的最短距离和路线。

2024-04-09 11:10:04

车辆导航系统中最优路径算法的研究

的目的。并且改进后的 Di jkstra算法客服了传统的 Dijkstra算法计算盲目性计算的缺点,提高了路径搜寻的技术效率关键词:车辆导航系统

2023-09-21 06:25:55

全文详解A*算法及其变种

相比于 BFS,Dijkstra 算法新增了cost_so_far用于记录从当前点current到起点的路径所需要的代价,并将搜索规则改为优先搜索cost最小的点.如下图所示,,

2023-09-14 09:25:34

基于STM32的A*(A星)寻路算法实现

STM32 + LED点阵屏 实现A星算法寻路A星算法最初发表于1968年。它可以被认为是Dijkstra

资料下载 贾熹 2021-12-27 19:15:59

基于改进Dijkstra算法的多AGV动态路径规划

针对多自动导引车( Automatic guided vehicle,AGV)在柔性制造系统中岀现的路径规划与冲突问题,提出了一种基于时间窗的改进 Dijkstra算法,实现多ΔGⅤ的动态路径规划

资料下载 佚名 2021-05-17 16:30:56

一种高效节能的虚拟网络映射算法

资源评估,计算最佳映射节点。在链路映射阶段,采用υ Dijkstra算法,对于毎条候选物理链路,综合考虑链路剩氽带宽资源、途径节点剩余资源以及跳数,重新计算链路排序值,从而获得高效节能的最佳映射链路。仿真实验数据表明

资料下载 佚名 2021-05-10 15:34:33

一种优化的双层卫星网络临时按序路由算法

路由算法HCR。在LEO层使用HCR算法建立从源卫星到目的卫星的多条无循环路径,当LEO层出现网络拥塞时利用GEO层卫星实现数据分层传输。仿真结果表明,与传统

资料下载 佚名 2021-03-31 15:57:25

基于SVDPP算法的新型协同过滤推荐算法

  为进一步改善个性化推荐系统的推荐效果,通过使用强化学习方法对 SVDPP算法进行优化,提出一种新的协同过滤推荐算法。考虑用户评分的时间效应,将推荐问题转化为马尔科夫决策过程。在此基础上,利用Q-

资料下载 佚名 2021-03-09 17:20:09

路径规划算法实现原理

本文会用matlab实现Dijkstra算法,并且会分享一些函数用法的链接,也是本人学习得来,供大家参考,批评指正。

2023-09-06 15:36:53

Dijkstra算法和A*算法

在本文中,我们将主要介绍Dijkstra算法和A*算法,从成本计算的角度出发,并逐步展开讨论。 我们将从广度优先搜索开始,然后引入

2023-07-07 10:56:01

自动驾驶路径规划技术之A-Star算法

Astar算法与Dijkstra算法的效果差不多,但Astar算法访问的

2023-03-23 12:26:14

为什么很多编程语言要把0作为第一个下标索引呢?

这个问题 Dijkstra 已经解答过了,没错,就是你知道的 Dijkstra,Dijkstra 最短路径

2023-02-02 10:33:33

Dijkstra和A*算法及其Matlab实现

写在前面的话:只是对两种路径优化算法进行简单的理解和尝试,为后续使用做准备。如果用到,请再次好好理解原理和Matlab源码。

2022-12-07 15:04:36

秒杀几道运用Dijkstra算法的题目

读完本文,可以去力扣解决如下题目: 743. 网络延迟时间(中等) 1514. 概率最大的路径(中等) 1631. 最小体力消耗路径(中等) 其实,很多算法的底层原理异常简单,无非就是一步一步延伸

2021-09-24 10:59:28

7天热门专题 换一换
相关标签