ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

Matlab实现Floyd算法:动态规划求解所有顶点对最短路径

Matlab实现Floyd算法:动态规划求解所有顶点对最短路径 1. 项目概述从“最短路径”到“全局洞察”在数据建模和算法实践中我们常常会遇到一类经典问题如何找到网络中任意两点之间的最短距离无论是城市间的交通规划、通信网络的路由选择还是社交网络中影响力的传播分析其核心都可以抽象为图论中的最短路径问题。对于这类问题Dijkstra算法因其高效而闻名但它有一个前提——要求图中所有边的权重为非负值。在实际场景中比如考虑带有“优惠”可视为负权重边的物流成本或是存在风险传导负相关的金融网络Dijkstra算法就束手无策了。这时我们需要一个更通用、更强大的工具这就是Floyd算法也称为Floyd-Warshall算法。Floyd算法的魅力在于其思想的简洁与力量的强大。它不局限于寻找单一源点到其他点的最短路径而是旨在一次性解决“所有顶点对”之间的最短路径问题。它的核心是一种基于动态规划的“中转”思想逐步考虑是否通过引入某个中间顶点k能够使得从i到j的路径变得更短在Matlab这样的矩阵实验室环境中实现Floyd算法更是相得益彰。Matlab强大的矩阵运算能力使得我们可以用极其简洁的代码清晰直观地演绎整个动态规划过程将抽象的图论模型转化为可计算、可可视化的矩阵操作。本文将深入探讨如何在Matlab中构建图论模型并实现Floyd算法。我不会仅仅停留在给出代码而是会拆解算法每一步背后的动态规划原理分享如何用Matlab矩阵来优雅地表示图邻接矩阵如何初始化距离矩阵和路径记录矩阵以及三重循环的每一个k、i、j究竟在做什么。更重要的是我会结合多年建模经验分享几个关键实操技巧如何高效处理不存在的边通常用Inf表示如何从最终的距离矩阵和路径矩阵中回溯出具体的最短路径序列以及在面对大规模稀疏图时如何对基本Floyd算法进行思考和优化。无论你是正在准备数学建模竞赛还是需要在科研或工程中解决网络优化问题这篇内容都将为你提供一个从理论到实践、可直接“抄作业”的完整指南。2. Floyd算法核心思想与动态规划拆解Floyd算法是一种典型的动态规划算法其目标是求解加权图中所有顶点对之间的最短路径。理解其动态规划思想是灵活运用和后续优化的基础。2.1 算法思想允许“中转”的松弛操作想象一下你要计算一个城市交通图中任意两个地点A和B的最短车程。最直接的方法是枚举所有可能路径但这在顶点数多时完全不现实。Floyd算法提供了一个系统化的“逐步改进”策略。它的核心思想是假设图中顶点编号为1, 2, ..., n。我们定义一个二维数组D即距离矩阵其中D(i, j)表示当前考虑下从顶点i到顶点j的“允许经过的中间顶点编号不大于k”的最短路径长度。注意这里的k是一个关键的阶段变量。算法从一个初始状态开始初始状态 (k0)不允许经过任何中间顶点。此时D(i, j)就是连接顶点i和j的边的权重。如果i和j不直接相连则D(i, j)为无穷大(Inf)对于每个顶点自身D(i, i) 0。这个初始矩阵就是图的邻接矩阵。然后算法进行n个阶段的“松弛”操作阶段k (k从1到n)在第k个阶段我们允许路径经过顶点k作为中转站。对于每一对顶点(i, j)我们检查这样一个问题“如果我从i先到k再从k到j这条新路径会不会比当前记录的从i到j的路径更短”用状态转移方程表示就是D_k(i, j) min( D_{k-1}(i, j), D_{k-1}(i, k) D_{k-1}(k, j) )其中D_k代表允许经过前k个顶点即顶点1, 2, ..., k作为中转时的最短距离估计。这个方程是动态规划的精华。D_{k-1}(i, j)是上一阶段已知的i到j的最短距离不经过k或已用更优方式经过其他点。D_{k-1}(i, k) D_{k-1}(k, j)则是尝试经过新引入的顶点k所构成的路径距离。通过取最小值我们确保了D_k(i, j)始终是当前阶段下的最优解。当k从1迭代到n后D_n(i, j)就意味着允许经过所有n个顶点作为中转后从i到j的最短路径长度。由于图中总共就n个顶点因此D_n就是最终的所有点对最短距离矩阵。2.2 为什么Floyd算法能处理负权重这是Floyd算法相比Dijkstra算法的一个显著优势。关键在于动态规划的状态定义和转移过程。只要图中不存在总和为负的环路即“负权环”Floyd算法就能给出正确的最短路径长度。原因在于对于包含负权边但不形成负权环的图任意两点间的最短路径仍然是简单路径不包含环因此其经过的顶点数不会超过n-1。Floyd算法的n个阶段迭代足以让这条路径上所有可能的顶点顺序作为“中转站”被考虑到。在迭代过程中即使某条边权重为负算法也会在相应的min()比较中将其纳入考量从而更新出更短的距离。注意负权环的检测。Floyd算法本身不能直接求解存在负权环的图因为最短路径长度可以无限小。但是算法运行完毕后我们可以通过检查最终的距离矩阵D的主对角线元素来间接判断。如果存在某个D(i, i) 0则说明图中存在一个经过顶点i的负权环。这是因为D(i, i)本应表示从i出发再回到i的最短距离在无环情况下应为0出现负数则意味着存在一个环路使得总权值为负。2.3 路径重建记录“前驱”或“后继”计算最短距离往往不够我们通常还需要知道具体是哪条路径。Floyd算法可以通过维护一个额外的路径矩阵Path矩阵来实现这一点。常见的路径记录方式有两种前驱矩阵Predecessor MatrixPP(i, j)表示在从i到j的当前最短路径上j的前一个顶点是什么。初始化时如果i和j直接相连则P(i, j) i否则P(i, j) 0或j表示无路径或直达。后继矩阵Successor MatrixNextNext(i, j)表示在从i到j的当前最短路径上从i出发后走到的第一个顶点是什么。初始化时如果i和j直接相连则Next(i, j) j否则Next(i, j) 0或Inf。在算法迭代过程中一旦发生距离更新即发现经过k更短我们就同步更新路径矩阵。如果使用后继矩阵Next更新规则为当D(i, k) D(k, j) D(i, j)时不仅更新距离同时令Next(i, j) Next(i, k)。这意味着从i到j的新最短路径第一步是走到从i到k的最短路径的第一步。路径回溯时使用后继矩阵非常直观要从i到j先看Next(i, j)假设是x然后看Next(x, j)依次类推直到到达j。使用前驱矩阵则需从终点反向回溯到起点。在Matlab中实现时我个人更倾向于使用后继矩阵Next因为其回溯逻辑与人的正向思维更一致代码也稍显简洁。3. Matlab实现Floyd算法的详细步骤与代码精讲在Matlab中实现Floyd算法关键在于利用矩阵运算思维来理解三重循环并高效地处理矩阵初始化与更新。下面我将分步拆解并提供可直接运行的代码块。3.1 图的表示邻接矩阵构建在Matlab中图最自然的表示方式就是邻接矩阵。对于一个有n个顶点的图我们创建一个n x n的矩阵WWeight。W(i, j)表示从顶点i到顶点j的有向边的权重。如果i和j之间没有直接相连的有向边则W(i, j) InfMatlab中用inf表示无穷大。对于所有iW(i, i) 0自己到自己的距离为0。对于无向图邻接矩阵是对称阵即W(i, j) W(j, i)。构建示例假设我们有一个4个顶点的有向图边及其权重如下(1-2:5), (1-3:Inf), (1-4:7), (2-3:1), (2-4:Inf), (3-1:2), (3-4:4), (4-2:3)。Inf表示无直接连接n 4; W inf(n); % 初始化全为Inf % 将对角线置零 for i 1:n W(i, i) 0; end % 填充已知边权 W(1,2)5; W(1,4)7; W(2,3)1; W(3,1)2; W(3,4)4; W(4,2)3; % 此时 W 就是我们的邻接矩阵 disp(邻接矩阵 W:); disp(W);3.2 算法核心三重循环的动态实现这是Floyd算法的本体。我们初始化距离矩阵D W路径后继矩阵Next。function [D, Path] floyd_algorithm(W) % FLOYD_ALGORITHM 使用Floyd算法计算所有顶点对最短路径 % 输入: W - n*n 邻接矩阵W(i,j)为边权无连接则为InfW(i,i)0 % 输出: D - n*n 最短距离矩阵D(i,j)为i到j的最短距离 % Path - n*n 路径后继矩阵Path(i,j)为i到j最短路径上i的后继顶点 n size(W, 1); D W; % 初始化距离矩阵 Path zeros(n); % 初始化路径矩阵 % 初始化Path矩阵如果i和j直接相连则Path(i,j)j否则为0 for i 1:n for j 1:n if i ~ j isfinite(W(i, j)) W(i, j) inf Path(i, j) j; else Path(i, j) 0; % 0 表示暂无路径或自身 end end end % Floyd算法核心三重循环 for k 1:n for i 1:n % 一个小优化如果D(i,k)已经是无穷大则i经k到任何点j都是无穷大无需内层循环 if D(i, k) inf continue; end for j 1:n % 动态规划状态转移 if D(i, k) D(k, j) D(i, j) D(i, j) D(i, k) D(k, j); % 更新路径i到j的新路径第一步是i到k路径的第一步 Path(i, j) Path(i, k); end end end % 可选在此处加入负权环检测如果发现D(i,i)0可报错或处理 end end代码精讲与注意事项Path矩阵初始化这里采用了后继矩阵的初始化方式。Path(i,j)j意味着从i到j是直接走的。Path(i,j)0是一个标志位表示在初始状态下没有直接路径或ij。在后续更新中Path(i,j)会被赋予一个有效的顶点编号1到n之间。三重循环的顺序for k1:n是最外层这是Floyd算法的标准形式必须严格遵守。它代表了动态规划的“阶段”。如果错把k放在内层算法逻辑就完全错误了。中间判断优化if D(i, k) inf这是一个重要的实用优化。如果从i到k的当前最短距离是无穷大那么试图通过k中转到达任何点j都不可能得到有限距离因此可以跳过对当前i的所有j的循环。这在图比较稀疏时能显著减少不必要的计算。路径更新Path(i, j) Path(i, k)这是理解路径记录的关键。当发现i-k-...-j比已知的i-...-j更短时新的最短路径从i出发的第一步必然和i-k的最短路径的第一步相同。因此我们用Path(i, k)来更新Path(i, j)。3.3 路径回溯从矩阵到具体节点序列计算出D和Path矩阵后我们需要一个函数来根据给定的起点s和终点t回溯出完整的最短路径节点序列。function path_seq reconstruct_path(Path, s, t) % RECONSTRUCT_PATH 根据Floyd算法生成的Path矩阵重建从s到t的最短路径 % 输入: Path - Floyd算法输出的后继矩阵 % s - 起点编号 % t - 终点编号 % 输出: path_seq - 从s到t的最短路径节点序列向量如果不可达则为空 if Path(s, t) 0 % Path(s,t)为0表示没有路径在初始化中st时也为0但距离为0 path_seq []; return; end path_seq [s]; % 路径序列从起点开始 current s; while current ~ t next_vertex Path(current, t); % 这里有一个关键点我们查找的是从current到t的后继 % 但更通用的做法是查找从current到t的后继即Path(current, t) % 然而在标准的基于后继矩阵的Floyd实现中Path(i,j)记录的是从i到j的最短路径上i的直接后继。 % 因此我们应该沿着Path(current, target)迭代其中target固定为t。 % 但注意我们的Path矩阵是在允许经过所有顶点后最终的状态。 % 更稳健的回溯方法是从s开始不断查找当前顶点到终点t的后继。 % 但这样可能不是最优的。标准做法是从s开始根据Path(s, t)找到第一个后继v1 % 然后根据Path(v1, t)找到下一个直到到达t。 % 然而我们的Path(i,j)存储的是从i到j的最短路径上i的直接后继。 % 因此正确的回溯循环应该是 next_hop Path(current, t); if next_hop 0 % 理论上在最终矩阵中如果D(s,t)为有限值Path(s,t)不应为0。 % 出现0说明可能没有路径或者代码有bug。 path_seq []; return; end path_seq [path_seq, next_hop]; current next_hop; end % 当current t时循环结束t已在序列末尾 end更清晰且正确的回溯方法上面的回溯函数逻辑可能有些绕。一个更清晰、更常用的方法是利用Path矩阵中存储的“直接后继”信息进行逐步向前推进function path_seq reconstruct_path_simple(Path, s, t) % 一个更简单清晰的后继矩阵回溯方法 if Path(s, t) 0 path_seq []; return; end path_seq s; current s; while current ~ t current Path(current, t); % 当前顶点到t的后继 path_seq [path_seq, current]; end end这个版本假设Path(i,j)在算法结束后如果i到j有路径则Path(i,j)的值就是i在这条最短路径上的下一个顶点。这个假设在标准的Floyd算法实现中是成立的。回溯时我们从s开始不断将Path(current, t)加入序列直到到达t。3.4 完整调用示例与结果验证让我们用一个完整的例子来测试上述代码。%% 主脚本Floyd算法完整示例 clear; clc; % 1. 定义图的邻接矩阵 (使用之前的示例) W [0, 5, inf, 7; inf, 0, 1, inf; 2, inf, 0, 4; inf, 3, inf, 0]; n size(W, 1); fprintf(顶点数 n %d\n, n); disp(邻接矩阵 W:); disp(W); % 2. 调用Floyd算法函数 [D, Path] floyd_algorithm(W); fprintf(\n--- Floyd算法结果 ---\n); disp(所有顶点对最短距离矩阵 D:); disp(D); disp(路径后继矩阵 Path:); disp(Path); % 3. 验证与路径回溯 fprintf(\n--- 最短路径回溯示例 ---\n); start 1; target 3; shortest_dist D(start, target); fprintf(从顶点 %d 到顶点 %d 的最短距离为: %.2f\n, start, target, shortest_dist); path_sequence reconstruct_path_simple(Path, start, target); if isempty(path_sequence) fprintf(顶点 %d 到顶点 %d 没有路径\n, start, target); else fprintf(最短路径序列为: ); fprintf(%d , path_sequence); fprintf(\n); % 手动验证路径长度 calc_dist 0; for idx 1:length(path_sequence)-1 i path_sequence(idx); j path_sequence(idx1); calc_dist calc_dist W(i, j); end fprintf(通过路径序列计算的权重和为: %.2f (应与D矩阵一致)\n, calc_dist); end % 4. 检查负权环通过主对角线 fprintf(\n--- 负权环检测 ---\n); has_negative_cycle false; for i 1:n if D(i, i) 0 fprintf(警告发现负权环顶点 %d 到自身的距离 D(%d,%d) %.2f 0\n, i, i, i, D(i,i)); has_negative_cycle true; end end if ~has_negative_cycle fprintf(未检测到负权环所有 D(i,i) 0。\n); end运行结果分析对于这个示例图D矩阵会计算出所有点对的最短距离。例如从顶点1到顶点3直接连接是Inf但通过路径1-2-3距离为516。我们的算法应该能正确计算出D(1,3)6并且Path(1,3)通过回溯能得到序列[1, 2, 3]。通过运行上述代码你可以验证这些结果。4. 性能分析、优化与Matlab实战技巧基本的Floyd算法时间复杂度为O(n³)空间复杂度为O(n²)用于存储D和Path矩阵。对于顶点数n很大的图例如上万计算会非常缓慢。但在数学建模或中小规模网络分析中n在几百到一两千它在Matlab中通常是可行的。4.1 算法复杂度与Matlab优化时间复杂度 O(n³)三重嵌套循环每层最多n次迭代共n³数量级的操作。这是该算法的主要瓶颈。空间复杂度 O(n²)需要存储两个n×n的矩阵。对于n1000双精度浮点数需要大约100010008Bytes*2 ≈ 16MB内存占用尚可n10000时则需要约1.6GB内存压力就很大了。在Matlab中的优化思路预分配数组我们的代码中D和Path在函数开始时已用zeros或直接赋值方式确定大小这符合Matlab的最佳实践避免了在循环中动态增长数组带来的巨大开销。向量化尝试Floyd算法的核心迭代D(i,j) min(D(i,j), D(i,k)D(k,j))理论上可以对固定的k用矩阵运算一次性更新所有i,j。例如for k 1:n % 利用广播机制D(:,k)是列向量D(k,:)是行向量 % 这里生成一个临时矩阵其(i,j)元素为 D(i,k)D(k,j) temp_dist D(:, k) D(k, :); % 这里利用了Matlab的隐式扩展R2016b以后 % 比较并更新 update_mask temp_dist D; D(update_mask) temp_dist(update_mask); % 路径更新需要更复杂的逻辑难以完全向量化通常仍需部分循环 end这种方法将内层的i和j循环向量化了可以大幅提升在Matlab中的运行速度尤其是对于中等规模的矩阵。但是路径矩阵Path的更新逻辑Path(i,j) Path(i,k)依赖于update_mask并且需要按元素操作这使得完全向量化变得复杂。一个折中方案是如果只关心最短距离而不关心具体路径可以只用向量化方式计算D矩阵。稀疏矩阵处理如果图是稀疏的边数远小于n²使用Matlab的sparse稀疏矩阵存储W、D可以节省大量内存。然而Floyd算法在迭代过程中D矩阵往往会逐渐变得稠密因为很多Inf会被更新为有限值所以优化效果有限。对于真正的大规模稀疏图更适合使用多次运行Dijkstra算法针对每个源点或Johnson算法。4.2 常见问题与调试技巧在实现和使用Floyd算法时你可能会遇到以下典型问题结果不正确距离矩阵D的值异常检查邻接矩阵W的初始化确保W(i,i)0不存在的边设置为Infinf。一个常见错误是将不存在的边设为0这会导致算法误以为存在一条权重为0的边从而严重干扰结果。检查三重循环的顺序最外层必须是for k 1:n。这是动态规划的阶段维度顺序错误会导致状态转移错误。检查更新条件确保是if D(i,k) D(k,j) D(i,j)而不是。使用可以保证在距离相等时路径矩阵不会被不必要的更新虽然对距离结果无影响但可能影响最终记录的路径尤其是在有多条等长最短路径时。路径回溯失败或序列错误检查Path矩阵初始化确保在初始化时对于直接相连的边(i,j)Path(i,j)正确设置为j。对于ij或不直接相连的可以设为0或i自身或一个特殊值。我们的代码中设为0并在回溯函数中以此判断无路径。验证Path更新逻辑在距离更新的同时必须同步更新Path矩阵。规则是Path(i,j) Path(i,k)。可以手动模拟一个简单图比如3个顶点在纸上演算每一步然后与程序输出对比。回溯函数逻辑确保回溯函数正确理解了Path矩阵的含义。如果Path是后继矩阵那么从s开始next Path(s, t)就是第一个后继然后next Path(next, t)直到next t。算法运行速度太慢应用向量化如前所述尝试对距离更新部分进行向量化。减少不必要的计算我们已经加入了if D(i,k) inf的跳过判断。对于稀疏图这个优化效果明显。使用更高效的算法如果n很大比如2000且只需要计算少量点对的最短路径考虑使用graph对象和shortestpath函数Matlab R2015b以后引入了图形处理工具箱其底层可能采用了更高效的算法。使用Profiler使用Matlab的profile工具查看代码热点针对性优化。处理负权环算法结束后务必检查距离矩阵D的主对角线。如果存在D(i,i) 0则说明存在包含顶点i的负权环。此时所有能到达该环且能从该环到达的顶点对之间的最短路径长度理论上都是负无穷可以无限绕环。我们的算法给出的D值在这种情况下可能没有意义或者只是迭代结束时的一个状态。在实际应用中检测到负权环通常意味着模型有问题或需要特殊处理。4.3 Matlab图形化展示可选为了让结果更直观我们可以用Matlab的绘图功能简单展示图和最短路径。%% 可视化示例 (需要根据图的坐标这里用随机位置示例) figure; hold on; title(网络图与最短路径示例); % 为顶点生成随机位置实际应用中应使用真实坐标或布局算法如force-directed pos rand(n, 2) * 10; % 1. 绘制所有边灰色 for i 1:n for j 1:n if isfinite(W(i, j)) W(i, j) 0 i ~ j plot([pos(i,1), pos(j,1)], [pos(i,2), pos(j,2)], Color, [0.7 0.7 0.7], LineStyle, --); end end end % 2. 绘制顶点 scatter(pos(:,1), pos(:,2), 100, b, filled); for i 1:n text(pos(i,1)0.1, pos(i,2)0.1, num2str(i), FontSize, 12, FontWeight, bold); end % 3. 高亮显示一条最短路径 (例如从1到3) if ~isempty(path_sequence) for idx 1:length(path_sequence)-1 i path_sequence(idx); j path_sequence(idx1); plot([pos(i,1), pos(j,1)], [pos(i,2), pos(j,2)], r, LineWidth, 2); end fprintf(图中红色高亮线显示了从顶点 %d 到顶点 %d 的最短路径。\n, start, target); end hold off; axis equal;这段代码会生成一个简单的图形界面将顶点画在平面上用灰色虚线表示所有原始边并用红色粗线高亮显示我们回溯出的最短路径。这在进行结果汇报或调试时非常有用。5. 在数学建模中的典型应用场景与扩展Floyd算法不仅仅是求最短路径其变体和思想在数学建模中有着广泛的应用。5.1 经典应用场景交通网络规划计算城市间最短行车时间或最低成本。W矩阵可以包含距离、时间、费用或综合成本。Floyd算法能一次性算出所有城市对的最优路线为全局调度、枢纽选址提供数据支持。通信网络路由在计算机网络中路由器需要知道到其他路由器的最短路径跳数或延迟。Floyd算法可以用于计算路由表虽然实际动态协议如OSPF使用更分布式的方法但原理相通。社交网络分析计算网络中任意两人之间的“距离”例如最短好友链长度即“六度空间”理论。此时的边权重通常为1每段关系。D矩阵就是图的距离矩阵其最大值图的直径和平均值平均路径长度是重要的网络特征。项目关键路径分析变形在计划评审技术PERT中可以将任务作为顶点任务依赖和持续时间作为边通过求最长路径关键路径来管理项目。通过将权重取负并确保图中无正权环Floyd算法可以用于求所有点对的最长路径但通常有更专门的算法如关键路径法CPM。可达性分析如果不关心距离只关心两点是否连通可以将权重设为1连通或Inf不连通。Floyd算法运行后D(i,j) Inf即表示i可达j。这实际上是计算了图的传递闭包。此时算法可以简化Warshall算法。5.2 算法扩展与变体最小环检测在Floyd算法迭代过程中当i j时D(i, k) D(k, j)实际上构成了一个经过顶点k的环i - ... - k - ... - i。在更新D(i, i)时记录其最小值即可找到包含顶点i的最小环。遍历所有i可找到全局最小环。“必经点”最短路径如果需要求从s到t且必须经过某个指定顶点集V_m的最短路径可以先运行Floyd算法得到全源最短距离D然后将其转化为一个新的完全图顶点集为{s, t} ∪ V_m边权为D(u,v)再在这个规模小得多的新图上求解旅行商问题TSP或使用动态规划。这是一种经典的“分层”或“缩点”思想。动态图更新如果图的结构边权发生微小变化增、删、改一条边重新运行O(n³)的Floyd算法代价高昂。有一些增量式算法可以更高效地更新最短距离矩阵但其逻辑比静态Floyd复杂得多。5.3 建模实战心得数据预处理是关键你的模型结果质量很大程度上取决于输入的邻接矩阵W。如何将实际问题中的“距离”量化为一个数值是物理距离、时间、费用还是综合评分是否需要考虑单向通行有向图这些都需要在建模初期仔细定义。理解Inf的含义Inf在Matlab中参与运算时需小心。Inf (-Inf)会得到NaN非数Inf Inf比较结果为假。在Floyd算法中我们主要使用Inf来表示“不可达”并利用min()函数和加法Inf 任何有限数 Inf的特性。确保你的初始化正确。路径信息很重要在很多建模问题中不仅需要知道最短距离是多少还需要知道具体路径是什么例如需要给出具体的运输路线。因此实现并正确维护Path矩阵是必不可少的步骤。在论文中展示一两条关键的最短路径序列比只放一个距离矩阵更有说服力。规模与效率权衡在建模比赛中如果顶点数n超过500纯Matlab实现的Floyd算法可能会成为时间瓶颈。此时需要考虑是否真的需要所有点对的最短路径如果只需要少量点对改用多次Dijkstra算法使用优先队列优化可能更快。或者是否可以简化模型对顶点进行聚合例如将相邻的多个小区合并为一个区域以减少n利用Matlab工具箱Matlab的graph和digraph对象以及相关的函数如shortestpath,distances已经高度优化并且支持多种算法自动选择。在正式建模中除非题目明确要求自己实现算法否则直接使用这些内置函数是更可靠、更高效的选择。自己实现Floyd的价值在于深入理解算法原理以及在需要高度定制化如记录路径、检测负环、进行特殊修改时使用。Floyd算法以其简洁统一的思想成为了图论模型中的一个基石。在Matlab中实现它不仅是一次编程练习更是对动态规划和矩阵运算的深刻体会。希望这篇详细的拆解能帮助你在下次遇到网络优化问题时能自信地拿起这个工具并清晰地知道每一步背后的原理与细节。
返回列表