Python实现SPFA算法
目录
- Python实现SPFA算法
- 引言
- 一、SPFA算法的理论基础
- 1.1 最短路径问题
- 1.2 SPFA算法的基本原理
- 1.3 SPFA算法的复杂度
- 二、SPFA算法的Python实现
- 2.1 基本实现
- 2.2 案例一:使用SPFA算法进行城市交通最短路径计算
- 2.2.1 实现代码
- 2.3 案例二:负权重边的处理
- 2.3.1 实现代码
- 2.4 案例三:图的可视化
- 2.4.1 实现代码
- 三、SPFA算法的应用领域
- 四、SPFA算法的优劣势
- 4.1 优势
- 4.2 劣势
- 五、总结
Python实现SPFA算法
引言
SPFA(Shortest Path Faster Algorithm)是一种用于解决单源最短路径问题的高效算法。它是Bellman-Ford算法的优化版本,特别适用于稀疏图。SPFA算法的核心思想是利用队列来维护当前可能的最短路径,通过不断更新路径长度,最终得到从源点到其他所有点的最短路径。
本文将详细探讨SPFA算法的原理与实现,提供多个应用实例,并通过面向对象的方式进行代码实现,帮助读者深入理解SPFA算法的具体应用。
一、SPFA算法的理论基础
1.1 最短路径问题
最短路径问题是图论中的经典问题,旨在寻找从一个节点到其他节点的最短路径。在不同的应用场景中,最短路径问题可以涉及到地图导航、网络路由、资源优化等多个方面。
1.2 SPFA算法的基本原理
SPFA算法的基本步骤如下:
- 初始化:设置源节点的距离为0,其他节点的距离为正无穷。
- 使用队列维护待处理节点:将源节点加入队列。
- 迭代处理队列:每次从队列中取出一个节点,更新其邻接节点的距离。如果更新后的距离小于当前记录的距离,则将邻接节点加入队列。
- 结束条件:当队列为空时,算法结束,所有节点的最短路径已被计算。
1.3 SPFA算法的复杂度
SPFA算法在最坏情况下的时间复杂度为O(VE),其中V为图的顶点数,E为边数。虽然在稀疏图中通常比Bellman-Ford算法更快,但在特定情况下,可能会退化为O(VE)。
二、SPFA算法的Python实现
接下来,我们将使用Python实现SPFA算法,并通过面向对象的方式进行代码组织。
2.1 基本实现
from collections import defaultdict, deque
import mathclass Graph:def __init__(self):self.edges = defaultdict(list) # 存储图的边def add_edge(self, u, v, weight):self.edges[u].append((v, weight)) # 添加一条边 u -> v,权重为weightdef spfa(self, start):distances = {node: math.inf for node in self.edges} # 初始化距离distances[start] = 0queue = deque([start]) # 初始化队列while queue:current = queue.popleft() # 取出队头节点for neighbor, weight in self.edges[current]:# 放松操作if distances[current] + weight < distances[neighbor]:distances[neighbor] = distances[current] + weightif neighbor not in queue:queue.append(neighbor) # 加入队列return distances# 示例
graph = Graph()
graph.add_edge('A', 'B', 1)
graph.add_edge('A', 'C', 4)
graph.add_edge('B', 'C', 2)
graph.add_edge('B', 'D', 5)
graph.add_edge('C', 'D', 1)distances = graph.spfa('A')
print(f"从A出发的最短路径:{distances}")
2.2 案例一:使用SPFA算法进行城市交通最短路径计算
假设我们有一个城市交通网络,包含多个交叉路口和道路。我们将使用SPFA算法计算从某个交叉路口到其他交叉路口的最短路径。
2.2.1 实现代码
class TrafficGraph(Graph):def __init__(self):super().__init__()def add_road(self, intersection1, intersection2, distance):self.add_edge(intersection1, intersection2, distance)self.add_edge(intersection2, intersection1, distance) # 双向道路# 创建交通图
traffic_graph = TrafficGraph()
traffic_graph.add_road('Intersection A', 'Intersection B', 10)
traffic_graph.add_road('Intersection A', 'Intersection C', 15)
traffic_graph.add_road('Intersection B', 'Intersection D', 12)
traffic_graph.add_road('Intersection C', 'Intersection D', 10)
traffic_graph.add_road('Intersection B', 'Intersection C', 5)# 计算从交叉路口A出发的最短路径
distances = traffic_graph.spfa('Intersection A')
print(f"从交叉路口A出发的最短路径:{distances}")
2.3 案例二:负权重边的处理
SPFA算法能够处理带负权重的边,但不能处理负权重环。下面的例子展示了如何使用SPFA算法处理包含负权重的图。
2.3.1 实现代码
class NegativeWeightGraph(Graph):def __init__(self):super().__init__()# 创建包含负权重的图
neg_weight_graph = NegativeWeightGraph()
neg_weight_graph.add_edge('A', 'B', 4)
neg_weight_graph.add_edge('A', 'C', 2)
neg_weight_graph.add_edge('B', 'C', 3)
neg_weight_graph.add_edge('B', 'D', 2)
neg_weight_graph.add_edge('C', 'D', -5) # 负权重边# 计算从A出发的最短路径
distances = neg_weight_graph.spfa('A')
print(f"从A出发的最短路径:{distances}")
2.4 案例三:图的可视化
我们可以将SPFA算法的结果进行可视化,以更直观地理解最短路径。以下代码使用Matplotlib进行简单的图形展示。
2.4.1 实现代码
import matplotlib.pyplot as pltclass VisualizedGraph(Graph):def __init__(self):super().__init__()def visualize(self, distances):plt.figure(figsize=(8, 6))for node, dist in distances.items():plt.text(node[0], node[1], f"{node}: {dist}", fontsize=12, ha='center')plt.xlim(-1, 4)plt.ylim(-1, 4)plt.title("最短路径可视化")plt.xlabel("X坐标")plt.ylabel("Y坐标")plt.grid()plt.show()# 创建可视化图
viz_graph = VisualizedGraph()
viz_graph.add_edge((0, 0), (1, 1), 1)
viz_graph.add_edge((0, 0), (2, 2), 4)
viz_graph.add_edge((1, 1), (2, 2), 2)# 计算最短路径并可视化
distances = viz_graph.spfa((0, 0))
viz_graph.visualize(distances)
三、SPFA算法的应用领域
SPFA算法广泛应用于以下领域:
- 网络路由:在网络中寻找最优路径,降低延迟。
- 城市交通:在城市地图中计算最短行驶时间。
- 资源分配:在生产和物流中优化资源分配。
- 游戏开发:在游戏地图中计算角色移动的最短路径。
四、SPFA算法的优劣势
4.1 优势
- 适用性强:能够处理带负权重的图,适用范围广。
- 实现简单:算法简单易于理解和实现。
4.2 劣势
- 效率问题:在特定情况下,可能会比Dijkstra算法慢。
- 对负权重环敏感:如果图中存在负权重环,算法将无法正常工作。
五、总结
SPFA算法是一种高效且实用的单源最短路径算法,能够处理带负权重的边。本文通过多个实例展示了SPFA算法在不同场景下的应用,结合面向对象的设计理念,使得代码更加模块化和易于扩展。
希望读者能够通过本文深入理解SPFA算法的原理与实现,并在实际应用中灵活运用,为解决最短路径问题提供有力的支持。
相关文章:
Python实现SPFA算法
目录 Python实现SPFA算法引言一、SPFA算法的理论基础1.1 最短路径问题1.2 SPFA算法的基本原理1.3 SPFA算法的复杂度 二、SPFA算法的Python实现2.1 基本实现2.2 案例一:使用SPFA算法进行城市交通最短路径计算2.2.1 实现代码 2.3 案例二:负权重边的处理2.3…...

MYSQL安装(ubuntu系统)
rpm -qa 查询安装软件包 ps axj 查询服务 卸载mysql(万不得已) ps axj | grep mysql 查看是否存在mysql服务 systemctl stop mysqld 关闭该服务 rpm -qa | grep mysql 查安装mysql安装包 rmp -qa | grep mysql | xargs (yum apt) -y remove进行批量…...

Cpp二叉搜索树的讲解与实现(21)
文章目录 前言一、二叉搜索树的概念定义特点 二、二叉树的实现基本框架查找插入删除当只有0 ~ 1个孩子的时候当有2个孩子的时候 三、二叉树的应用K模型KV模型 四、二叉树的性能分析总结 前言 这是全新的一个篇章呢,二叉搜索树是我们接下来学习set、map的前提 迈过它…...

微服务设计模式 — 补偿事务模式(Compensating Transaction Pattern)
微服务设计模式 — 补偿事务模式(Compensating Transaction Pattern) 定义 在云计算和分布式系统中,管理跨多个微服务或组件的事务一致性是一项极具挑战性的任务,补偿事务模式Compensating Transaction Pattern)是一种…...

20 实战:形状编码、运动补偿和纹理编码的实现(基于python)
在当今多媒体时代,视频处理与编码已经成为各个领域中不可或缺的一部分。无论是视频编辑、流媒体传输,还是计算机视觉应用,视频编码技术都扮演着关键角色。本文将详细解析一个基于Python的图形用户界面(GUI)视频编码器。通过对代码的逐行讲解、功能分析以及参数调节方法的探…...

区块链-C++挖矿软件XMRIG源码分析
C++挖矿软件源码分析 3rdpartybackendgrgon2Obfusheader.hmain 程序 xmrig.cppxmrig命名空间process类Entry::IdApp类CoreControllerbasetoolkernelinterfacesDonateStrategy.cppdonate.h/2/dmiCmake 跨平台的自动化构建系统CMakeLists.txt.cmake 13个引入算力哈希率 HashrateE…...

C语言指针的介绍
零.导言 在日常生活中,我们常常在外出时居住酒店,细心的你一定能发现酒店不同的房间上有着不同的门牌号,上面写着像308,512之类的数字。当你定了酒店之后,你就会拿到一个写有门牌号的钥匙,凭着钥匙就能进入…...

八大排序算法——堆排序
目录 前言 一、向上调整算法建堆 二、向下调整算法建堆 三、堆排序 前言 堆排序是基于堆结构的一种排序思想,因此要为一个乱序的数组进行排序的前提是数组必须要是一个堆,所以要先对数组进行建堆操作 一、向上调整算法建堆 时间复杂度:O…...

U盘文件不翼而飞?这些数据恢复工具帮你找回!
U盘因其便携性是我们日常工作和生活中不可或缺的工具。不过有时候它也会出点小状况。如果你U盘里的数据突然不见了,不要着急,可以先试试这几款数据恢复工具! 福昕数据恢复 直达链接:www.pdf365.cn/foxit-restore/ 操作教程&…...
在Java中 try catch 会影响性能吗?
1、在Java中,异常处理确实会对性能产生影响,但在正常执行的代码路径中,即没有发生异常的情况下,try-catch块的性能影响是微不足道的 2、但是,如果出现异常被抛出时,Java虚拟机需要执行一些额外的操作来处理…...

吞吐量最高飙升20倍!破解强化学习训练部署难题
**强化学习(RL)对大模型复杂推理能力提升有关键作用,然而,RL 复杂的计算流程以及现有系统局限性,也给训练和部署带来了挑战。近日,字节跳动豆包大模型团队与香港大学联合提出 HybridFlow(开源项…...
redis的数据过期策略
Redis对数据设置了数据的有效时间,数据过期之后,就需要将数据从内存中删除掉.可以按照不同的规则进行删除,这种删除规则就被称之为数据的删除策略(数据过期策略),而这种策略有两种:惰性删除和定期删除 惰性删除:设置key过期时间后,我们不去管它,当需要该key时,我们在检查其是否…...

三周精通FastAPI:27 使用使用SQLModel操作SQL (关系型) 数据库
官网文档:https://fastapi.tiangolo.com/zh/tutorial/sql-databases/ SQL (关系型) 数据库 FastAPI不需要你使用SQL(关系型)数据库。 但是您可以使用任何您想要的关系型数据库。 这里我们将看到一个使用SQLModel的示例。 SQLModel是在SQLAlchemy和Pydantic的基础…...

Kubernetes金丝雀发布
华子目录 Canary金丝雀发布什么是金丝雀发布Canary发布方式基于header(http包头)灰度发布基于权重的金丝雀发布 Canary金丝雀发布 什么是金丝雀发布 金丝雀发布也称为灰度发布,是一种软件发布策略主要目的是在将新版本的软件全面推广到生产环…...
树形DP讲解
文章目录 树形DP讲解一、引言二、树形DP基础1、树的定义2、树形DP的基本思想3、代码示例:子树大小 三、经典例题解析1、树的平衡点1.1、代码示例 2、没有上司的舞会(树的最大独立集)2.1、代码示例 四、总结 树形DP讲解 一、引言 树形动态规…...
容器:如何调试容器
调试容器,主要是指的调试Dockerfile,调试Dockerfile中的各个命令的执行,大小等 1、docker history查看构建过程和所有的中间层 2、docker run rm -it -u root XXX sh,通过临时容器的方式启动,可以调试中间层文件 3、do…...

用图说明 CPU、MCU、MPU、SoC 的区别
CPU CPU 负责执行构成计算机程序的指令,执行这些指令所指定的算术、逻辑、控制和输入/输出(I/O)操作。 MCU (microcontroller unit) 不同的 MCU 架构如下,注意这里的 MPU 表示 memory protection unit MPU (microprocessor un…...
牛客周赛 Round 65
文章目录 超市思路:Solved: 雨幕思路:Solved: 闺蜜思路:Solved: 医生思路:Solved: 降温(easy)思路:Solved: F-降温(hard&a…...

超级经典的79个软件测试面试题(内含答案)
1、软件的生命周期(prdctrm) 计划阶段(planning)-〉需求分析(requirement)-〉设计阶段(design)-〉编码(coding)->测试(testing)->运行与维护(running maintrnacne) 测试用例 用例编号 测试项目 测试标题 重要级别 预置条件 输入数据 执行步骤 预期结果 2、问…...
【Mac】安装 F5-TTS
1、下载项目 项目地址:【GitHub】 SWivid F5-TTS 2、创建并激活 Python 虚拟环境 # 创建 Python 虚拟环境 userMac F5-TTS-main % python3 -m venv f5-tts# 激活进入 Python 虚拟环境 userMac F5-TTS-main % source f5-tts/bin/activate (f5-tts) userrMac F5-TT…...

深入剖析AI大模型:大模型时代的 Prompt 工程全解析
今天聊的内容,我认为是AI开发里面非常重要的内容。它在AI开发里无处不在,当你对 AI 助手说 "用李白的风格写一首关于人工智能的诗",或者让翻译模型 "将这段合同翻译成商务日语" 时,输入的这句话就是 Prompt。…...
mongodb源码分析session执行handleRequest命令find过程
mongo/transport/service_state_machine.cpp已经分析startSession创建ASIOSession过程,并且验证connection是否超过限制ASIOSession和connection是循环接受客户端命令,把数据流转换成Message,状态转变流程是:State::Created 》 St…...
【解密LSTM、GRU如何解决传统RNN梯度消失问题】
解密LSTM与GRU:如何让RNN变得更聪明? 在深度学习的世界里,循环神经网络(RNN)以其卓越的序列数据处理能力广泛应用于自然语言处理、时间序列预测等领域。然而,传统RNN存在的一个严重问题——梯度消失&#…...
【论文笔记】若干矿井粉尘检测算法概述
总的来说,传统机器学习、传统机器学习与深度学习的结合、LSTM等算法所需要的数据集来源于矿井传感器测量的粉尘浓度,通过建立回归模型来预测未来矿井的粉尘浓度。传统机器学习算法性能易受数据中极端值的影响。YOLO等计算机视觉算法所需要的数据集来源于…...

ios苹果系统,js 滑动屏幕、锚定无效
现象:window.addEventListener监听touch无效,划不动屏幕,但是代码逻辑都有执行到。 scrollIntoView也无效。 原因:这是因为 iOS 的触摸事件处理机制和 touch-action: none 的设置有关。ios有太多得交互动作,从而会影响…...

华硕a豆14 Air香氛版,美学与科技的馨香融合
在快节奏的现代生活中,我们渴望一个能激发创想、愉悦感官的工作与生活伙伴,它不仅是冰冷的科技工具,更能触动我们内心深处的细腻情感。正是在这样的期许下,华硕a豆14 Air香氛版翩然而至,它以一种前所未有的方式&#x…...

Qemu arm操作系统开发环境
使用qemu虚拟arm硬件比较合适。 步骤如下: 安装qemu apt install qemu-system安装aarch64-none-elf-gcc 需要手动下载,下载地址:https://developer.arm.com/-/media/Files/downloads/gnu/13.2.rel1/binrel/arm-gnu-toolchain-13.2.rel1-x…...
日常一水C
多态 言简意赅:就是一个对象面对同一事件时做出的不同反应 而之前的继承中说过,当子类和父类的函数名相同时,会隐藏父类的同名函数转而调用子类的同名函数,如果要调用父类的同名函数,那么就需要对父类进行引用&#…...

给网站添加live2d看板娘
给网站添加live2d看板娘 参考文献: stevenjoezhang/live2d-widget: 把萌萌哒的看板娘抱回家 (ノ≧∇≦)ノ | Live2D widget for web platformEikanya/Live2d-model: Live2d model collectionzenghongtu/live2d-model-assets 前言 网站环境如下,文章也主…...

tauri项目,如何在rust端读取电脑环境变量
如果想在前端通过调用来获取环境变量的值,可以通过标准的依赖: std::env::var(name).ok() 想在前端通过调用来获取,可以写一个command函数: #[tauri::command] pub fn get_env_var(name: String) -> Result<String, Stri…...