Floyd最短路算法

详解图的最短路径算法(BFS、Dijkstra、Floyd)(附上图解步骤) 详解图的最短路算法、针对BFS、Dijkstra、Floyd算法写出详细的图解、解题步骤 阅读详情

此算法由Robert W. Floyd(罗伯特·弗洛伊德)于1962年发表在“Communications of the ACM”上。同年Stephen Warshall(史蒂芬·沃舍尔)也独立发表了这个算法。Robert W.Floyd这个牛人是朵奇葩,他原本在芝加哥大学读的文学,但是因为当时美国经济不太景气,找工作比较困难,无奈之下到西屋电气公司当了一名计算机操作员,在IBM650机房值夜班,并由此开始了他的计算机生涯。

Floyd算法又称为插点法,是一种利用动态规划的思想寻找给定的加权图中多源点之间最短路径的算法,与Dijkstra算法类似,用于求每一对顶点的最短路径。有向图无向图均可,也可以有负权边。


暑假,小哼准备去一些城市旅游。有些城市之间有公路,有些城市之间则没有,如左图。为了节省经费以及方便计划旅程,小哼希望在出发之前知道任意两个城市之前的最短路程。

上图中有4个城市8条公路,公路上的数字表示这条公路的长短。请注意这些公路是单向的。我们现在需要求任意两个城市之间的最短路程,也就是求任意两个点之间的最短路径。这个问题这也被称为“多源最短路径”问题。

现在需要一个数据结构来存储图的信息,我们仍然可以用一个4*4的矩阵(二维数组e)来存储。比如1号城市到2号城市的路程为2,则设e[1][2]的值为2。2号城市无法到达4号城市,则设置e[2][4]的值为∞。另外此处约定一个城市自己是到自己的也是0,例如e[1][1]为0


现在问题来了如何求任意两点之间的最短路径呢?

如果求任意两点之间的最短路径,两点之间可以直接到达但却不是最短的路径,要让任意两点(例如从顶点a点到顶点b)之间的路程变短,只能引入第三个点(顶点k),并通过这个顶点k中转即a->k->b,才可能缩短原来从顶点a点到顶点b的路程。那么这个中转的顶点k是1~n中的哪个点呢?甚至有时候不只通过一个点,而是经过两个点或者更多点中转会更短。比如上图中从4号城市到3号城市(4->3)的路程e[4][3]原本是12。如果只通过1号城市中转(4->1->3),路程将缩短为11(e[4][1]+e[1][3]=5+6=11)。其实1号城市到3号城市也可以通过2号城市中转,使得1号到3号城市的路程缩短为5(e[1][2]+e[2][3]=2+3=5)。所以如果同时经过1号和2号两个城市中转的话,从4号城市到3号城市的路程会进一步缩短为10。通过这个的例子,我们发现每个顶点都有可能使得另外两个顶点之间的路程变短。好,下面我们将这个问题一般化。

当任意两点之间不允许经过第三个点时,这些城市之间最短路程就是初始路程


在只允许经过1号顶点的情况下,任意两点之间的最短路程更新为:


在只允许经过1号顶点的情况下,只需判断e[i][1]+e[1][j]是否比e[i][j]要小即可。e[i][j]表示的是从i号顶点到j号顶点之间的路程。e[i][1]+e[1][j]表示的是从i号顶点先到1号顶点,再从1号顶点到j号顶点的路程之和。其中i是1~n循环,j也是1~n循环,代码实现如下。

for(i=1;i<=n;i++)   
{   
    for(j=1;j<=n;j++)   
    {   
      if ( e[i][j] > e[i][1]+e[1][j] )   
      e[i][j] = e[i][1]+e[1][j];   
    }   
} 

接下来继续求在只允许经过1和2号两个顶点的情况下任意两点之间的最短路程。如何做呢?我们需要在只允许经过1号顶点时任意两点的最短路程的结果下,再判断如果经过2号顶点是否可以使得i号顶点到j号顶点之间的路程变得更短。即判断e[i][2]+e[2][j]是否比e[i][j]要小,在只允许经过1和2号顶点的情况下,任意两点之间的最短路程更新为:


判断e[i][2]+e[2][j]是否比e[i][j]要小,代码实现为如下。

//经过1号顶点   
for(i=1;i<=n;i++)   
   for(j=1;j<=n;j++)   
 if (e[i][j] > e[i][1]+e[1][j]) 
 e[i][j]=e[i][1]+e[1][j];   
//经过2号顶点   
for(i=1;i<=n;i++)   
    for(j=1;j<=n;j++)   
 if (e[i][j] > e[i][2]+e[2][j])  
e[i][j]=e[i][2]+e[2][j]; 

同理,继续在只允许经过1、2和3号顶点进行中转的情况下,求任意两点之间的最短路程。任意两点之间的最短路程更新为:


最后允许通过所有顶点作为中转,任意两点之间最终的最短路程为:

整个算法过程虽然说起来很麻烦,但是代码实现却非常简单,核心代码只有五行:

for(k=1;k<=n;k++)   
    for(i=1;i<=n;i++)   
 for(j=1;j<=n;j++)   
     if(e[i][j]>e[i][k]+e[k][j])   
   e[i][j]=e[i][k]+e[k][j]; 
另外需要注意的是:Floyd算法不能解决带有“负权回路”(或者叫“负权环”)的图,因为带有“负权回路”的图没有最短路。例如下面这个图就不存在1号顶点到3号顶点的最短路径。因为1->2->3->1->2->3->…->1->2->3这样路径中,每绕一次1->-2>3这样的环,最短路就会减少1,永远找不到最短路。其实如果一个图中带有“负权回路”那么这个图则没有最短路。

Floyd优缺点分析

优点:容易理解,可以算出任意两个节点之间的最短距离,代码编写简单。
缺点:时间复杂度比较高(n3),不适合计算大量数据。

Floyd算法与Dijkstra算法的不同

1.Floyd算法是求任意两点之间的距离,是多源最短路,而Dijkstra(迪杰斯特拉)算法是求一个顶点到其他所有顶点的最短路径,是单源最短路。
2.Floyd算法可以算带负权的,而Dijkstra(迪杰斯特拉)算法是不可以算带负权的。并且Floyd算法不能算负权回路。
3.Dijkstra(迪杰斯特拉)算法时间复杂度一般是o(n^2),Floyd算法时间复杂度是o(n^3),Dijkstra(迪杰斯特拉)算法比Floyd算法块。
4.Floyd算法属于动态规划,Dijkstra(迪杰斯特拉)算法属于贪心算法。

#include<stdio.h>   
int main()   
{   
    int e[10][10];
	int k,i,j,n,m,t1,t2,t3   
    int inf=99999999;//用inf(infinity的缩写)存储一个我们认为的正无穷值   
    scanf("%d %d",&n,&m);//读入n和m,n表示顶点个数,m表示边的条数   
    //初始化   
    for(i=1;i<=n;i++)   
    {
    for(j=1;j<=n;j++)   
     {
      if(i==j) 
	  e[i][j]=0;   
      else 
      e[i][j]=inf;   
	 }
	}
    //读入边   
    for(i=1;i<=m;i++)   
    {   
    scanf("%d %d %d",&t1,&t2,&t3);   
    e[t1][t2]=t3;   
    }   
    //Floyd算法核心部分 
    for(k=1;k<=n;k++)   
    for(i=1;i<=n;i++)   
    for(j=1;j<=n;j++)   
    if(e[i][j]>e[i][k]+e[k][j])   
    e[i][j]=e[i][k]+e[k][j];   
    //输出最终的结果   
    for(i=1;i<=n;i++)   
    {   
     for(j=1;j<=n;j++)   
     {   
     printf("%10d",e[i][j]);   
     }   
     printf("\n");   
    }   
    return 0;   
} 


Matlab_Floyd算法求解最短路 最短路问题(short-path problem)是网络理论解决的典型问题之一,可用来解决管路铺设、线路安装、厂区布局和设备更新等实际问题。基本内容是:若网络中的每条边都有一个数值(长度、成本、时间等),则找出两节点(通常是源节点和阱节点)之间总权和最小的路径就是最短路问题。 解决最短路问题的Floyd算法: Floyd算法: 又称为插点法,是一种利用动态规划的思想寻找给定的... 阅读详情

相关推荐

Floyd (弗洛伊德)算法简述

Floyd在1962年由Robert Floyd以其当前公认的形式出版。算法作为三个嵌套for循环的现代公式首先由Peter Ingerman在1962年描述。Floyd 算法是解决图论问题的比较经典的算法,是解决给定的加权图中顶点间的最短路径的一种算法,可以正确处理有向图的最短路径问题。

慕羽★的博客 2万+

Folyd 算法为什么不能处理带负权值的边组成的回路?

我们都知道Dijkstra算法的局限性是不可以处理带有负权值的图,但是Floyd算法可以 不过在Folyd算法对应的解释中,说“Floyd算法允许有带负权值的边,但不允许有包含带负权值的边组成的回路” 起初我看到这句话对后半部分是有些不太明白的,前半部分很简单,主要解释后半部分 这句话的意思并不是说“只要回路中存在负权值Floyd就不可以解决” 而是“组成这个回路的所有的边的权值之和如果为负,就无法解决,否则还是可以解决的” 下面给出两个例子就明白了 这个图中右侧的三个边组成了一个回

ThePythonFucker的博客 6121

Floyd 算法--多源最短路

我们是把 k =0 的 i 和j 对应的数值都初始化了,这样才能去计算 k = 1 的时候 i 和 j 对应的数值。grid[i][j][k] = m,表示 节点i 到 节点j 以[1...k] 集合为中间节点的最短距离为m。你可以反过来想,节点i 到 节点j 中间一定经过很多节点,那么你能用什么方式来表述中间这么多节点呢?节点i 到 节点k 的最短距离 不经过节点k,中间节点集合为[1...k-1],所以 表示为。,同理节点k 到 节点j 的最短距离 也是不经过节点k,表示为。节点i 到 节点j 的。

qq_73704268的博客 823

弗洛伊德(Floyd)算法示例、输出最短路径方式、负值环问题

@[TOC]弗洛伊德(Floyd)算法 弗洛伊德(Floyd)算法示例、输出最短路径示例 弗洛伊德(Floyd)算法:在大话数据结构和浙大数据结构教材中的程序稍有不同,记录一下。 数据图: 代码 数组P(参考大话数据结构)、数组pf(参考浙大教材)用于记录最短路径,显示各顶点间的最短路径的方式也有不同. 问题:刚开始,我把数组 pf 设置为在main中的局部变量,结果在递归程序lujing中出错,显示“Program received signal SIGSEGV”,后来改成全局变量就正常了,不知道为啥,

qq_30972947的博客 1642

DSPF28335:从零到一,实战GPIO与外部中断的嵌入式系统交互设计

本文以德州仪器DSPF28335芯片为例,详细讲解了嵌入式系统中GPIO与外部中断(EXTI)的实战配置方法。通过一个完整的按键控制LED并触发ADC采样的项目,深入剖析了GPIO寄存器配置、三级中断机制(外设-PIE-CPU)以及中断服务函数编写的核心要点,帮助开发者掌握嵌入式交互设计的基石,并提供了关键的避坑指南与调试清单。

weixin_29169899的博客 115

MS1030超声波流量计电路实战:如何用15ps精度优化水表设计(附配置代码)

本文深入探讨了如何利用MS1030超声波流量计芯片实现15ps高精度测量,以优化水表设计。文章从系统误差分配出发,详细解析了硬件电路设计要点、SPI通信配置及核心优化技巧,如利用可编程偏置电压和8回波累加功能来提升抗干扰能力与测量稳定性,并附有实用的配置代码示例。

svm4gardener的博客 333

最短路——floyd算法

1. Floyd算法的介绍 算法的特点: 弗洛伊德算法是解决任意两点间的最短路径的一种算法,可以正确处理有向图或有向图或负权(但不可存在负权回路)的最短路径问题,同时也被用于计算有向图的传递闭包。Floyd-Warshall算法的时间复杂度为O(N3),空间复杂度为O(N2)。 Floyd-Warshall算法不能解决带有“负权回路”(或者叫“负权环”)的图,因为带有“负权回路”...

AC_AC_的博客 2696

✨使用 vLLM + Docker 部署 Qwen3-Embedding-8B 并实现高效文本向量生成(附 `curl` 测试)

本文介绍了如何使用 vLLM 和 Docker 部署 Qwen3-Embedding-8B 嵌入模型服务,并通过标准 OpenAI 兼容接口进行调用和结果解析。如果你在部署中遇到任何问题,欢迎留言讨论!

用大模型重构生活:猫奴程序员的AI智能日常记录 6238

Floyd算法(854. Floyd求最短路)

本篇博客就来讲解一下求解多源汇最短路问题中的Floyd算法。什么是多源汇最短路?就是求n个点中任意两点的距离。

2301_77160836的博客 1220

C#:实现统计图像主颜色的算法(附完整源码)

C#:实现统计图像主颜色的算法(附完整源码)

希望我的博客,能帮上你解决学习中工作中所遇到的问题 519

RISC-V CPU设计(三)---多周期CPU的设计与实现

基本情况 本多周期CPU支持RV32I指令集(fence,ecall,ebreak除外),已通过部分指令的测试,如代码有bug,欢迎指出。 模块划分 代码将CPU划分为以下几个模块: 1.控制单元:ControlUnit 用于产生控制信号,是CPU的大脑,指挥中枢。 2.分支决策单元:BranchUnit 用于决定B型指令是否发生跳转 3.立即数单元:ImmUnit 用于从指令中解析出立即数. 4.寄存器堆:RegisterFile RISC-V的32个寄存器,其中x0寄存器恒为0,不可更改。 5.指令存储

qq_40268672的博客 5542

多源最短路算法——Floyd算法

1.多源最短路简介: 我们知道单源最短路是指从某一个源点到图中的其它顶点的最短路。 多源最短路就是指每一个点到图中其他顶点的最短路。 那么有的人肯定想我知道求单源最短路的算法了,那么有多少个点我就求多少次呗,这样做时间效率不高,空间效率也极其低。 那么有什么算法求解多源最短路呢?——Floyd 2.Floyd简介: 3.三维空间Floyd核心代码: int g[N][N]; // 邻接矩阵存图...

ly's Blog 3241

selenium绕过检测,规避检测

现在不少大网站有对selenium采取了监测机制。比如正常情况下我们用浏览器访问淘宝等网站的 window.navigator.webdriver的值为 undefined或者为false。而使用selenium访问则该值为true。那么如何解决这个问题呢?我们正常浏览器登录查看,window.navigator.webdriver的值为false我们通过selenium打开的网页,测试,可见window.navigator.webdriver的值为true。

景天科技苑 1万+

最短路算法(1)——floyd算法

本章将介绍原理及floyd的算法实现。

2301_76390048的博客 680

yolov8 转华为昇腾om脚本

yolov8 转华为昇腾om脚本

jacke121的专栏 1601

《UDS协议从入门到精通》系列——图解0x83:访问时间参数

详细介绍UDS协议0x83服务,目标ECU的时序参数设置有哪些注意点?

车载系统攻城狮 2138

最短路算法——Dijkstra,Floyd

本文介绍了两种经典的最短路径算法:Dijkstra算法和Floyd算法。Dijkstra算法采用贪心策略和堆优化,适用于单源非负权图的最短路径问题,时间复杂度为O(ElogV)。Floyd算法通过动态规划思想解决多源最短路径问题,使用三层循环枚举中转点更新距离矩阵,时间复杂度为O(V³)。两种算法分别适用于稀疏图和稠密图:Dijkstra适合边少点多的情况,而Floyd适合点多边少的情况。文章通过洛谷例题展示了两种算法的具体实现,并对比了它们的适用场景和性能特点。

CChisato_的博客 970

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

Dijkstra与Floyd求最短路算法简介

Dijkstra算法是一种用于求解带非负权值边的单源最短路径问题的经典算法。本文介绍了Dijkstra算法的核心思想:通过贪心策略,每次选择当前距离起点最近的未确定节点,更新其邻近节点的距离。文章给出了邻接表实现的C++代码示例,并详细解释了优先队列优化、距离初始化和路径更新的关键步骤。此外,还通过5个典型例题(包括模板题和应用题)展示了Dijkstra算法的实际应用,如处理双向边、最小瓶颈路径等问题。这些例题涵盖了从基础模板到变式应用的完整学习路径,适合算法初学者理解和掌握Dijkstra算法。

2403_88489850的博客 876

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

算法学习——最短路三大算法(Floyd,Djstra,SPFA算法)

在图论中,有一个问题是求两点之间的最短路。解决最短路有三种算法:Floyd算法,Dijstra算法,SPFA算法。 这一次我们单独讲一下Dijstra算法。 在一个图内,我们需要找到起点X0到终点Xn的最短路,如果我们去遍历每一个点,效率就会十分低下。因为在每一个点都要判断下一个点就非常繁琐,时间复杂度很容易变成指数级的。 我们用数组U来记录两点之间的距离。 准备一个数组S,表示起点到任意一点 的距离,初始值设为无穷。 然后在U中寻找一个和起点距离最短(这里指直接与起点相连)的点,把它加入数组S,

m0_57811707的博客 1222

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

最短路——floyd,dijstra,spfa算法

一直想整理一下最短路,好久之前学的(都忘了差不多了),再回顾一下,增加印象 最短路; 1.Floyd最短路算法; (被戏称为五行算法)它可以求出一个图中任意两点之间的最短路距离,即多源最短路算法,但是复杂度为O(n3)很大,所以一般比赛用到的机会很少,1s的时间要求下,最多只能求1000点之间的最短路。优点就是代码短,好理解。 主要思想就是用图中的一个点k来判断能不能优化i到j之间的最短距...

HANGANG的博客 327

算法 {Floyd最短路,Floyd传递关系}

1

qq_66485519的博客 301

最短路算法 dijkstra bellman-ford还有Floyd

最短路算法 最短路算法主要有dijkstra bellman-ford还有Floyd三种 dijkstra算法 计算边权为正的单源最短路。同时适用于有向图和无向图 bellman-ford算法 floyd算法 ...

zpf1998的博客 341

图论 24. Floyd算法(多源最短路问题)

​。

m0_49844155的博客 1281

图论-最短路Floyd算法

Floyd算法是一种基于动态规划的全源最短路算法。它通过三重循环逐步更新节点间的最短路径:外层循环引入中间节点k,内层双重循环遍历所有节点对(i,j),比较直接路径和经过k点的间接路径。

2402_88147924的博客 610

最短路问题之Floyd算法

如题

只想躺平不想动 410
上一篇: ACM进阶学习计划
下一篇: 完整winscp xshell 配置搭建tomcat上传项目
amazingcode_lyl
博客等级 码龄11年 21粉丝 13原创
评论 5
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值