当前位置:首页 > 数码 > Dijkstra算法的深入探索-把握效率与最优性 (dijkstra 怎么读)

Dijkstra算法的深入探索-把握效率与最优性 (dijkstra 怎么读)

admin7个月前 (04-16)数码66

引言

在计算机科学和图论中,算法在有效解决复杂问题方面起着至关重要的作用。其中一个突出的算法是Dijkstra算法,它由荷兰计算机科学家Edsger W. Dijkstra于1956年开发。Dijkstra算法已经成为路途导航和网络优化领域的基石。

Dijkstra算法

Dijkstra算法是一种常用的算法,用于查找加权图中两个节点之间的最短路径。它基于贪婪原理,每一步中总是选择具有最小暂定距离的节点。这样可以保证算法首先探索一条最有希望的路径,从而找到最短路径。

算法步骤

  1. 初始化:为图中的每个节点分配一个暂定的距离值。将源节点的距离设置为0,所有其他节点的距离设置为无穷大。将所有节点标记为未访问。
  2. 选择最小距离节点:从所有未访问节点中选择具有最小暂定距离的节点作为当前节点。
  3. 相邻节点的探索:遍历当前节点的所有相邻节点。
  4. 更新距离:对于每个相邻节点,如果从源节点到该节点的路径长度(通过当前节点)小于其当前暂定距离,则更新该相邻节点的暂定距离。
  5. 标记为已访问:将当前节点标记为已访问。
  6. 选择下一个当前节点:重复步骤2-5,直到所有节点都被标记为已访问。
  7. 最短路径重构:根据暂定距离值,重构从源节点到所有其他节点的最短路径。

重要限制

需要注意的是,Dijkstra算法假设边的权重不是负值。边的权重为负可能使算法产生误报或使其进入无限循环。如果边的权重为负,应该使用Bellman-Ford算法或A算法等其他算法。

效率和最优性

效率

Dijkstra算法的时间复杂度为O((V+E)logV),其中V表示图中节点的数量,E表示图中的边数。为了提高算法的性能,可以使用有效的数据结构,例如优先级队列或最小堆。

最优性

在边的权重非负的情况下,Dijkstra算法保证找到图中源节点与所有其他节点之间的最短路径。这是因为贪婪原理保证算法始终选择最短的路径。

现实世界的应用程序

Dijkstra算法由于能够在加权图中找到最短路径,因此在现实世界中有很多应用。以下是一些最突出的应用:

导航系统

Dijkstra算法被广泛应用于导航系统中,以确定两个位置之间的最短路线。通过将道路网络表示为加权图,节点表示路口,边表示具有相关权重(如距离或旅行时间)的道路,该算法帮助驾驶员找到最有效的路径。

网络路由

在计算机网络中,路由器使用Dijkstra算法来确定传输数据包的最佳路径。通过将网络拓扑视为一个图,并根据延迟或带宽等因素为链路分配权重,该算法有助于最小化延迟和拥塞。

运输与物流

Dijkstra算法应用于运输和物流管理系统。它帮助优化递送服务、公共交通系统和航空网络的路线。通过考虑距离、交通状况或运输成本等因素,该算法有助于最大限度地减少旅行时间,减少燃料消耗,提高运输效率。

结论

Dijkstra算法是一种有效的算法,用于查找加权图中两个节点之间的最短路径。它以其效率、最优性和广泛的现实世界应用而著称。Dijkstra算法在许多领域发挥着至关重要的作用,例如导航、网络路由和运输,它将继续在解决复杂问题和优化系统中发挥关键作用。


【数据结构】最短路径之迪杰斯特拉(Dijkstra)算法与弗洛伊德(Floyd)算法

迪杰斯特拉(Dijkstra)算法核心: 按照路径长度递增的次序产生最短路径。

迪杰斯特拉(Dijkstra)算法步骤:(求图中v0到v8的最短路径)并非一下子求出v0到v8的最短路径,而是 一步一步求出它们之间顶点的最短路径 ,过过程中都是 基于已经求出的最短路径的基础上,求得更远顶点的最短路径,最终得出源点与终点的最短路径 。

弗洛伊德(Floyd)算法是一个经典的 动态规划算法 。

最短路径 | 深入浅出Dijkstra算法(一)

上次我们介绍了神奇的只有 五行的 Floyd-Warshall 最短路算法 ,它可以方便的求得 任意两点的最短路径, 这称为 “多源最短路”。

这次来介绍 指定一个点(源点)到其余各个顶点的最短路径, 也叫做 “单源最短路径”。 例如求下图中的 1 号顶点到 2、3、4、5、6 号顶点的最短路径。

与 Floyd-Warshall 算法一样,这里仍然 使用二维数组 e 来存储顶点之间边的关系, 初始值如下。

我们还需要用 一个一维数组 dis 来存储 1 号顶点到其余各个顶点的初始路程, 我们可以称 dis 数组为 “距离表”, 如下。

我们将此时 dis 数组中的值称为 最短路的“估计值”。

既然是 求 1 号顶点到其余各个顶点的最短路程, 那就 先找一个离 1 号顶点最近的顶点。

通过数组 dis 可知当前离 1 号顶点最近是 2 号顶点。 当选择了 2 号顶点后,dis[2]的值就已经从“估计值”变为了“确定值”, 即 1 号顶点到 2 号顶点的最短路程就是当前 dis[2]值。

为什么呢?你想啊, 目前离 1 号顶点最近的是 2 号顶点,并且这个图所有的边都是正数,那么肯定不可能通过第三个顶点中转,使得 1 号顶点到 2 号顶点的路程进一步缩短了。 因此 1 号顶点到其它顶点的路程肯定没有 1 号到 2 号顶点短,对吧 O(∩_∩)O~

既然选了 2 号顶点,接下来再来看 2 号顶点 有哪些 出边 呢。有 2->3 和 2->4 这两条边。

先讨论 通过 2->3 这条边能否让 1 号顶点到 3 号顶点的路程变短。 也就是说现在来比较 dis[3] 和 dis[2]+e[2][3] 的大小。其中 dis[3]表示 1 号顶点到 3 号顶点的路程,dis[2]+e[2][3]中 dis[2]表示 1 号顶点到 2 号顶点的路程,e[2][3]表示 2->3 这条边。所以 dis[2]+e[2][3]就表示从 1 号顶点先到 2 号顶点,再通过 2->3 这条边,到达 3 号顶点的路程。

我们发现 dis[3]=12,dis[2]+e[2][3]=1+9=10,dis[3]>dis[2]+e[2][3],因此 dis[3]要更新为 10。这个过程有个专业术语叫做 “松弛” 。即 1 号顶点到 3 号顶点的路程即 dis[3],通过 2->3 这条边 松弛成功。 这便是 Dijkstra 算法的主要思想: 通过 “边” 来松弛 1 号顶点到其余各个顶点的路程。

同理通过 2->4(e[2][4]),可以将 dis[4]的值从 ∞ 松弛为 4(dis[4]初始为 ∞,dis[2]+e[2][4]=1+3=4,dis[4]>dis[2]+e[2][4],因此 dis[4]要更新为 4)。

刚才我们对 2 号顶点所有的出边进行了松弛。松弛完毕之后 dis 数组为:

接下来,继续在剩下的 3、4、5 和 6 号顶点中,选出离 1 号顶点最近的顶点。通过上面更新过 dis 数组,当前离 1 号顶点最近是 4 号顶点。此时,dis[4]的值已经从“估计值”变为了“确定值”。下面继续对 4 号顶点的所有出边(4->3,4->5 和 4->6)用刚才的方法进行松弛。松弛完毕之后 dis 数组为:

继续在剩下的 3、5 和 6 号顶点中,选出离 1 号顶点最近的顶点,这次选择 3 号顶点。此时,dis[3]的值已经从“估计值”变为了“确定值”。对 3 号顶点的所有出边(3->5)进行松弛。松弛完毕之后 dis 数组为:

继续在剩下的 5 和 6 号顶点中,选出离 1 号顶点最近的顶点,这次选择 5 号顶点。此时,dis[5]的值已经从“估计值”变为了“确定值”。对5号顶点的所有出边(5->4)进行松弛。松弛完毕之后 dis 数组为:

最后对 6 号顶点的所有出边进行松弛。因为这个例子中 6 号顶点没有出边,因此不用处理。 到此,dis 数组中所有的值都已经从“估计值”变为了“确定值”。

最终 dis 数组如下,这便是 1 号顶点到其余各个顶点的最短路径。

OK,现在来总结一下刚才的算法。 Dijkstra算法的基本思想是:每次找到离源点(上面例子的源点就是 1 号顶点)最近的一个顶点,然后以该顶点为中心进行扩展,最终得到源点到其余所有点的最短路径。

基本步骤如下:

在 博客 中看到两个比较有趣的问题,也是在学习Dijkstra时,可能会有疑问的问题。

当我们看到上面这个图的时候,凭借多年对平面几何的学习,会发现在“三角形ABC”中,满足不了 构成三角形的条件(任意两边之和大于第三边)。 纳尼,那为什么图中能那样子画?

还是“三角形ABC”,以A为起点,B为终点,如果按照平面几何的知识, “两点之间线段最短”, 那么,A到B的最短距离就应该是6(线段AB),但是,实际上A到B的最短距离却是3+2=5。这又怎么解释?

其实,之所以会有上面的疑问,是因为 对边的权值和边的长度这两个概念的混淆, 。之所以这样画,也只是为了方便理解(每个人写草稿的方式不同,你完全可以用别的方式表示,只要便于你理解即可)。

PS:数组实现邻接表可能较难理解,可以看一下 这里

参考资料:

怎么读

Dijkstra算法是一种基于贪心策略的算法。每次新扩展一个路程最短的点,更新与其相邻的点的路程。当所有边权都为正时,由于不会存在一个路程更短的没扩展过的点,所以这个点的路程永远不会再被改变,因而保证了算法的正确性。

根据这个原理, 用Dijkstra算法求最短路径的图不能有负权边, 因为扩展到负权边的时候会产生更短的路径,有可能破坏了已经更新的点路径不会发生改变的性质。

那么,有没有可以求带负权边的指定顶点到其余各个顶点的最短路径算法(即“单源最短路径”问题)呢?答案是有的, Bellman-Ford算法 就是一种。(我们已经知道了 Floyd-Warshall 可以解决“多源最短路”问题,也要求图的边权均为正)

通过 邻接矩阵 的Dijkstra时间复杂度是。其中每次找到离 1 号顶点最近的顶点的时间复杂度是 O(N),这里我们可以用 优先队列(堆) 来优化,使得这一部分的时间复杂度降低到。这个我们将在后面讨论。

免责声明:本文转载或采集自网络,版权归原作者所有。本网站刊发此文旨在传递更多信息,并不代表本网赞同其观点和对其真实性负责。如涉及版权、内容等问题,请联系本网,我们将在第一时间删除。同时,本网站不对所刊发内容的准确性、真实性、完整性、及时性、原创性等进行保证,请读者仅作参考,并请自行核实相关内容。对于因使用或依赖本文内容所产生的任何直接或间接损失,本网站不承担任何责任。

标签: 算法

“Dijkstra算法的深入探索-把握效率与最优性 (dijkstra 怎么读)” 的相关文章

编程利器-面试法宝-刷题360-悟透算法真理 (面条式编程)

编程利器-面试法宝-刷题360-悟透算法真理 (面条式编程)

最近不时在刷算法题,刷华为OD算法题,有诸多好处: 宿愿用我自己疯狂刷题的劲头,感化大家,让大家爱上刷题,顺利经过华为OD机试,把握更多低劣的算法。 上方这道题,是很经典的深度优先搜查...

面向跨领域数据的迁移学习算法与模型研究 (什么是跨领域)

面向跨领域数据的迁移学习算法与模型研究 (什么是跨领域)

引言 随着数据的快速增长和跨领域应用的需求,如何利用已有的知识和数据来解决新领域的问题成为了一个重要的研究方向。迁移学习作为一种有效的机器学习方法,可以通过利用源领域的知识和数据来改善目标领...

如何选择和使用-业务模型与算法模型 (如何选择和使用注意事项)

如何选择和使用-业务模型与算法模型 (如何选择和使用注意事项)

数据模型:业务模型与算法模型的全面解析 导言 数据的世界离不开模型,但"模型"一词的使用往往令人困惑。从营销中的 4P 模型到机器学习中的 K-means 聚类,它们都被称为模型。那么,这些模型...

使用生成对抗网络实现图像风格转换的突破性新算法 (使用生成对抗性网络的舞蹈动作生成)

使用生成对抗网络实现图像风格转换的突破性新算法 (使用生成对抗性网络的舞蹈动作生成)

一、图像风格转换简介 图像风格转换是指将一张图像的风格转换为另一张图像的风格,而保持图像内容不变。传统的图像风格转换方法通常基于图像的像素级别操作,如调整亮度、对比度和色彩等。这些方法往往无...

程序开发中罕用的十种算法-你用过几种 (程序开发中罕见的语言)

程序开发中罕用的十种算法-你用过几种 (程序开发中罕见的语言)

当编写程序时,了解和经常使用不同的算法对处置疑问至关关键。以下是C#中罕用的10种算法,每个算法都随同着示例代码和详细说明。 1.冒泡排序(BubbleSort): 冒泡排序...

时序分析中的常用算法-都在这里了 (时序分析的特点)

时序分析中的常用算法-都在这里了 (时序分析的特点)

简介 时序分析是一种预测建模技术,它利用历史数据中事件的时间特征来预测未来事件的特征。它不同于回归分析,因为时序分析依赖于事件发生的顺序。 时序分析类型 时序分析分为两类: 静态时序分...

强化学习算法在资源调度与优化领域的革命性应用 (深度学习算法)

强化学习算法在资源调度与优化领域的革命性应用 (深度学习算法)

强化学习简介 强化学习是一种机器学习方法,通过智能体与环境的交互来学习最优策略。在资源调度与优化中,我们可以将资源调度问题看作是一个强化学习问题,其中智能体是资源调度器,环境是计...