图论与最短路在数学建模中的应用
一、图论模型
-
图 G=(V,E)G=(V,E)G=(V,E)
- VVV:顶点集合
- EEE:边集合
-
每条边 (u,v)(u,v)(u,v) 赋予权值 w(u,v)w(u,v)w(u,v),可用 邻接矩阵 或 邻接表 表示。
二、最短路问题的数学形式
目标 :寻找从源点 sss 到目标点 ttt 的路径 PPP,使得路径权值和最小。
d(s,t)=minP∈P(s,t)∑(u,v)∈Pw(u,v) d(s,t) = \min_{P \in \mathcal{P}(s,t)} \sum_{(u,v)\in P} w(u,v) d(s,t)=P∈P(s,t)min(u,v)∈P∑w(u,v)
其中:
- P(s,t)\mathcal{P}(s,t)P(s,t):所有从 sss 到 ttt 的可行路径集合
- w(u,v)w(u,v)w(u,v):边的权值
三、最短路算法
-
Dijkstra 算法
- 适用于 非负权图
- 贪心策略:逐步扩展源点集合,选取最近节点
-
Bellman-Ford 算法
-
允许 负权边
-
动态规划思想:
dk(v)=min{dk−1(v),min(u,v)∈E(dk−1(u)+w(u,v))} d_k(v) = \min\{ d_{k-1}(v), \min_{(u,v)\in E} (d_{k-1}(u)+w(u,v)) \} dk(v)=min{dk−1(v),(u,v)∈Emin(dk−1(u)+w(u,v))}
-
可检测负环
-
-
Floyd-Warshall 算法
-
适合 全源最短路
-
递推公式:
d(k)(i,j)=min(d(k−1)(i,j), d(k−1)(i,k)+d(k−1)(k,j)) d^{(k)}(i,j) = \min\big( d^{(k-1)}(i,j),\ d^{(k-1)}(i,k)+d^{(k-1)}(k,j) \big) d(k)(i,j)=min(d(k−1)(i,j), d(k−1)(i,k)+d(k−1)(k,j))
-
四、MATLAB 实现
1. Dijkstra 算法
matlab
INF = 1e9;
G = [0 4 2 INF INF;
4 0 1 5 INF;
2 1 0 8 10;
INF 5 8 0 2;
INF INF 10 2 0];
n = size(G,1);
start = 1;
dist = ones(1,n)*INF;
visited = zeros(1,n);
dist(start) = 0;
for i = 1:n
[~, u] = min(dist + visited*INF);
visited(u) = 1;
for v = 1:n
if ~visited(v) && dist(u)+G(u,v) < dist(v)
dist(v) = dist(u)+G(u,v);
end
end
end
disp('Dijkstra: 起点到各点的最短距离:');
disp(dist);
2. Bellman-Ford 算法
matlab
INF = 1e9;
edges = [1 2 4;
1 3 2;
2 3 1;
2 4 5;
3 2 1;
3 4 8;
3 5 10;
4 5 2];
n = 5; % 节点数
m = size(edges,1);
start = 1;
dist = ones(1,n)*INF;
dist(start) = 0;
% 松弛操作 n-1 次
for k = 1:n-1
for i = 1:m
u = edges(i,1);
v = edges(i,2);
w = edges(i,3);
if dist(u) + w < dist(v)
dist(v) = dist(u) + w;
end
end
end
% 检测负环
hasNegativeCycle = false;
for i = 1:m
u = edges(i,1);
v = edges(i,2);
w = edges(i,3);
if dist(u) + w < dist(v)
hasNegativeCycle = true;
end
end
disp('Bellman-Ford: 起点到各点的最短距离:');
disp(dist);
if hasNegativeCycle
disp('图中存在负权回路!');
end
3. Floyd-Warshall 算法
matlab
INF = 1e9;
G = [0 4 2 INF INF;
4 0 1 5 INF;
2 1 0 8 10;
INF 5 8 0 2;
INF INF 10 2 0];
n = size(G,1);
for k = 1:n
for i = 1:n
for j = 1:n
if G(i,k)+G(k,j) < G(i,j)
G(i,j) = G(i,k)+G(k,j);
end
end
end
end
disp('Floyd-Warshall: 所有点对最短路径矩阵:');
disp(G);
五、总结
-
建模方法:用图表示系统,用边权表示代价
-
最短路问题目标:找到权和最小路径
-
算法选择:
- 单源非负权:Dijkstra
- 单源含负权:Bellman-Ford
- 全源最短路:Floyd-Warshall