【运筹优化】最短路算法之SPFA算法 + Java代码实现
文章目录
- 一、SPFA算法简介
- 二、SPFA算法思想
- 三、Java代码实现
- 四、测试
一、SPFA算法简介
SPFA 算法是 Bellman-Ford算法 的队列优化算法的别称,通常用于求含负权边的单源最短路径,以及判负权环。SPFA 最坏情况下复杂度和朴素 Bellman-Ford 相同,为 O(VE)。
SPFA算法的全称是:Shortest Path Faster Algorithm,是西南交通大学段凡丁于 1994 年发表的论文中的名字。不过,段凡丁的证明是错误的,且在 Bellman-Ford 算法提出后不久(1957 年)已有队列优化内容,所以国际上不承认 SPFA 算法是段凡丁提出的。
二、SPFA算法思想
若给定的图存在负权边,类似Dijkstra算法等算法便没有了用武之地,SPFA算法便派上用场了。简洁起见,我们约定加权有向图G不存在负权回路,即最短路径一定存在。
用数组d记录每个结点的最短路径估计值,而且用邻接表来存储图G。我们采取的方法是动态逼近法:设立一个先进先出的队列用来保存待优化的结点,优化时每次取出队首结点u,并且用u点当前的最短路径估计值对离开u点所指向的结点v进行松弛操作,如果v点的最短路径估计值有所调整,且v点不在当前的队列中,就将v点放入队尾。这样不断从队列中取出结点来进行松弛操作,直至队列空为止。
定理
只要最短路径存在,上述SPFA算法必定能求出最小值。证明:每次将点放入队尾,都是经过松弛操作达到的。换言之,每次的优化将会有某个点v的最短路径估计值d[v]变小。所以算法的执行会使d越来越小。由于我们假定图中不存在负权回路,所以每个结点都有最短路径值。因此,算法不会无限执行下去,随着d值的逐渐变小,直到到达最短路径值时,算法结束,这时的最短路径估计值就是对应结点的最短路径值。
实际上,如果一个点进入队列达到n次,则表明图中存在负环,没有最短路径。
段凡丁论文中的复杂度证明 (O(kE),k 是小常数)是错误的,在此略去。该算法的最坏复杂度为 O(VE)。
对SPFA的一个很直观的理解就是由无权图的BFS转化而来。在无权图中,BFS首先到达的顶点所经历的路径一定是最短路(也就是经过的最少顶点数),所以此时利用数组记录节点访问可以使每个顶点只进队一次,但在带权图中,最先到达的顶点所计算出来的路径不一定是最短路。一个解决方法是放弃数组,此时所需时间自然就是指数级的,所以我们不能放弃数组,而是在处理一个已经在队列中且当前所得的路径比原来更好的顶点时,直接更新最优解。
SPFA算法有两个优化策略SLF和LLL
SLF:Small Label First 策略,设要加入的节点是j,队首元素为i,若dist(j)<dist(i),则将j插入队首,否则插入队尾;
LLL:Large Label Last 策略,设队首元素为i,队列中所有dist值的平均值为x,若dist(i)>x则将i插入到队尾,查找下一元素,直到找到某一i使得dist(i)<=x,则将i出队进行松弛操作。SLF 和 LLF 在随机数据上表现优秀,但是在正权图上最坏情况为 O(VE),在负权图上最坏情况为达到指数级复杂度。
三、Java代码实现
@Data
public class SPFA {// 距离矩阵double[][] distance;// 起点int start;// 终点int end;/*** @param distance* @param start* @param end* @Description 构造函数* @Author WSKH*/public SPFA(double[][] distance, int start, int end) {this.distance = distance;this.start = start;this.end = end;}/*** @Description 进行求解* @Author WSKH*/public void solve() {// 初始化dis一维数组double[] dis = new double[distance.length];for (int i = 0; i < dis.length; i++) {if (i != start) {dis[i] = Double.MAX_VALUE;}}// 声明队列(用集合模拟)List<Integer> list = new LinkedList<>();// 初始化队列,添加起点进入队列list.add(start);// 记录每个顶点入队的次数int[] counter = new int[distance.length];counter[start]++;//HashMap<Integer,List<Integer>> shortestPathMap = new HashMap<>();for (int i = 0; i < distance.length; i++) {List<Integer> arrayList = new ArrayList<>();arrayList.add(start);shortestPathMap.put(i,arrayList);}// 开始循环while (!list.isEmpty()) {// 获取当前队首元素索引int index = list.remove(0);// 看看能不能松弛for (int i = 0; i < dis.length; i++) {if (i != start && i != index && dis[i] > distance[index][i] + dis[index]) {dis[i] = distance[index][i] + dis[index];List<Integer> integerList = new ArrayList<>(shortestPathMap.get(index));integerList.add(i);shortestPathMap.put(i,integerList);// 看看i能不能入队if (!list.contains(i)) {list.add(i);counter[i]++;// 如果某个顶点入队次数大于顶点数,那么说明图中存在负权回路if (counter[i] > distance.length) {throw new RuntimeException("存在负权回路!" + Arrays.toString(counter));}}}}}System.out.println("每个顶点入队次数为:" + Arrays.toString(counter));System.out.println("起点到其余各个点的最短路为:" + Arrays.toString(dis));System.out.println(shortestPathMap.get(end));}
}
四、测试
public class Test {public static void main(String[] args) {double[][] distance = new double[][]{{0, 8, 9, 2, 5},{8, 0, 7, 2, 8},{9, 7, 0, 3, 9},{2, 2, 3, 0, 5},{5, 8, 9, 5, 0},};new SPFA(distance,0,2).solve();}
}
控制台输出:
每个顶点入队次数为:[1, 2, 2, 1, 1]
起点到其余各个点的最短路为:[0.0, 4.0, 5.0, 2.0, 5.0]
[0, 3, 2]
其中 [0, 3, 2] 代表0到2的最短路径为:0->3->2
相关文章:
【运筹优化】最短路算法之SPFA算法 + Java代码实现
文章目录 一、SPFA算法简介二、SPFA算法思想三、Java代码实现四、测试 一、SPFA算法简介 SPFA 算法是 Bellman-Ford算法 的队列优化算法的别称,通常用于求含负权边的单源最短路径,以及判负权环。SPFA 最坏情况下复杂度和朴素 Bellman-Ford 相同…...
linuxOPS基础_linux权限管理
权限概述 什么是权限 在多用户计算机系统的管理中,权限是指某个特定的用户具有特定的系统资源使用权利。 在Linux 中分别有读、写、执行权限 \权限针对文件权限针对目录读r(read)表示可以查看文件内容;cat、less…表示可以(ls)查看目录中存在的文…...
linux安装homeassistant(智能设备远程控制开源框架)
1、安装docker 先切换到root 用户,先安装一些基本环境: yum install -y yum-utils device-mapper-persistent-data lvm2添加阿里云软件源 yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo然后安装 D…...
TensorRT Triton Inference Server: 版本 error魔术标记不匹配 , NGC使用
魔术标记不匹配错误Serialization assertion magicTagRead kMAGIC_TAG failed.Magic tag does not match 原因: 转换和推理使用的镜像的标签是相同的,但是转换的镜像中pip list得到trt版本为8.6.0,但是推理环境中 rootf2c810ba3976:/# /usr/…...
Elasticsearch 文本分析器(下)
字符过滤器 注意:字符过滤器用于在将字符流传递给分词器之前对其进行预处理 html_strip HTML元素替换过滤器 此过滤器会替换掉HTML标签,且会转换HTML实体 如:& 会被替换为 &。 {"tokenizer": "keyword","…...
Git操作方法
目录 Git是什么 Git特点 Git作用 Git原理 集中式 分布式 Git安装 修改语言 Git操作 1.初始化Git仓库 2.提交工作区的内容到版本库 3.查看版本记录 4.版本回退 5.版本前进 Git 命令 通用操作 工作状态 版本回退 版本前进 远程仓 1.GitHub 2.GitLab 3.码云…...
CorelDRAW矢量绘图2023中文版下载
市面上的矢量绘图工具虽然很多,但权威又专业的却不多,选到不好用的工具,会极大的影响自己创作,CorelDRAW简称cdr,是一款功能强大的矢量图制作软件,一说到矢量图制作,大家都会不由自主地想到cdr。…...
Java-API简析_java.lang.Float类(基于 Latest JDK)(浅析源码)
【版权声明】未经博主同意,谢绝转载!(请尊重原创,博主保留追究权) https://blog.csdn.net/m0_69908381/article/details/131129886 出自【进步*于辰的博客】 其实我的【Java-API】专栏内的博文对大家来说意义是不大的。…...
pycharm的基本使用
废话文学 本人记录笔记始终遵循“能动手绝不动脑,能动脑绝不动手”的基本原则。不会的操作,跟着笔记干就完事了,还动啥脑袋?留着脑细胞刷抖音擦边小姐姐他不香吗? 什么是IDE IDE即【集成开发环境】,Inte…...
为什么要使用微软的 Application Framework?
我是荔园微风,作为一名在IT界整整25年的老兵,今天来看一下我们为什么要使用微软的 Application Framework? 虽然Application Framework 并不是新观念,它们却在最近数年才成为 PC 平台上软件开发的主流工具。面向对象语言是具体实…...
Python爬虫基础知识点
Python爬虫是使用Python编写的程序,可以自动抓取互联网上的数据。常用的Python爬虫框架包括Scrapy、BeautifulSoup、Requests等。Python爬虫可以应用于众多场合,如大数据分析、信息监测、数据挖掘和机器学习等领域。那么新手应该如何学习python爬虫呢&am…...
K8s运维备忘
1.服务器集群搭建: VagrantFile中加入以下代码,创建3个虚拟机: Vagrant.configure("2") do |config| (1..3).each do |i| config.vm.define "k8s-node#{i}" do |node| # 设置虚拟机的Box …...
激光雷达+rtk+rgb联合使用(4)
因为一直在忙一些乱七八糟的事情,就没顾得上继续写,想着快速收尾算了。 前面写到,我在点云的匹配上花了大量的时间,不断的调参数,换方法,一共几百个点云,想着先每50个匹配一次,得到几…...
【K8S系列】快速初始化⼀个最⼩集群
序言 走得最慢的人,只要不丧失目标,也比漫无目的地徘徊的人走得快。 文章标记颜色说明: 黄色:重要标题红色:用来标记结论绿色:用来标记一级重要蓝色:用来标记二级重要 希望这篇文章能让你不仅有…...
Exploit/CVE-2010-0738
打开JBoss的潘多拉魔盒:JBoss高危漏洞分析 *本文中涉及到的相关漏洞已报送厂商并得到修复,本文仅限技术研究与讨论,严禁用于非法用途,否则产生的一切后果自行承担。 前言 JBoss是一个基于J2EE的开放源代码应用服务器࿰…...
Go单元测试及框架使用
Go自带测试框架 单元测试 建议Go 语言推荐测试文件和源代码文件放在一块,测试文件以 _test.go 结尾。函数名必须以 Test 开头,后面一般跟待测试的函数名参数为 t *testing.T 简单测试用例定义如下: func TestXXXX(t *testing.T) {// ...}…...
TreeMap类型实体类数据进行排序
实体类Student类代码如下所示: package com.test.Test11;public class Student implements Comparable<Student>{private int age;private String name;private Double height;public int getAge() {return age;}public void setAge(int age) {this.age age…...
HOOPS助力AVEVA数字化转型:支持多种3D模型格式转换!
行业: 电力和公用事业、化工、造船、能源、采矿业 挑战: 创建大规模复杂资产的客户需要汇集多种类型的数据,以支持初始设计和创建强大的数字双胞胎;现有版本的产品只支持半打CAD格式;有限的内部开发资源限制了增加对新…...
(转载)基于遗传模拟退火的聚类算法(matlab实现)
1 理论基础 1.1 模糊聚类分析 模糊聚类是目前知识发现以及模式识别等诸多领域中的重要研究分支之一。随着研究范围的拓展,不管是科学研究还是实际应用,都对聚类的结果从多方面提出了更高的要求。模糊C-均值聚类(FCM)是目前比较流行的一种聚类方法。该…...
【C++】struct 和 class 的区别
欢迎来到博主 Apeiron 的博客,祝您旅程愉快。时止则止,时行则行。动静不失其时,其道光明。 目录 1、缘起 2、示例代码 3、总结 1、缘起 在 C 中,struct 和 class 唯一的区别就在于 默认的访问权限不同。区别如下: …...
活动笔记丨物业行业人效提升与灵活用工新路径
近日,盖雅工场成功举办物业行业人效提升专场交流,来自广深地区央企和民营的领先物业企业和现场服务业的多位代表齐聚深圳招商积余大厦,共同研讨行业人效提升的挑战和实践。 本次闭门交流会聚焦于人效提升,讨论话题包括各自企业在人…...
学习笔记:吴恩达ChatGPT提示工程
以下为个人笔记,原课程网址Short Courses | Learn Generative AI from DeepLearning.AI 01 Introduction 1.1 基础LLM 输入 从前有一只独角兽,输出 它和其他独角兽朋友一起住在森林里输入 法国的首都在哪?输出 法国的首都在哪…...
POI in Action
POI 组件依赖 按需引入对应依赖 (给出官方的指引) 组件作用Maven依赖POIFSOLE2 FilesystempoiHPSFOLE2 Property SetspoiHSSFExcel XLSpoiHSLFPowerPoint PPTpoi-scratchpadHWPFWord DOCpoi-scratchpadHDGFVisio VSDpoi-scratchpadHPBFPublisher PUBpoi-scratchpadHSMFOutloo…...
苹果Vision Pro将引爆人机交互的重大变革
2023年6月6日,苹果发布了大家期待已久的Vision Pro,Vision Pro是一款专业级MR设备,融合了虚拟现实(VR)和增强现实(AR)技术,可以让用户完全沉浸在高分辨率显示内容中。允许用户以一种全新的方式在其周围的空间中查看APP。用户可以用…...
MMDetection学习记录(二)之配置文件
文件结构 config文件 在 config_base_ 文件夹下有 4 个基本组件类型,分别是:数据集(dataset),模型(model),训练策略(schedule)和运行时的默认设置(default runtime)。 命名风格 {model}_[model setting]_{backbone}_{neck}_[no…...
Python数据分析:NumPy、Pandas和Matplotlib的使用和实践
在现代数据分析领域中,Python已成为最受欢迎的编程语言之一。Python通过庞大的社区和出色的库支持,成为了数据科学家和分析师的首选语言。在Python的库中,NumPy、Pandas和Matplotlib是三个最为重要的库,它们分别用于处理数值数组、…...
实习生面试问题及回答记录
文章目录 文章简介技术类1、DFS和BFS算法的区别是什么?2、解释一下什么是快速排序?3、 如果让你写一个排序算法?你会怎么写?(大概说出代码的思路)4、解释一下二分查找的具体逻辑?5、在代码的数据…...
设计模式(十):结构型之外观模式
设计模式系列文章 设计模式(一):创建型之单例模式 设计模式(二、三):创建型之工厂方法和抽象工厂模式 设计模式(四):创建型之原型模式 设计模式(五):创建型之建造者模式 设计模式(六):结构型之代理模式 设计模式…...
买法拍房需要注意什么
法拍房,由于其价格亲民、房屋信息透明度高、竞拍过程公平公正而受到越来越多的人开始关注。但是其中又有着许多的风险及相关的注意事项。那么,如何做到成功“捡漏”,买法拍房需要注意什么呢? 买法拍房需要注意什么 1、隐藏的各种收费 税费&a…...
linux命令输出结果但不显示在屏幕上的通用办法
linux命令输出结果但不显示在屏幕上的通用办法 这个针对于我这种小白马大哈很简单的一个命令,记给自己备用 举个例子:unzip命令不输出结果 unzip xx.zip > /dev/null 2>&1 unzip xx.zip > /dev/null 前半部分是将标准输出重定向到空设备&a…...
做购物网站的费用/百度推广怎么推
分类: Oracle 问题描述:对数据库做检查,发现system表空间持续占满99%。使用如下语句查看:SQL> select b.tablespace_name "表空间",b.bytes/1024/1024 "大小M",(b.bytes-sum(nvl(a.bytes,0)))/1024/1024 &…...
绑定ip地址的网站/ai智能搜索引擎
一直都是在自己IIS上部署的,第一次部署MVC项目到共享主机,遇到了些问题。如果你也遇到过类似下图的问题,希望这篇文章对你有些帮助。 首先, 到 IIS management 设置IIS: 7.0 and ASP.Net Runtime Version: 4.0 , 然后到高级选项确…...
用微信微博网站来做睡眠经济/哪个公司的网站制作
https://blog.csdn.net/xiaoshan0711/article/details/54571823 在小程序的开发过程中,我们会遇到一种情况,就是在制作五星点评的时候,默认五颗星星都是要亮的。这里我们就要分享一下自己做默认五星的心得。 在这里我们先看一下效果图&#x…...
网站建设要学哪些软件有哪些内容/百度地图疫情实时动态
本篇文章是我学习UE4的笔记 学习地址如下 本文出现的英语单词: Spawn 生成 添加淡入淡出效果 一个是在小球的蓝图类里面,添加游戏开始的淡入效果 一个是在失败的蓝图类里添加一个淡出效果 具体的蓝图类如下图所示 主要是要先获取到camera palyer 就是目前的摄像机. 然…...
怎么把服务器做网站/一手渠道推广平台
一.Intent的介绍 Intent的中文意思是“意图,意向”,在Android中提供了Intent机制来协助应用间的交互与通讯,Intent负责对应用中一次操作的动作、动作涉及数据、附加数据进行描述,Android则根据此Intent的描述,负责找到…...
app推广方式有哪些/南京seo排名优化公司
最近家里杂事较多,自学时间实在少的可怜,所以都在空闲时间看看老外写的内容,学习之外顺便翻译分享~等学习的时间充足些再写写自己的一些学习内容和知识点分析(最近有在接触的:复习(C#,SQL)、(学习)TypeScriptÿ…...