数据结构与算法之Floyd弗洛伊德算法求最短路径

目录

前言

Floyd弗洛伊德算法

定义

步骤

一、初始化

二、添加中间点

三、迭代

四、得出结果

时间复杂度

代码实现

结束语


前言

今天是坚持写博客的第18天,希望可以继续坚持在写博客的路上走下去。我们今天来看看数据结构与算法当中的弗洛伊德算法。


Floyd弗洛伊德算法

定义

Floyd弗洛伊德算法是一种用于在加权图中找到所有顶点对之间的最短路径的算法。这个算法可以处理带有正权、负权甚至零权(但不存在负权环路)的图。

对于了解Floyd弗洛伊德算法,我们需要先了解几个前置概念:

  1. 加权图:图中的每条边都有一个与之关联的权值
  2. 最短路径:从一个顶点到另一个顶点的总权值最小的路径
  3. 负权环路:一个环路(即一条起点和终点相同的路径),其所有边的权值之和为负。如果存在负权环路,则最短路径问题可能没有解,因为可以通过无限次地遍历这个环路来不断减小路径的总权值。

步骤

假设我们有如下的图:

其中A到B的权值为2,A到C的权值为6,A到D的权值为5,B到C的权值为1,B到D的权值为4,C到D的权值为3。我们可以先得出他的邻接矩阵:

为什么对角线上的值都是零?因为对角线上的路径都是一个环路,图上没有自己指向自己的环路,因此都是0

下面进入正题,如何使用弗洛伊德算法呢?

一、初始化

首先,为图中所有顶点对(i, j)之间设置一个距离矩阵D,其中D[i][j]表示从顶点i到顶点j的当前已知最短距离。如果两个顶点之间没有直接相连的边,则设置D[i][j]为一个很大的数(通常是一个无穷大的值,表示为∞)。如果两个顶点之间有直接相连的边,则设置D[i][j]为该边的权值。另外,设置一个中间矩阵P,用于记录最短路径的信息

二、添加中间点

  1. 对于图中的每一个顶点k(作为中间点),遍历所有顶点对(i, j)(其中i和j是图中的顶点且i ≠ j,i ≠ k,j ≠ k)。
  2. 如果从i到k再到j的路径比已知的i到j的路径更短(即dist[i][k] + dist[k][j] < dist[i][j]),则更新dist[i][j]为dist[i][k] + dist[k][j]。

三、迭代

重复步骤二,对于图中的每一个顶点k都执行一次。由于图中总共有n个顶点,因此这个步骤需要执行n次迭代。

四、得出结果

在完成所有迭代后,dist矩阵将包含图中所有顶点对之间的最短路径长度。如果dist[i][j]的值仍然是无穷大,则表示从顶点i到顶点j没有路径


时间复杂度

Floyd算法的时间复杂度为O(n^3),其中n是图中顶点的数量。这是因为算法需要进行n次迭代,每次迭代都需要检查所有n^2个顶点对。 


代码实现

下面是大家期待的代码实现,今天我们用python实现

import numpy as np  
  
def floyd_warshall(graph):  
  
    n = len(graph)  
    # 复制邻接矩阵作为距离矩阵  
    dist = np.copy(graph)  
  
    # 遍历所有顶点作为中间点  
    for k in range(n):  
        # 遍历所有顶点对 (i, j)  
        for i in range(n):  
            for j in range(n):  
                # 如果通过顶点 k 可以找到更短的路径  
                if dist[i][k] + dist[k][j] < dist[i][j]:  
                    dist[i][j] = dist[i][k] + dist[k][j]  
  
    return dist  
  
# 示例图(邻接矩阵)  
graph = np.array([  
    [0, 5, float('inf'), 10],  
    [float('inf'), 0, 3, float('inf')],  
    [float('inf'), float('inf'), 0, 1],  
    [float('inf'), float('inf'), float('inf'), 0]  
])  
  
# 调用 Floyd-Warshall 算法  
distances = floyd_warshall(graph)  
  
# 打印结果  
print("Shortest distances between all pairs of vertices:")  
print(distances)

结束语

以上就是今天对弗洛伊德算法求解最短路径的解释,希望对大家有所帮助,如果对您有帮助,希望您可以留下一个点赞、关注和收藏,这对我很重要,谢谢!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/679897.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

如何学习SQL?YouTube近百万粉丝技术频道的学习路径图。

大家好&#xff0c;我是王有志&#xff0c;一个分享硬核 Java 技术的金融摸鱼侠&#xff0c;欢迎大家加入 Java 人自己的交流群“共同富裕的 Java 人”。 ByteByteGo 频道在 5 月 30 日的通信邮件中提到了“How to Learn SQL”这一主题&#xff0c;并给出了一张详细的学习路径…

python——网络编程

流程图 面向连接的套接字 面向连接的通信提供序列化的、可靠的和不重复的数据交付&#xff0c;而没有记录边界。主要的协议是传输控制协议&#xff08;TCP&#xff09;; TCP套接字&#xff0c;在python中&#xff0c;必须使用SOCK_STREAM作为套接字类型 tcp的特点 面向连接…

使用GitHub托管静态网页

前言​&#xff1a; 如果没有服务器&#xff0c;也没有域名&#xff0c;又想部署静态网页的同学&#xff0c;那就可以尝试使用GitHub托管自己的网页​。 正文&#xff1a; 首先要有自己的GitHub的账号&#xff0c;如果没有可以自己搜索官网进行注册登录&#xff0c;国内对Gi…

深入了解 C 语言 Bug

目录 一、引言二、Bug的定义三、Bug的由来四、Bug的影响五、应对 Bug 的方法六、结论 一、引言 1、在 C 语言的编程世界中&#xff0c;Bug 是一个我们无法回避的话题。 2、Bug&#xff0c;简单来说&#xff0c;就是程序中存在的错误或缺陷。它可以表现为程序运行结果的异常、崩…

容器运行nslookup提示bash: nslookup: command not found【笔记】

在容器中提示bash: nslookup: command not found&#xff0c;表示容器中没有安装nslookup命令。 可以通过以下命令安装nslookup&#xff1a; 对于基于Debian/Ubuntu的容器&#xff0c;使用以下命令&#xff1a; apt-get update apt-get install -y dnsutils对于基于CentOS/R…

机器学习、深度学习模型建模开发过程中常见的评估指标汇总学习记录

在机器学习、深度学习模型的开发过程中&#xff0c; 很重要的一个环节就是要对模型的性能进行评估分析&#xff0c;不同类型的任务不同的模型对应使用不同的评估指标体系&#xff0c;本文的主要目的是正好趁着最近有这块的需求&#xff0c;就想着找点时间把汇总学习的内容整理记…

TypeScript学习(一):开发环境搭建

官方文档搭建参考 https://learn.microsoft.com/zh-cn/training/modules/typescript-get-started/ 1.下载node.js https://nodejs.org/en/download 2.下载vscode https://code.visualstudio.com/ 3.在线ts的测试工具 https://www.typescriptlang.org/play/ 4.下载typescr…

Linux线程安全:线程互斥

一、线程互斥的概念 1.1临界资源与互斥的关系 临界资源&#xff1a;多线程执行流共享的资源就叫做临界资源。 临界区&#xff1a;每个线程内部&#xff0c;访问临界资源的代码&#xff0c;就叫做临界区。 互斥&#xff1a;任何时刻&#xff0c;互斥保证有且只有一个执行流进入…

274 基于matlab的随机粗糙表面对微气体轴承内气体压强分布的影响

基于matlab的随机粗糙表面对微气体轴承内气体压强分布的影响。采用差分法求解气体轴承的雷诺方程&#xff0c;通过尺寸参数、分形维数对粗糙度表面设置&#xff0c;滑流参数设置&#xff0c;实现气压分布可视化结果显示。程序已调通&#xff0c;可直接运行。 274 气体轴承 随机…

软件设计,建模及需求分析

文章目录 设计原则建模及需求分析重构 设计原则 SOLID原则 单一职责 开闭 &#xff08;扩展开放&#xff0c;修改关闭&#xff09; 里氏替换 &#xff08;父类出现地方都可以用子类替换&#xff09; 接口隔离 依赖倒置&#xff08;高层模块不依赖低层&#xff0c;两层都依…

[数据集][图像分类]茶叶叶子病害分类数据集304张4类别

数据集类型&#xff1a;图像分类用&#xff0c;不可用于目标检测无标注文件 数据集格式&#xff1a;仅仅包含jpg图片&#xff0c;每个类别文件夹下面存放着对应图片 图片数量(jpg文件个数)&#xff1a;304 分类类别数&#xff1a;4 类别名称:[“anthracnose”,“bird_eye_spot”…

三维模型轻量化工具:手工模型、BIM、倾斜摄影等皆可用!

老子云是全球领先的数字孪生引擎技术及服务提供商&#xff0c;它专注于让一切3D模型在全网多端轻量化处理与展示&#xff0c;为行业数字化转型升级与数字孪生应用提供成套的3D可视化技术、产品与服务。 老子云是全球领先的数字孪生引擎技术及服务提供商&#xff0c;它专注于让…

端口映射如何检测?

端口映射是一种网络通信技术&#xff0c;它允许将公网IP地址的特定端口指向内部局域网中的特定设备或应用程序。通过端口映射&#xff0c;可以实现远程访问内部设备&#xff0c;解决了网络环境限制的问题。 在进行端口映射之前&#xff0c;需要进行端口映射检测&#xff0c;以确…

JS:setTimeout计时器优化

setTimeout会因为浏览器的事件循环机制导致计时器的误差&#xff0c;JS代码越复杂、越多&#xff0c;误差越大。 通过使用performance.now()可以一定程度上减小这个误差值。 performance.now()返回的是一个浮点数&#xff0c;表示从页面加载到现在的毫秒数&#xff0c;精度可…

动态数组的实现(仿写ArrayList)

动态数组是什么 之前写过一篇数组和静态数组的介绍&#xff1a;数组的定义和特点&#xff0c;静态数组CURD的实现 我们在静态数组的基础上&#xff0c;增加一些比较方便的功能&#xff0c;比如自动扩容&#xff0c;获取数组长度等&#xff0c;这样的数组叫动态数组 动态数组…

浅析Vue3基础知识(vue3笔记之入门篇)

本文是结合实践中和学习技术文章总结出来的笔记(个人使用),如有雷同纯属正常((✿◠‿◠)) 喜欢的话点个赞,谢谢! 时下Vue框架都是使用Vue3版本来开发项目了,为了加深对Vue3基本知识的了解,特写了这个笔记 1. 生命周期 1.1. vue3生命周期 一个组件从开始到结束,正常的生命周…

【免费】2021年数学建模国赛C题问题一--基于熵权法和TOPSIS法详细版附Word加代码

各位大佬好 &#xff0c;这里是阿川的博客&#xff0c;祝您变得更强 个人主页&#xff1a;在线OJ的阿川 大佬的支持和鼓励&#xff0c;将是我成长路上最大的动力 阿川水平有限&#xff0c;如有错误&#xff0c;欢迎大佬指正 Python 初阶 Python–语言基础与由来介绍 Python–…

EXCEL多sheet添加目录跳转

EXCEL多sheet添加目录跳转 背景 excel中有几十个sheet&#xff0c;点下方左右切换sheet太耗时&#xff0c;希望可以有根据sheet名超链接跳转相应sheet&#xff0c;处理完后再跳回原sheet。 方案一 新建目录sheet&#xff0c;在A1写sheet名&#xff0c;右键选择最下方超链接…

I.MX RT1170之MIPI CSI摄像头初始化和显示流程详解

在上一篇文章I.MX RT1170之MIPI DSI初始化和显示流程详解中&#xff0c;我们介绍了RT1170单片机中MIPI DSI显示屏初始化和显示的详细步骤&#xff0c;那这一节就来介绍MIPI的另一个接口应用&#xff1a;摄像头CSI的初始化和配置流程。 对于摄像头来说&#xff0c;一般我们还要…

软件产品必须要进行鉴定测试吗?测试流程和作用简析

软件产品是现代社会中不可或缺的一部分&#xff0c;它们在商业、娱乐、科技等领域的应用广泛且深入。然而&#xff0c;我们是否关注过这些软件产品的鉴定测试呢?鉴定测试是什么?它的测试流程有哪些?又有什么作用呢?在本文中&#xff0c;我们将为您全面解析这些问题。 鉴定…