【数据结构】图论最短路圣器:Floyd算法如何用双矩阵征服负权图?

最短路径

  • 穿越负权迷雾:Floyd算法如何解锁全图最短路径?​​
  • 一、Floyd算法
    • 1.1 算法思想
    • 1.2 算法逻辑
    • 1.3 算法评价
    • 1.4 算法限制
  • 二、三种算法对比
  • 🌟结语

图的基本应用

穿越负权迷雾:Floyd算法如何解锁全图最短路径?​​

大家好,很高兴又和大家见面啦!!!

你是否曾为Dijkstra算法在负权图前折戟而苦恼?这位单源最短路径的王者虽能高效征服正权图,却对负权边束手无策——当图上出现“补贴路径”(负权值)时,Dijkstra的贪心策略将彻底失效!

而今天登场的图灵奖得主​​Floyd算法​​,正为此而生!它用动态规划的三重循环(复杂度O(丨V丨³),以惊人的简洁性完成两大壮举:
1️⃣ ​​暴力破解全源最短路径​​:同时计算图中任意两点的最短距离
2️⃣ ​​完美驾驭负权图​​:轻松化解Dijkstra的致命弱点(除负权环外)

透过递推矩阵的魔法,你将看到:
▸ 初始邻接矩阵如何在中转点催化下层层蜕变(含分步图解)
▸ 路径矩阵如何像侦探般记录关键前驱节点
▸ C语言实现如何用双矩阵破译路径密码
▸ 负权环检测为何是算法必备的安全阀

文末更奉上​​三大算法对决表​​,助你秒选最佳路径方案!​​点击揭开全源最短路径的终极奥秘→​

一、Floyd算法

Floyd算法是由罗伯特·弗洛伊德(Robert·W·Floyd)提出,用于解决所有顶点之间的最短路径问题。

罗伯特·弗洛伊德(Robert·W·Floyd):

  • 1978年图灵奖得主
  • 提出了Floyd算法(Floyd-Warshall算法)
  • 提出了堆排序算法

1.1 算法思想

Floyd算法使用动态规划的思想,将求解每一对顶点之间的最短路径分解为多个阶段进行求解:

  • 对于n个顶点的图G,求任意一对顶点 V i − > V j V_i->V_j Vi>Vj 之间的最短路径,可将其分解为以下阶段:
    • 初始阶段:不允许在其它顶点中转,获取各顶点之间的最短路径
    • V 0 V_0 V0 阶段:允许在 V 0 V_0 V0 中转,再次获取各顶点之间的最短路径
    • V 1 V_1 V1 阶段:允许在 V 0 、 V 1 V_0、V_1 V0V1 中转,再次获取各顶点之间的最短路径
    • ⋯ \cdots
    • V n − 1 V_{n-1} Vn1阶段:允许在 V 0 、 V 1 、 ⋯ 、 V n − 1 V_0、V_1、\cdots、V_{n-1} V0V1Vn1 中转,再次获取各顶点之间的最短路径

为了更好的说明该算法的思想,下面我们以有向图G为例,介绍一下整个算法的执行过程:

6
4
5
10
13
a
b
c

在这个图中,包含3个顶点和5条弧:

  • ∣ V ∣ = { a , b , c } |V| = \{a, b, c\} V={a,b,c}
  • ∣ E ∣ = { < a , b , 6 > , < a , c , 13 > , < b , a , 10 > , < b , c , 4 > , < c , a , 5 > } |E| = \{\\<a, b, 6>, <a, c, 13>, \\ <b, a, 10>, <b, c, 4>, \\ <c, a, 5>\\\} E={<a,b,6>,<a,c,13>,<b,a,10>,<b,c,4>,<c,a,5>}

在Floyd算法执行的过程中,算法每一次执行,都会递推产生一个 3 3 3 阶方阵序列:

  • 初始阶段,各顶点之间的路径默认没有中转点:
    • V i V_i Vi 与点 V j V_j Vj 之间连通,则从点 V i V_i Vi 到点 V j V_j Vj 的弧 < v i , v j > <v_i, v_j> <vi,vj> 的权值即为这两个顶点之间的路径长度
    • V i V_i Vi 与点 V j V_j Vj 之间不连通,则默认这两个顶点之间的路径长度为 ∞ \infty
    • 初始阶段生成的 3 3 3 阶方阵如下所示:

初始阶段方阵 V ( − 1 ) = [ ∣ a ∣ b ∣ c ∣ — — — — — — — — a ∣ 0 ∣ 6 ∣ 13 ∣ — — — — — — — — b ∣ 10 ∣ 0 ∣ 4 ∣ — — — — — — — — c ∣ 5 ∣ ∞ ∣ 0 ∣ ] {初始阶段方阵V^{(-1)}}= \begin{bmatrix} & | & a &|& b&| & c&| \\ — & — & — &—& —&— & —&—\\ a & | & 0&|& 6&| & 13&| \\ — & — & — &—& —&— & —&—\\ b & | & 10 &|& 0&| & 4&| \\ — & — & — &—& —&— & —&—\\ c & | & 5 &|& \infty &| & 0&| \end{bmatrix} 初始阶段方阵V(1)= abca0105b60c1340

  • V 0 V_0 V0阶段,各顶点之间借助 a a a 为中转点,继续查找各顶点之间的最短路径:
    • a a a 到点 b b b 借助顶点 a a a 为中转点,没有更优路径
    • a a a 到点 c c c 借助顶点 a a a 为中转点,没有更优路径
    • b b b 到点 a a a 借助顶点 a a a 为中转点,没有更优路径
    • b b b 到点 c c c 借助顶点 a a a 为中转点,没有更优路径
    • c c c 到点 a a a 借助顶点 a a a 为中转点,没有更优路径
    • c c c 到点 b b b 借助顶点 a a a为中转点,存在更优路径 < c , a , b , 11 > <c, a, b, 11> <c,a,b,11>
    • V 0 V_0 V0 阶段生成的 3 3 3 阶方阵如下所示:

V 0 阶段方阵 V ( 0 ) = [ ∣ a ∣ b ∣ c ∣ — — — — — — — — a ∣ 0 ∣ 6 ∣ 13 ∣ — — — — — — — — b ∣ 10 ∣ 0 ∣ 4 ∣ — — — — — — — — c ∣ 5 ∣ 11 ∣ 0 ∣ ] {V_0阶段方阵V^{(0)}}= \begin{bmatrix} & | & a &|& b&| & c&| \\ — & — & — &—& —&— & —&—\\ a & | & 0&|& 6&| & 13&| \\ — & — & — &—& —&— & —&—\\ b & | & 10 &|& 0&| & 4&| \\ — & — & — &—& —&— & —&—\\ c & | & 5 &|& \color{red}11 &| & 0&| \end{bmatrix} V0阶段方阵V(0)= abca0105b6011c1340

  • V 1 V_1 V1阶段,各顶点之间借助 a a a 为中转点,继续查找各顶点之间的最短路径:
    • a a a 到点 b b b 借助顶点 a 、 b a、b ab 为中转点,没有更优路径
    • a a a 到点 c c c 借助顶点 a 、 b a、b ab 为中转点,存在更优路径 < a , b , c , 10 > <a, b, c, 10> <a,b,c,10>
    • b b b 到点 a a a 借助顶点 a 、 b a、b ab 为中转点,没有更优路径
    • b b b 到点 c c c 借助顶点 a 、 b a、b ab 为中转点,没有更优路径
    • c c c 到点 a a a 借助顶点 a 、 b a、b ab为中转点,没有更优路径
    • c c c 到点 b b b 借助顶点 a 、 b a、b ab为中转点,没有更优路径
    • V 1 V_1 V1 阶段生成的 3 3 3 阶方阵如下所示:

V 1 阶段方阵 V ( 1 ) = [ ∣ a ∣ b ∣ c ∣ — — — — — — — — a ∣ 0 ∣ 6 ∣ 10 ∣ — — — — — — — — b ∣ 10 ∣ 0 ∣ 4 ∣ — — — — — — — — c ∣ 5 ∣ 11 ∣ 0 ∣ ] {V_1阶段方阵V^{(1)}}= \begin{bmatrix} & | & a &|& b&| & c&| \\ — & — & — &—& —&— & —&—\\ a & | & 0&|& 6&| & \color{red}10&| \\ — & — & — &—& —&— & —&—\\ b & | & 10 &|& 0&| & 4&| \\ — & — & — &—& —&— & —&—\\ c & | & 5 &|& \color{red} 11&| & 0&| \end{bmatrix} V1阶段方阵V(1)= abca0105b6011c1040

  • V 2 V_2 V2阶段,各顶点之间借助 a a a 为中转点,继续查找各顶点之间的最短路径:
    • a a a 到点 b b b 借助顶点 a 、 b 、 c a、b、c abc 为中转点,没有更优路径
    • a a a 到点 c c c 借助顶点 a 、 b 、 c a、b、c abc 为中转点,没有更优路径
    • b b b 到点 a a a 借助顶点 a 、 b 、 c a、b、c abc 为中转点,存在更优路径 < b , c , a , 9 > <b, c, a, 9> <b,c,a,9>
    • b b b 到点 c c c 借助顶点 a 、 b 、 c a、b、c abc 为中转点,没有更优路径
    • c c c 到点 a a a 借助顶点 a 、 b 、 c a、b、c abc为中转点,没有更优路径
    • c c c 到点 b b b 借助顶点 a 、 b 、 c a、b、c abc为中转点,没有更优路径
    • V 2 V_2 V2 阶段生成的 3 3 3 阶方阵如下所示:

V 2 阶段方阵 V ( 2 ) = [ ∣ a ∣ b ∣ c ∣ — — — — — — — — a ∣ 0 ∣ 6 ∣ 10 ∣ — — — — — — — — b ∣ 9 ∣ 0 ∣ 4 ∣ — — — — — — — — c ∣ 5 ∣ 11 ∣ 0 ∣ ] {V_2阶段方阵V^{(2)}}= \begin{bmatrix} & | & a &|& b&| & c&| \\ — & — & — &—& —&— & —&—\\ a & | & 0&|& 6&| & \color{red}10&| \\ — & — & — &—& —&— & —&—\\ b & | & \color{red}9 &|& 0&| & 4&| \\ — & — & — &—& —&— & —&—\\ c & | & 5 &|& \color{red} 11&| & 0&| \end{bmatrix} V2阶段方阵V(2)= abca095b6011c1040

到此为止,我们就完成了该图G中所有顶点之间的最短路径的获取;

1.2 算法逻辑

在上述的过程中,我们不难发现,整个Floyd算法在执行的过程中,实际上就是在维护一个大小为 ∣ V ∣ × ∣ V ∣ |V| × |V| V×V 的二维数组,或者说是图G的邻接矩阵;

为了更加清晰的获取到各点之间的准确路径,我们还可以再增加一个记录路径的矩阵path[][],该矩阵的功能就是记录从点 V i V_i Vi 到点 V j V_j Vj 时途径的中转点,即最短路径中点 V j V_j Vj 的前驱顶点;

算法的整个执行过程,实际上就是在遍历图G的邻接矩阵,只不过我们需要遍历 ∣ V ∣ |V| V 次,每一次遍历都相当于将点 V k V_k Vk 作为中转点,去查找是否存在更短的路径;

算法的C语言实现如下所示:

void Floyd(AMGraph* g,int*** A,int*** path) {// 创建递推矩阵A与路径矩阵path*A = (int**)calloc(g->ver_num, sizeof(int*));assert(*A);*path = (int**)calloc(g->ver_num, sizeof(int*));assert(*path);for (int i = 0; i < g->ver_num; i++) {(*A)[i] = (int*)calloc(g->ver_num, sizeof(int));assert((*A)[i]);(*path)[i] = (int*)calloc(g->ver_num, sizeof(int));assert((*path)[i]);}// 初始阶段for (int i = 0; i < g->ver_num; i++) {for (int j = 0; j < g->ver_num; j++) {(*A)[i][j] = g->edge_matrix[i][j];// 路径存在,记录当前路径的前驱顶点if (i != j && (*A)[i][j] != INT_MAX) {(*path)[i][j] = i;}// 路径不存在,则初始化为-1else {(*path)[i][j] = -1;}}}// 递推阶段——以点K为中转点for (int k = 0; k < g->ver_num; k++) {// 遍历矩阵for (int i = 0; i < g->ver_num; i++) {for (int j = 0; j < g->ver_num; j++) {// 当前距离大于以点k为中转点的路径长度if ((*A)[i][k] != INT_MAX && (*A)[k][j] != INT_MAX && ((*A)[i][j] > (*A)[i][k] + (*A)[k][j])) {(*A)[i][j] = (*A)[i][k] + (*A)[k][j];	// 更新点i到点j的路径长度(*path)[i][j] = (*path)[k][j];			// 更新该路径上点j的前驱顶点信息}}}}
}

1.3 算法评价

该算法实现的方式其时间复杂度和空间复杂度分别为:

  • 时间复杂度: T ( N ) = O ( ∣ V ∣ 3 ) T(N) = O(|V|^3) T(N)=O(V3)
  • 空间复杂度: S ( N ) = O ( ∣ V ∣ 2 ) S(N) = O(|V|^2) S(N)=O(V2)

可以看到算法中最主要的时间消耗在于递推的过程:

  • 遍历一趟矩阵需要 O ( ∣ V ∣ 2 ) O(|V|^2) O(V2) 的时间复杂度
  • 总共需要遍历 ∣ V ∣ |V| V

而算法的主要空间消耗在于对递推矩阵 A[][] 和路径矩阵path[][]的空间上,为了完整的记录所有结点的信息,因此,这两个矩阵的大小均为 ∣ V ∣ 2 |V|^2 V2

1.4 算法限制

在上述的实现中,并不能完整的展示Floyd算法,主要原因是因为该算法无法处理负权值回路:

-9
2
5
a
b
c

在上图中,如果我们要求顶点b到顶点b的最短路径,显然我们每走一次路径 < b , c , a , b > <b, c, a, b> <b,c,a,b> 该带权路径长度就会-2,走的次数越多,该带权路径长度越小,在这种情况下,我们就无法通过Floyd算法正确的得到最短路径,因此我们还需要在算法中加入对负权环的判断:

	// 检测负权环for (int i = 0; i < g->ver_num; i++) {if ((*A)[i][i] < 0) {printf("该图中存在负权环");return;}}

我这里对负权环的处理是采取的打印提示的方式,当然也可以选择别的方式,只要能够对负权环进行一个正确的检测即可。

二、三种算法对比

现在我们已经介绍完了处理最短路径问题的三种算法:BFS、Dijkstra、Floyd,下面我们就从六个维度来对比一下这三个算法的区别:

BFSDijkstraFloyd
用途求单源最短路径求单源最短路径求各顶点之间的最短路径
无权图适用适用适用
带权图不适用适用适用
带负权值的图不适用不适用适用
带负权值回路的图不适用不适用不适用
时间复杂度 O ( ∣ V ∣ 2 ) O(|V|^2) O(V2) O ( ∣ V ∣ + ∣ E ∣ ) O(|V|+|E|) O(V+E) O ( ∣ V ∣ 2 ) O(|V|^2) O(V2) O ( ∣ E ∣ log ⁡ ∣ V ∣ ) O(|E|\log|V|) O(ElogV) O ( ∣ V ∣ 3 ) O(|V|^3) O(V3)

在实际的问题中,我们可以根据自己的需求,选择合适的算法来处理最短路径问题;

🌟结语

通过本文的探索,我们揭开了Floyd算法的神秘面纱:
🔹 三重循环的优雅暴力:以 O ( 丨 V 丨 3 ) O(丨V丨^3) O(V3) 时间复杂度征服全源最短路径问题
🔹 动态规划的智慧结晶:通过递推矩阵的巧妙迭代,层层解锁最优路径
🔹 负权图的破壁者:打破Dijkstra算法局限,轻松驾驭负权边(除负权环外)
🔹 双矩阵的完美协奏:A矩阵记录距离,path矩阵回溯路径,实现路径溯源

📚 下一篇预告
在图论的奇妙世界中,我们将迎来新的伙伴:
🔥 《有向无环图:表达式的终极优化引擎》

  • 揭秘如何用DAG实现表达式树的重构
  • 探索公共子表达式消除的图解法
  • 图解拓扑排序如何实现无环表达式优化
  • 直击编译器中表达式优化的核心技术!

如果本文助你攻克了最短路径难题:
👉 点击🌟关注 不迷路
💡 点亮❤️【赞】支持创作火花
🗂️ 加入⭐【收藏】构建知识图谱
🔄 举手之劳【转发】,让更多开发者突破算法迷雾

你对Floyd算法还有哪些疑问?欢迎在评论区✍️留下思考,我们一起探讨图论精髓!

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

宝塔面板集成阿里云 OSS 备份失败的解决方案

宝塔面板集成阿里云OSS备份失败的解决方案 一、问题背景 在使用宝塔面板配置阿里云OSS云存储备份功能时,用户遇到如下错误: Traceback (most recent call last):File "class/CloudStoraUpload.py", line 144, in __init__from alioss_main import OSSClient as ocFile "…

如何安全高效地维护CMS智能插件?

作为网站开发者或运维人员&#xff0c;你是否经历过这样的场景&#xff1a;满怀期待地点击了插件“更新”按钮&#xff0c;刷新页面后却看到一片刺眼的500错误&#xff1f;或发现网站加载速度从2秒骤降到10秒&#xff1f;智能插件为CMS系统&#xff08;如WordPress、Drupal、亿…

FastAPI如何用角色权限让Web应用安全又灵活?

title: FastAPI如何用角色权限让Web应用安全又灵活? date: 2025/06/13 05:46:55 updated: 2025/06/13 05:46:55 author: cmdragon excerpt: 基于角色的路由访问控制是Web应用中常见的安全控制模式,通过为用户分配特定角色来管理权限。FastAPI利用依赖注入系统实现权限控制…

利用 SpreadJS 优化表格渲染性能

引言 在当今的数据驱动时代&#xff0c;表格作为一种重要的数据展示和交互方式&#xff0c;广泛应用于各类 Web 应用中。然而&#xff0c;当表格数据量增大或操作复杂度提高时&#xff0c;渲染性能往往会成为一个关键问题。SpreadJS 作为一款功能强大的纯前端电子表格控件&…

状态检查常用SQL

使用MySQL自身命令获取数据库服务状态。 连接数 -- 最大使用连接数 show status like Max_used_connections; -- 系统配置的最大连接数 show global variables like %max_connections; -- 当前打开的连接数 show status like Threads_connected; 缓存 -- 未从缓冲池读取的次…

【Mac 上离线安装 ADB 工具】

✅ 一、步骤总览&#xff08;离线安装 ADB&#xff09; 下载 ADB 离线包&#xff08;zip 文件&#xff09;解压到一个固定位置&#xff08;比如 ~/adb&#xff09;配置环境变量验证安装是否成功 ✅ 二、步骤详情&#xff08;假设你已经下载好了 zip 文件&#xff09; &#x1…

什么是数据仓库的ETL

ETL详解&#xff1a;数据整合的核心技术 1. 什么是ETL&#xff1f; ETL&#xff08;Extract, Transform, Load&#xff09;是数据仓库和数据分析领域的核心数据处理流程&#xff0c;指从不同数据源**抽取&#xff08;Extract&#xff09;数据&#xff0c;经过清洗转换&#x…

数字ic后端设计从入门到精通8(含fusion compiler, tcl教学)ULVTLL、LVT、ULVT详解及应用

LVT vs ULVT vs ULVTLL:从PPA、成本的角度出发 比较维度LVTULVTULVTLL阈值电压(Vth)中等低极低但经过优化减少泄漏开关速度中等快略慢于ULVT但优于LVT驱动能力较低高较高,略低于ULVT漏电流较低高显著低于ULVT动态功耗中等低低静态功耗低高低面积小小略大(因需额外技术减少泄…

Jupyter notebook中的感叹号!魔法命令介绍

背景&#xff1a; 之前用过anaconda conda创建过虚拟环境&#xff0c;也用过venv虚拟环境&#xff0c;也搭建过Jupyter notebook环境&#xff0c;但是今天看到下列的代码&#xff0c;不清楚感叹号代表什么。 如&#xff1a; !python -m venv signlang_env 解答&#xff1a; &a…

mysql 数值函数 介绍

MySQL 提供了多种数值函数&#xff0c;用于处理和操作数值数据。以下是一些常见的 MySQL 数值函数的介绍和使用示例&#xff1a; 1. ABS() 功能&#xff1a;返回一个数值的绝对值。语法&#xff1a;ABS(number)示例&#xff1a; SELECT ABS(-5); -- 输出&#xff1a; 5 2. …

HBase 安装与简单操作指南

一、安装前准备 1. 系统要求 Java 1.8+Hadoop 2.x/3.x (已配置并运行,伪分布式或全分布式)SSH 免密登录配置完成确保系统主机名解析正确2. 下载 HBase 最新稳定版下载地址: wget https://downloads.apache.org/hbase/2.4.11/hbase-2.4.11-bin.tar.gz 二、安装步骤 1. 解…

OpenCV CUDA模块设备层-----用于CUDA 纹理内存(Texture Memory)的封装类cv::cudev::Texture

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 cv::cudev::Texture 是 OpenCV CUDA 模块&#xff08;opencv_cudaimgproc&#xff09;中用于 CUDA 纹理内存&#xff08;Texture Memory&#xf…

自主学习-《Self-Adapting Language Models》

代码&#xff1a; https://jyopari.github.io/posts/seal 拟人比喻&#xff1a; 学生把备考的东西&#xff0c;以自己的方式记成笔记精华&#xff0c;更有利于他的理解和记忆。 背景&#xff1a; Self-improving: 本文&#xff1a; 输入外界知识&#xff0c;LLM将其整理为笔记(…

马上行计划管理后端架构

小程序日活未破万低成本高可用及滚动发版实战。 小程序已经积累很多用户了&#xff0c;高可用及滚动发布已经提上日程。 日活未破万&#xff0c;选购多台多家云服务器或者自建机房搭建k8s(Kubernetes)&#xff0c;成本显然有点太高了。因此取了折中的办法本地和云端服务同时启…

C++---类和对象(上)

1.类的定义 1.1类定义格式 首先我们引入一个新的关键字-----class&#xff0c;class定义一个类。 定义方法 跟我们之前定义结构体非常的像 那我们来简单的看一个类的定义 我们C语言实现的时候&#xff0c;结构体和函数是分离的。但是现在不需要&#xff0c;我可以直接写 …

UE5.5构建iOS失败但没有显式错误信息的问题

报错信息如下 UnrealBuildTool failed. See log for more details. (/Users/somebody/Library/Logs/Unreal Engine/LocalBuildLogs/UBA-UnrealDemo-IOS-Shipping_2.txt) AutomationException: UnrealBuildTool failed. See log for more details. (/Users/somebody/Library/Lo…

浅谈 Unity XR:从混战到统一,OpenXR 的演进与现实困境

一.引言 在 XR&#xff08;扩展现实&#xff09;技术日渐普及的今天&#xff0c;Unity 已成为开发 VR、AR 和 MR 应用的主流平台。然而在这个生态蓬勃发展的背后&#xff0c;XR 的接口标准也经历了混乱到统一的演进过程。从早期的厂商割据&#xff0c;到 Unity 的初步抽象&…

Python基础教学:航天工程领域的精确计算和金融领域的精确计算,分别采用的小数保留位数的方法有哪些?有什么区别?-由Deepseek产生

在Python中处理航天工程和金融领域的精确计算时&#xff0c;虽然都强调精度&#xff0c;但因目标需求、误差容忍度和计算性质不同&#xff0c;其小数保留位数的方法和策略存在显著差异。以下是关键方法和区别分析&#xff1a; 一、航天工程领域 核心需求&#xff1a; 物理世界…

机器人玩具:成年人的心灵游乐场与未来前哨

当提及“机器人玩具 ”&#xff0c;许多人脑海中仍会浮现出孩童在游戏垫上摆弄塑料小人的画面。然而&#xff0c;时代已悄然转变——那些曾被视为童年专属的机械伙伴&#xff0c;如今正被越来越多的成年人郑重捧在手中。这不是一种幼稚的退行&#xff0c;而是一场关于创造力、情…

Spring Cloud LoadBalancer深度解析:官方负载均衡方案迁移指南与避坑实践

引言&#xff1a;为什么LoadBalancer正在取代Ribbon&#xff1f; “Ribbon已进入维护模式” —— Spring官方公告 当你的Spring Boot升级到3.x版本&#xff0c;Ribbon的依赖项将无法通过编译。作为Spring Cloud 官方钦定的替代方案&#xff0c;LoadBalancer凭借&#xff1a; ✅…