迪杰斯特拉(Dijkstra)算法

2023-10-26

一 算法介绍

迪杰斯特拉算法是由荷兰计算机科学家在1956年发现的算法,此算法使用类似广度优先搜索的方法解决了带权图的单源最短路径问题。它是一个贪心算法。

二 核心思想

1. 选定一个点,这个点满足两个条件:1.未被选过,2.距离最短

2. 对于这个点的所有邻近点去尝试松弛

三 算法步骤 

首先,可以设置两个集合分别是A和B,A用来存放已经求出最短路径的点,B用来存放还未计算出最短路径的点,接下来就可以开始做题啦!!!

我们从图中任选一点来解题,假设我们将源点source选择在” 0 "这个点。一开始所有点到达源点0的距离我们假设为∞,代表不可达。源点0到自己本身的距离为0,初始化如下:此时A集合为:{0},B集合为:{1,2,3,4,5,6}

第一步:从0点开始,更新和0邻接的所有点的距离,此时,因为与0邻接的有1和2,并且到这两个点的距离,小于原来的距离,所以要将这两个点到0的距离都进行更新如下图,

第二步:从B集合里面选择一个点加入A集合,这个点要满足距离0点的距离最短,因此我们选择2这个点添加到集合A,此时集合A变为:{0,2},集合B变为:{1,3,4,5,6},如下图

第三步:选择刚刚加入的这个2点,更新所有与2点邻接的点,因为与2邻接的点有3和5,并且这两个点到0点的距离小于原来它们到0点的距离

第四步:从B集合里面选择1这点加入到集合A中,因为1这个点在B集合中距离0最近,如下图,此时A集合变成:{0,1,2},B集合变成:{3,4,5,6}

第五步:选择刚刚加入的1这个点,更新1所有的邻接点,它的邻接点有3和4,因为此刻从0到3的距离为6,小于原来0到3的距离8,因此这个时候到6的距离更新为6(5+1),此时0到4的距离被更新为11

第六步:从B集合中选择一个距离0点最小距离的点,加入集合A,此时可以选择3这个点,因为3这个点在B集合里面距离0点最近,此时集合A变为:{0,1,2,3},集合B变为:{4,5,6}

第七步:从刚刚选择的这个3点出发,更新3所有的邻接点,3的邻接点有4和5,原来4到0的距离为11,3加进来之后,4到0的距离为7,小于原来的11,所以要更新,原来5到0的距离为10,3加进来之后,5到0的距离为8,所以也要更新

第八步:从B集合中选择一个距离0点最小距离的点,因此我们选择4点,因为此时4这个点距离0点最近,为7,于是集合A变成:{0,1,2,3,4},集合B变成:{5,6}

第九步:从刚刚选择的点4出发,更新它的所有邻接点,4的邻接点有6,原来6到0的距离为∞,此时4加进来之后6到0的距离变为14,它小于∞,因此要更新6到0的距离,更新为11

第十步:从集合B中选择一个距离0点最短距离的点,加入集合,此时我们可以选择5这个点,因为这个时候它在B集合中是距离0点最近的点,于是集合A变为:{0,1,2,3,4,5},集合B变为{6}

第11步:从刚刚选择的这个点出发,也就是从点5出发,更新它所有的邻接点,此时5的邻接点为6,原来0到6的距离为14,此时点5加进来之后,0到6的距离变为了11,因此需要更新0到6的距离

第12步:因为B集合只剩下一个点,为点6,直接将其加入A集合即可,此时A集合变为:{0,1,2,3,4,5,6},B集合变为:{ },至此,从0点到其它所有点的最短路径已经算出来了,为下图

四 注意事项

1.不能处理带有负权边的图(可能得不到最优解,认为是无法处理负权图),只能处理非负权图

          为什么? ,以此图为例,按照Dijkstra的思想,首先0点加入集合,然后1点加入集合,然后3点加入集合,然后2加入集合,此时0->2更新为99-300,但是此刻已经无法更新0->3(原来的值为2)了。

              

2.只能解决单源最短路径问题

五  核心代码 

                                                                                   

以此图为例,写一段测试代码。使用邻接矩阵来存储图结构,100代表两点之间没有通路,看成无穷,你也可以使用比图中距离大的任何一个数。如下图

                                                                              

使用的数据结构有:vector,在这里,我们将最核心的代码封装成一个函数,我们最终的目的是求出某一个源点到其它点的最短距离,那么返回值可以是一个vector。并并且我们需要两个参数,分别代表图结构和源点,函数定义如下:

const int inf = 500;  //可以给别的值,只要大于图中任何一边的距离即可
vector<int> dijkstra(vector<vector<int> > G,int source)
{
    int n = G.size(); //n代表图的顶点个数
    vector<int> dis(n,inf); //dis代表源点到其它点的最短距离,inf代表无穷,初始化vector
    vector<int> vis(n,false); //vis代表某个顶点是否被访问过,初始化所有的顶点为false
    //源点到源点的距离为0
    dis[source]=0;
    
    /*
        根据前面咱们的分析可以知道,要不断寻找没有被访问过且距离源点最近的点,有n个顶点,
        就要寻找n-1次,找到点之后,对其邻接点进行松弛,为什么只要寻找n-1个点呢?因为当
        剩下一个点的时候,这个点已经没有需要松弛的邻接点了。此时从源点到这个点的距离就是最短距离了。
    */
    //可以使用一个for循环,循环n-1次,来寻找n-1个点
    for(int i=0; i<n-1; i++)
    {
        int node = -1;  //进入循环之后,假设一开始不知道哪个是没有被访问过且距离源点最短的点
        for(int j=0;j<n;j++)  //使用这个循环开始寻找没有被访问过且距离源点最短距离的点
        {
            if(!vis[j] && (node == -1 || dis[j]<dis[node]))
            {
                node = j;  //把当前距离源点最短距离的点给node
            }
        }
        //对这个距离源点最短距离的点的所有邻接点进行松弛
        for(int j=0; j<n; j++)
        {
            dis[j]=min(dis[j],dis[node]+G[node][j]);
            /*
                这边要特别注意:对于不是node的邻接点并不会影响它原来的距离,以2点为例
                对于邻接的已经访问过的点也不会产生影响,以3点为例
            */
        }
        //标记为已访问过
        vis[true];
    }
    return dis;
}

 

六 心得体会

有时候一开始不会,代码也看不懂,觉得不想照打一遍,觉得那是浪费时间,其实不然,如果不会,先按照别人的思路打一遍,然后自己带数据进去走一遍代码,带着数据多走几遍,很快就能明白。各位小伙伴们,欢迎大家来进行讨论!!! 

 

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

迪杰斯特拉(Dijkstra)算法 的相关文章

  • Dijkstra算法——java实现

    面试时遇到Dijkstra算法 这个算法我是知道的 但是没具体写过 所以答题比较慢 抽时间实现了下这个算法 nbsp Dijkstra算法基本思路 该算法的基本思路是这样的 从起始点开始 将未访问过的相邻节点加入一个优先队列 类似于广度优先
  • 机器人路径规划之Dijkstra算法

    在机器人路径规划之动态窗口法文中 xff0c 介绍了一种局部路径规划方法 动态窗口法 xff0c 本文将介绍一种全局路径规划方法 Dijkstra算法 狄克斯特拉算法 Dijkstra算法是从一个顶点到其余各顶点的最短路径算法 xff0c
  • 2、无人驾驶--路径规划算法:Dijkstra

    目录 2 Dijkstra2 1 算法简介2 2 算法思路具体流程 xff1a 2 3 算法具体实现2 3 1 程序详解 2 Dijkstra 声明 xff1a 本文是学习古月居 基于栅格地图的机器人路径规划算法指南 黎万洪 后写的笔记 x
  • 最短路经算法简介(Dijkstra算法,A*算法,D*算法)

    转自 http www embhelp com drew algorithm shortpath htm 作者 Drew 据 Drew 所知最短路经算法现在重要的应用有计算机网络路由算法 机器人探路 交通路线导航 人工智能 游戏设计等等 美
  • 【路径规划】(1) Dijkstra 算法求解最短路,附python完整代码

    好久不见 我又回来了 这段时间把路径规划的一系列算法整理一下 感兴趣的点个关注 今天介绍一下机器人路径规划算法中最基础的 Dijkstra 算法 文末有 python 完整代码 那我们开始吧 1 算法介绍 1959 年 荷兰计算机科学家 E
  • 图论:Dijkstra算法——最详细的分析,图文并茂,一次看懂!

    文章目录 1 Dijkstra算法简介 2 算法实现范例 3 邻接矩阵 4 Dijkstra 算法的 C 描述 5 Dijkstra 算法的 Matlab 描述 6 温故知新 1 Dijkstra算法简介 背景 迪杰斯特拉算法 Dijkst
  • Dijkstra 负权重算法

    好吧 首先我知道 Dijkstra 不适用于负权重 我们可以使用 Bellman ford 代替它 但在我遇到的一个问题中 它指出所有边的权重都从 0 到 1 不包括 0 和 1 而路径的成本实际上就是产品 所以我的想法就是只取日志 现在所
  • 使用 Dijkstra 算法寻找最短路径

    我需要找到图的两个顶点之间的最短路线 我有一个矩阵 其中包含所有权重 我该怎么做 目前 我有以下代码 private int Dijkstra int start int end bool done new bool 8 int paren
  • Dijkstra 算法的复杂性

    我从许多来源了解到 如果使用简单的方法来获取最小元素 线性搜索 Dijkstra 的最短路径也将以 O V 2 复杂度运行 但是 如果使用优先级队列 则可以优化为 O VLogV 因为该数据结构将在 O 1 时间内返回 min 元素 但在删
  • CUDA dijkstra 算法 [关闭]

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

    假设我们在一组顶点上有两个有向正权图 第一个图代表铁路 第二个图代表公交车道 顶点是公交车站或火车站或两者 我们需要找到从 A 到 B 的最短路径 但我们不能改变交通工具类型超过 N 次 我试图修改 Dijkstra 算法 但它只适用于一些
  • Java:使用 Fibonacci 堆实现 Dijkstra 算法

    新来的 但已经作为客人潜伏了一段时间了 好的 所以我一直在尝试使用 Fibonacci 堆 在 Java 中 执行 Dijkstra 的最短路径算法 经过一番搜索 我偶然发现了两个代表斐波那契堆的现成实现 第一个实现做得相当漂亮 可以找到h
  • 带优先级队列的 Dijkstra 算法

    在我的 Dijkstra 算法的实现中 我有 1 个包含所有节点的数组和 1 个包含所有节点的优先级队列 每当一个节点出队时 我都会用新的距离和它的来源更新所有相邻节点 这样我就可以回溯路径 优先级队列中的节点将更新为新距离 数组中的节点将
  • 如何在 QuickGraph Dijkstra 或 A* 中设置目标顶点

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

    寻求一种能够产生 N 条短路径的算法 有没有人有算法的经验来寻找多条短路径在有向图中 我的应用程序用于语言 查找同义词链 但从逻辑上讲 这可能用于地理或社交网络 我想要明显不同的路径 而不仅仅是沿途交换几个节点 我真的很想知道是否有办法避免
  • 实施 Dijkstra 算法

    我的任务是 大学课程 实施某种形式的寻路 现在 在规范中 我可以实现强力 因为要搜索的节点数量有限制 开始 中间两个 结束 但我想重新使用此代码并来实现迪杰斯特拉算法 http en wikipedia org wiki Dijkstra
  • 原始地理坐标和图形节点之间的最短路径

    我已经实现了一个简单的 Dijkstra 算法 用于使用 Java 查找 osm 地图上的最短路径 从 osm 文件创建的图形中的寻路效果非常好 但是 如果用户的当前位置和 或目的地不是该图的节点 只是原始坐标 我们如何将这些坐标 链接 到
  • 为什么使用 Dijkstra 算法而不是最佳(最便宜)优先搜索?

    从我到目前为止所读到的来看 这最佳优先搜索 https en wikipedia org wiki Best first search在找到到达目标的最短路径方面似乎更快 因为 Dijkstra 算法在遍历图时必须放松所有节点 是什么让 D
  • Dijkstra算法的时间复杂度是多少

    Dijkstra V E S O 1 for each vertex v V O V d v O 1 d source 0 O 1 while S V O V v non visited vertex with the smallest d
  • java有索引的最小优先级队列吗?

    我需要它来实现 Dijkstra 算法 并且我确实有自己的实现 但是使用 java 自己的类记录我的代码会更容易 不 Java标准库没有这样的数据结构 我想大多数人都用这个 http algs4 cs princeton edu 24pq

随机推荐

  • Android自定义View实现图片裁剪功能(本地选择图片进行裁剪)

    使用安卓自带的裁剪工具 发现有版本兼容问题 而且图片模糊问题也不好解决 于是自己动手绘制一个裁剪工具 先看效果 最终效果 自定义截图 实现思路 打开本地相册 获得图片Uri Uri转为Bitmap 用自定义View绘制可拖动选框 获得用户的
  • PhotonServer游戏服务器学习一

    步骤一 1 PhotonServe的官方网站https www photonengine com zh CN Photon 进入到官网后点击SDKs 选择Server 工程 点击SeverSDK ON PREMISES进行下载 需要注册一个
  • JDBC连接Access数据库的几种方式介绍

    接下来总结一下常用的几种连接方式 例如有如下的Access数据库student 表basic 以及6条记录 现在通过几种方式在Jsp中将他们的数据显示出来 如图所示 对于几种连接Access数据库的方式 基本上都是基于JDBC ODBC方式
  • 关于pytorch、torch_geometric安装 22.12.25

    系统坏了 重装系统 一开始以为电脑只能装cuda9 2版本一下 装了之后 显卡驱动自动更新了 然后显示可以装CUDA11 7版本一下 cuda 9 2 torch geometric 1 61 pytorch 1 6 0 python3 8
  • Linux 根目录爆掉,怎么办?

    极力推荐文章 欢迎收藏Android 干货分享 本篇文章主要介绍 Linux 开发中的部分知识点 通过阅读本篇文章 您将收获以下内容 一 cannot create temp file for here document No space
  • WebStorm 2023 下载、安装、汉化

    1 下载WebStorm 1 1 官网下载地址 https www jetbrains com webstorm https www jetbrains com webstorm download download thanks html
  • 问题解决:DatabaseMetaData.getTables()方法,返回了所有库中的表

    一 问题描述 DatabaseMetaData getTables 方法常常用来获取数据库中的所有表信息 但我想要获取我的本地数据库db test中的表信息 出现了错误 try Connection conn DBManager getCo
  • BigDecimal保留小数

    Java中BigDecimal取整方法 BigDecimal bd new BigDecimal 12 1 long l bd setScale 0 BigDecimal ROUND UP longValue 向上取整 long l bd
  • 【Docker存储】Docker容器的数据持久化

    Docker存储 Docker容器的数据持久化 一 Docker数据持久化方式 二 本次实践介绍 2 1 本次实践简介 2 2 本次实践环境介绍 三 容器的挂载目录 3 1 创建测试容器web01 3 2 查看容器信息 3 3 编辑测试文件
  • 单片机C语言中while(1)的问题

    单片机C语言的主程序 通常要用一个while 1 语句来让程序进入一个无限循环 目的是为了让程序一直保持在我们需要运行的情况下 虽然这种做法毋庸置疑 在网上还是有不少朋友有疑问 如果程序不加while 1 会出现什么情况 对于这种好学精神
  • Android开发——相册的访问、上传以及服务端对接

    相册的访问与图片保存 1 访问相册并上传到服务器 2 下载网络图片到相册 3 这里顺便分享一手后端的对接方法 4 生产环境资源配置 5 后端项目打包 一般Android开发需要涉及到本地相册的上传以及文件下载到相册 1 访问相册并上传到服务
  • redis必杀命令:发布订阅

    Redis 发布订阅 pub sub 是一种消息通信模式 发送者 pub 发送消息 订阅者 sub 接收消息 Redis 客户端可以订阅任意数量的频道 下图展示了频道 channel1 以及订阅这个频道的三个客户端 client2 clie
  • Spotify 一款不错的音乐工具

    Spotify简介 在这个时代 似乎听歌已经成了我们生活中不可缺少的一部分 生活中或多或少的我们都能接触到的 但每个人喜欢的风格是不一样的 又或者我们喜欢的歌曲可能因为种种的原因而听不见 那么下面这款工具就基本上能满足我们对歌曲的渴望 在这
  • 使用两个队列实现一个栈【数据结构】

    使用两个队列实现一个栈 StackByQueue h typedef int SQDataType typedef struct StackByQueue Queue q1 Queue q2 StackByQueue void InitSt
  • 多核编程与单核多线程编程

    并发 时间段内有很多的线程或进程在执行 但何时间点上都只有一个在执行 多个线程或进程争抢时间片轮流执行 并行 时间段和时间点上都有多个线程或进程在执行 单核cpu的话只能是并发 多核cpu才能做到并行执行 那有人可能有这样的疑问 那多进程的
  • Java Encoding

    现象 Java程序在Windows命令行编译运行打印中文时 直接在命令行下编译会报错 gbk编码的不可映射字符 Eclipse不存在该问题 分析 显然是几种编码格式不兼容 但要搞清楚源文件的编码方式 编译生成的class文件编码方式并且确保
  • Mac必备的矢量图处理软件:ai2021中文版

    备受期待的Adobe Illustrator 2021 for Mac终于来啦 这是全球最著名的矢量图形软件 这次的Illustrator2021中文版提升了软件的性 能 缩短了Illustrator 2021的启动时间并加快了文件打开速度
  • 【深度学习】深入浅出详解张量自动求导机制

    转载自 PaperWeekly 作者 清川 单位 上海交通大学博士生 研究方向 联邦学习 端云协同推断 1 写在前面 深入浅出 在计算机教材界被用滥的词 总是继承着领域小白的初心和梦想 顾名思义 它既意味着理解得透彻 又要求复述得通俗 如果
  • 软件测试人员在工作中如何运用Linux

    从事过软件测试的小伙们就会明白会使用Linux是多么重要的一件事 工作时需要用到 面试时会被问到 简历中需要写到 对于软件测试人员来说 不需要你多么熟练使用Linux所有命令 也不需要你对Linux系统完全了解 你只需要学会一些常用的基本命
  • 迪杰斯特拉(Dijkstra)算法

    一 算法介绍 迪杰斯特拉算法是由荷兰计算机科学家在1956年发现的算法 此算法使用类似广度优先搜索的方法解决了带权图的单源最短路径问题 它是一个贪心算法 二 核心思想 1 选定一个点 这个点满足两个条件 1 未被选过 2 距离最短 2 对于