Dijkstra算法和Floyd算法对比分析

2023-10-31

转载:http://blog.csdn.net/liuyanling_cs/article/details/56330652 

首先,Dijkstra算法与Floyd算法都是广度优先搜索的算法。都可以用来求单源点到其他所有点的最短路径。那么这两者的原理分别是怎样?彼此又有什么区别呢?

求此有向图中起点1到其他所有点的最短距离

在本文中,我们以一个小小的包含3个节点的有向图和邻接矩阵Graph来进行说明。

Graph[3][3] = {0,5,6
                1000,0,1000
                1000,-2,0}
  • 1
  • 2
  • 3
  • 1
  • 2
  • 3

一个简单的有向图

Dijskra算法

采用Dijkstra算法,需要有一个源点集合u,一个参考点集合v,以及一个滚动dist数组,用于存储S点到达其他所有点的最短路径。 
如果需要记录最短路线,还需要配置一个pre数组,用来存储当前最短路径下Index序号的点的前驱节点。 
初始化时,u中只有源点s,其他点都在v中,dist数组是s到其他所有点的直接距离,若没有边连接则为无穷大(本例中1000表示无穷大)。

初始化状态:u={1},v={2,3},dist[]={0,5,6},pre[]={1,1,1},flag={0,1,1}

算法开始,遍历dist查找最小值,将该最小值对应的点添加到u中,并从v中删除。一种实现方式是采用flag数组,0表示在u中,1表示在v中。

中间状态1:u={1,2},v={3},dist[]={0,5,6},pre[]={1,1,1},flag={0,0,1}

接着需要更新dist数组,判断从起始点1到v中的点之间的路径上插入新加入的点2,路径是否能变得更短,也就是比较dist[j]和Graph[1][2]+dist[2],然后使用较小值更新dist[j],若dist[j]被更新,则将pre[j]修改为2.

中间状态2:u={1,2},v={3},dist[]={0,5,6},pre[]={1,1,1},flag={0,0,1}

然后循环上述步骤,判断在v中且dist最小的点,然后加入到u中。

中间状态3: u={1,2,3},v={},dist[]={0,5,6},pre[]={1,1,1},flag={0,0,0}

此时发现v中已没有点,则结果被输出。

很显然,这个结果是不对的,从1到2的最短路径应该是1->3->2,长度为4. 而不是1->2,长度为5

这是因为按照Dijkstra的算法逻辑,是不能计算负权图的。 
Dijkstra算法本质上是贪心算法,下一条路径都是由当前更短的路径派生出来的更长的路径。不存在回溯的过程。 
如果权值存在负数,那么被派生出来的可能是更短的路径,这就需要过程可以回溯,之前的路径需要被更短的路径替换掉,而Dijkstra算法是不能回溯的。它每一步都是以当前最优选择为前提的。

Floyd算法

那么,Floyd算法会怎么做呢?Floyd算法实际上是一个动态规划算法。 
每一个点对u和v之间的最短路径,可能会经过N个点,这些中间点记为k。 
假定u到k之间的最短路径已经找好,k到v之间的最短路径已经找好,那么求u到v之间的最短路径,就是遍历各个可能的k点,然后求(u,k)+(k,v)之间的最小值。 
所以这实际上将大规模的问题自顶向下划分为了小规模的问题,这就是动态规划思想。

那么算法的步骤是怎样的呢? 
需要使用三层循环:

for(u){
       for(v){
               for(k)}}
  • 1
  • 2
  • 3
  • 1
  • 2
  • 3

若graph[u][k]+graph[k][v] < graph[u][v],则更新graph[u][v]。并记录以当前u为起点的情况下此点的前驱。 
当三层遍历完毕之后,所有点对之间的最短路径长度和路径就能求出来了。当然,如果只需要求某个点到其他所有点的最短距离,那么固定u,也就是说只用两层遍历就可以做到了。 
最后的矩阵为

{0,4,6
1000,0,1000
998,-2,0}
  • 1
  • 2
  • 3
  • 1
  • 2
  • 3

可以看到,求得的最短路径及其长度均是正确的。 
这是因为动态规划是可以回溯的,会遍历到从1到3再从3到2的路径。

总结

上述算法均为两种经典算法的最简单形式,没有任何优化。比如Floyd可以从空间复杂度上进行优化,Dijkstra在选择v中dist最小值时可以使用堆排序等。

本文意在引出一个关于贪心算法和动态规划算法之间区别与联系的论述。(出自邹博老师) 
考虑一阶马尔科夫模型,状态N仅仅可以从状态N-1得到,就像有限状态自动机,这就是正确使用贪心算法的前提。 
考虑高阶马尔科夫模型,状态N可能需要前面的状态N-1,N-2,N-3等等一起联合才能得到。这就是正确使用动态规划的前提。 
所以一定能用贪心算法解的问题肯定可以由动态规划解。但是可以用动态规划来解的问题,不一定能用贪心算法来解。

使用马尔科夫模型来类比动态规划思想的这个观点还有很多启发思维的地方。 
比如说在构建状态转移方程时,经常因为使用的状态不对,而列不出最终的状态转移方程。 

简单的状态转移方程,只需要考虑一个状态x的变化,而复杂的状态转移方程可能需要考虑x、y或者更多的状态迁移。那么如何找准这些影响最终结果的状态,并找准状态和结果之间的对应关系,是列好状态转移方程的一个重点。



https://blog.csdn.net/qq_17368865/article/details/79062348




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

Dijkstra算法和Floyd算法对比分析 的相关文章

  • Codility 钉板

    尝试了解 Codility NailingPlanks 的解决方案 问题链接 https app codility com programmers lessons 14 binary search algorithm nailing pla
  • 删除队列中的最后一个元素

    我需要删除队列的最后一个元素 我唯一可以使用的操作是 Peek 获取第一个元素而不删除它 Enqueue element 向队列末尾插入一个元素 Dequeue 删除第一个元素 IsEmpty true 或 false 队列是否为空 而且我
  • 如何将无向图转换为 DAG?

    The 维基页面 http en wikipedia org wiki Directed acyclic graph Relation to other kinds of graphs says 任何无向图都可以通过为其顶点选择总顺序并将每
  • 高维最近邻搜索的最佳数据结构

    我实际上正在处理高维数据 50 000 100 000 个特征 并且必须对其执行最近邻搜索 我知道随着维度的增长 KD 树的性能很差 而且我还了解到 一般来说 所有空间分区数据结构都倾向于对高维数据执行详尽的搜索 此外 还有两个重要事实需要
  • 解释一下从 N 个给定集合中的每一个中给出第 K 个最大数字的示例?

    今天我尝试解决一个Facebook 编程挑战赛 https facebook interviewstreet com recruit challenges 我遇到的挑战是 酒吧问题 可以找到here https github com alo
  • 寻找将集合映射到整数的双射函数

    对于任意两个序列 a b 其中 a a1 a2 an 且 b b1 b2 bn 0a b具有相同的元素 而不关心它们的顺序 例如 如果 a 1 1 2 3 b 2 1 3 1 c 3 2 1 3 则 f a f b f a f b 我知道有
  • 由周期表元素形成的最大单词的算法

    我想为以下问题场景编写一个算法 根据元素周期表元素的名称 找到可以组成的最大单词 符号如Na Ne等应被视为单个元素 这是在一家知名公司的求职面试中被问到的 有人可以帮我解决这个问题吗 我认为更好的方法是检查字典中的每个单词 看看是否可以从
  • 将字符串中的“奇怪”字符转换为罗马字符

    我需要能够将用户输入仅转换为 a z 罗马字符 不区分大小写 所以 我感兴趣的角色只有26个 然而 用户可以输入他们想要的任何 形式 的字符 西班牙语 n 法语 e 和德语 u 都可以包含用户输入中的重音符号 这些重音符号会被程序删除 我已
  • 数组中连续元素的最大乘积

    我在现场面试的时候被问到了这个算法问题 由于没有要求我签署保密协议 我将其发布在这里寻求答案 给定一个数组REAL不包含 0 的数字 找到产生最大乘积的连续元素 该算法应在线性时间内运行 我考虑过以下方法 使用两个数组 第一个是利用DP思想
  • 如何仅使用单个数组在 JavaScript 中模拟调用堆栈

    我正在看维基百科页面 https en wikipedia org wiki Call stack在调用堆栈上 并尝试理解这个图像 据我所知 哈哈 const memory memory 0 3 top of stack pointer m
  • 7 张牌扑克手牌评估器

    有谁知道评估 7 张牌扑克牌的快速算法吗 这比简单地暴力检查 7 张牌中每 21 个 5 张牌的组合更有效 Cheers Pete 我写了一篇JavaScript 核心评估方法仅使用位操作 因此速度非常快 考虑到这一点 查看 21 种组合还
  • 用 C++ 生成 AST

    我正在用 C 制作一个解释器 到目前为止我已经有了词法分析器来生成标记 问题是我不确定如何生成 行走 解析树 我正在考虑使用数组数组来制作解析树 但我不确定如何以正确的顺序将标记实际插入到解析树中 我不确定是自上而下 左右还是自下而上 左右
  • 计算两点之间的最短路线

    过去几周我一直在开发一款多人 HTML5 游戏 使用nodejs and websockets 我已经被这个问题困扰了一段时间 想象一下 我用数组实现了这个平铺地图 如下所示 1 or 棕色瓷砖 路上有障碍物 玩家无法通过 0 or 绿色瓷
  • 找到一条穿过任意节点序列的最短路径?

    In 这个先前的问题 https stackoverflow com questions 7314333 find shortest path from vertex u to v passing through a vertex wOP询
  • 需要一种将网络块范围折叠为超集范围列表的算法

    我的数学不及格 我需要一种有效的方法将网络范围缩小为超集 例如如果我输入 IP 范围列表 1 1 1 1至2 2 2 5 1 1 1 2至2 2 2 4 10 5 5 5至155 5 5 5 10 5 5 6至10 5 5 7 我想返回以下
  • 以 O(1) 计算汉明权重 [重复]

    这个问题在这里已经有答案了 在二进制表示中 汉明权重是 1 的数量 我偶然发现了网络并找到了一个 O 1 的答案 v v v gt gt 1 0x55555555 v v 0x33333333 v gt gt 2 0x33333333 in
  • 数量重新分配逻辑 - 具有外部数据集的 MapGroups

    我正在研究一种复杂的逻辑 需要将数量从一个数据集重新分配到另一个数据集 在例子中我们有Owner and Invoice 我们需要从数量中减去Invoice准确地Owner匹配 在给定汽车的给定邮政编码处 减去的数量需要重新分配回同一辆车出
  • 从 1 到 20 亿,像 (23,29) 这样相差 6 的连续素数对的数量

    如何在考虑时间复杂度的情况下从 1 到 20 亿 使用任何编程语言且不使用任何外部库 找到像 23 29 这样相差 6 的连续素数对的数量 尝试过埃拉托色尼筛 但获得连续素数是一个挑战 使用了生成器 但时间复杂度非常高 代码是 def ge
  • 将名称字符串编码为唯一的数字

    我有一大堆名字 数以百万计 他们每个人都有一个名字 一个可选的中间名和一个姓氏 我需要将这些名称编码为唯一代表这些名称的数字 编码应该是一对一的 即一个名称只能与一个数字相关联 一个数字只能与一个名称相关联 对此进行编码的明智方法是什么 我
  • 生产代码中的 LRU 实现

    我有一些 C 代码 需要使用 LRU 技术实现缓存替换 目前我知道两种实现LRU缓存替换的方法 每次访问缓存数据时使用时间戳 最后比较替换时的时间戳 使用缓存项的堆栈 如果最近访问过它们 则将它们移动到顶部 因此最后底部将包含 LRU 候选

随机推荐

  • tensorflow 移植到android平台

    我的书 淘宝购买链接 当当购买链接 京东购买链接 本文基于 https github com MindorksOpenSource AndroidTensorFlowMachineLearningExample 下载和安装jdk ndk和s
  • shell脚本根据端口杀死进程(带完整解析)

    各位可以将下述内容当为学习Shell脚本 如果只是想要更方便地根据端口杀死进程 可以直接使用该方法 port是端口 kill 9 lsof ti port 在项目开发的时候 我们经常需要根据相对应的端口来杀死进程 而这样的操作最少需要两步
  • 直流无刷减速电机PID控制

    最近做了直流无刷减速电机的控制的项目 针对项目中遇到的问题做下总结 PID Control PID 代码 速度环 位置环 串级 STM32F407VET6 STM32CubeMX 更新记录 V1 0 0 2022 8 5 完善了RTOS程序
  • 怎么使用大疆无人机建模?

    倾斜摄影测量技术是国际测绘遥感领域近年发展起来的一项高新技术 以大范围 高精度 高清晰的方式全面感知复杂场景 通过高效的数据采集设备及专业的数据处理流程生成的数据成果直观反映地物的外观 位置 高度等属性 为真实效果和测绘级精度提供保证 同时
  • 说说学习python pycharm中踩的坑

    说说学习python pycharm中踩的坑 我真的很讨厌很痛苦这种啥都不懂 只能在黑暗中摸索的感觉 1 python 3 9 及以上版本是不支持win7的 2 要安装 python 2 7 和 python 3 8 这样才能在pychar
  • 反射、xml解析

    反射 反射就读取class文件 获取该文件中的属性 方法等 作用 用来获取指定路径下的class文件中所具备的的所有属性和方法 返回Class对象的方式之一 getClass 每一个引用数据类型都有一个getClass的方法 返回的是该类的
  • EXCEL的快速分列

    1 打开Excel并选择分列 选择智能分列 点击 2 选择手动设置分列 3 注意符号一定是英文要和你分列的数据内符号一致 4 点击下一步完成 效果如下
  • 数据链路层三个基本问题(封装成帧 、透明传输和差错检测 )

    文章目录 使用点对点信道的数据链路层 1 1 数据链路和帧 1 2 三个基本问题 1 封装成帧 2 透明传输 3 差错检测 循环冗余检验CRC 帧检验序列 FCS 接收端对收到的每一帧进行 CRC 检验 数据链路层使用的信道主要有以下两种类
  • linux suse设置中文系统

    Linux字符编码默认为UTF 8 如出现乱码可设置为GBK 1 手动更改profile文件的命令 vi etc profile 2 在文件的末尾添加以下两行命令 export LC ALL zh CN GBK export LANG zh
  • Happiness【2019EC Final G题】【模拟】

    题目链接 题意很长 先翻译一下 由N个参赛队伍 给出其余N 1只参赛队伍 另外一支队伍是我们 本次ICPC一共有10道题 我们知道其余N支队伍每道题的通过时间和错误次数 如果是 则为没有在300分钟内解决该问题 最后给出我们队伍 做出每道题
  • 窨井液位计(下水道液位计)的分类

    窨井液位计又称下水道液位计 是应用在市政管网监测集水井 雨水井 污水井 观察井等测量水位变化的仪表 根据原理不同可分为 压力式 雷达式和超声波式3种 通过传感器测量液位数值 利用无线远传的方式上传到数据平台 实现对井下水位实时监测的目的 压
  • yapi的安装

    Yapi的安装 Yapi是一款不错的接口管理软件 我主要用它来进行接口Mock Yapi安装所需环境 Node js 7 6 Mongodb 2 6 git 各环境安装地址 git https git scm com downloads N
  • F.softmax()的用法

    F softmax 的用法 gt gt gt import torch gt gt gt import torch nn functional as F gt gt gt logits torch rand 2 2 gt gt gt pre
  • C++函数返回引用

    注 C 有三种传递方式 值传递 指针传递 引用传递 返回 值 和返回 引用 是不同的 函数返回值时会产生一个临时变量作为函数返回值的副本 而返回引用时不会产生值的副本 既然是引用 那引用谁呢 这个问题必须清楚 否则将无法理解返回引用到底是个
  • Spring Cloud Nacos源码讲解(五)- Nacos服务端健康检查

    Nacos服务端健康检查 长连接 概念 长连接 指在一个连接上可以连续发送多个数据包 在连接保持期间 如果没有数据包发送 需要双方发链路检测包 注册中心客户端2 0之后使用gRPC代替http 会与服务端建立长连接 但仍然保留了对旧http
  • The Black Tux

    The Black Tux IT桔子 The Black Tux IT桔子 The Black Tux theblacktux com posted on 2014 07 27 17 34 lexus 阅读 评论 编辑 收藏 转载于 htt
  • 从coco数据集中提取需要的类别

    进行目标检测时 有时只需要训练数据集中的部分图像 以 coco128 为例 只选出其中的车辆类 bicycle car motorcycle bus truck coco128 数据集中的标签为 txt 文件 每一个图像由若干行 每一行对应
  • 转载之remosaic

    一 Quadra CFA 介绍 Quadra CFA Quadra Color Filter array 功能提高了在弱光条件下的性能和信噪比 此功能在弱光条件下提供明亮和清晰的图像 在正常光照条件下提供高分辨率图像 Quadra CFA有
  • HTTPWeb服务器---HTTP整体设计框架

    整个项目采用B S模式 浏览器 服务器模式 通过浏览器发送的method 只要包含GET和POST两种方法 server对此进行响应 最终通过html显示所得到的结果 因为服务器同时处理多条连接 因此采用了多线程的结构 HTTP是在TCP之
  • Dijkstra算法和Floyd算法对比分析

    转载 http blog csdn net liuyanling cs article details 56330652 首先 Dijkstra算法与Floyd算法都是广度优先搜索的算法 都可以用来求单源点到其他所有点的最短路径 那么这两者