用Dijkstra算法和Floyd算法求解最短路问题
题目1:Dijkstra算法的Matlab实现
用Dijkstra算法求下图中从顶点
v
1
v_1
v1到其余顶点的最短距离。
Matlab代码:
%% 第1题Dijkstra
% 输入带权邻接矩阵
D = [0 3 7 5 inf inf inf;
3 0 2 inf 6 inf inf;
7 2 0 3 3 inf inf;
5 inf 3 0 inf 2 8;
inf 6 3 inf 0 inf 2;
inf inf inf 2 inf 0 2;
inf inf inf 8 2 2 0];
% 输入最短路起始点
start_point = 1;
% 初始化已归入最短路径的顶点
S = [start_point];
% 初始化未归入最短路径的顶点
S_bar = 1:length(D); S_bar(start_point) = [];
% 初始化从start_point到其他各点的最短路径长和各点对应的父点集
L = cellmat(1,length(D),1,1,0); Z=L; Z{1}=1;
% 初始化算法步骤表
Tab = table(1, 0, inf, inf, inf, inf, inf, inf, ...
'VariableNames', {'Iter','V1','V2','V3','V4','V5','V6','V7'});
while ~isempty(S_bar)
t = cellmat(1,length(D),1,1,inf);
dist=inf; new_point=[]; father_point=[];
% 将S中所有点的邻点中求得路径最小的点归入S, 并保留其路径长和父点
for i = S
for j = S_bar
t1 = L{i}+D(i,j);
t{1,j} = min(t{1,j}, t1);
if t1<dist
dist = t1; new_point=j; father_point=i;
end
end
end
% 更新S, S_bar, L, Z, Tab
S = [S, new_point]; S_bar(S_bar==new_point)=[];
L{new_point} = dist;
Z{new_point} = father_point;
Tab(end+1, :) = [{Tab.Iter(end)+1},t];
end
disp(Tab)
disp([{'L(v)'},L])
disp([{'Z(v)'},Z])
结果:
Iter V1 V2 V3 V4 V5 V6 V7
____ ___ ___ ___ ___ ___ ___ ___
1 0 Inf Inf Inf Inf Inf Inf
2 Inf 3 7 5 Inf Inf Inf
3 Inf Inf 5 5 9 Inf Inf
4 Inf Inf 5 Inf 9 7 13
5 Inf Inf Inf Inf 8 7 13
6 Inf Inf Inf Inf 8 Inf 9
7 Inf Inf Inf Inf Inf Inf 9
'L(v)' [0] [3] [5] [5] [8] [7] [9]
'Z(v)' [1] [1] [2] [1] [3] [4] [6]
相应的最短路径图如下:
题目2:Floyd算法的Matlab实现(含路径矩阵的求解)
已知7个顶点之间的相互连接信息如表所示,用Floyd算法求出每对顶点之间的最短路径。
若视为无向图问题,则如图:
Matlab代码:
%% 无向图的带权邻接矩阵
D = [0 3 inf inf inf inf inf;
3 0 2 inf 18 2.5 inf;
inf 2 0 6 2 inf inf;
inf inf 6 0 3 inf inf;
inf 18 2 3 0 4 inf;
inf 2.5 inf inf 4 0 1.5;
inf inf inf inf inf 1.5 0];
R_iter=[];
for i=1:length(D)
R_iter = [R_iter;1:length(D)];
end
D_iter = D;
k = 1;
while k <= length(D)
D_new = D_iter;
for i=1:length(D)
for j=1:length(D)
t = D_iter(i,k)+D_iter(k,j);
if t < D_iter(i,j)
D_new(i,j) = t;
R_iter(i,j) = k;
end
end
end
D_iter = D_new;
k = k+1;
end
disp(['D(',num2str(k-1),')='])
disp(D_iter)
disp(['R(',num2str(k-1),')='])
disp(R_iter)
%% 打印出最短路径和相应的距离
for i=1:length(D)
for j=1:length(D)
dist = D_iter(i,j);
if R_iter(i,j) == j
path = [i,j];
else
k = R_iter(i,j);
path_1 = [k];
while R_iter(i,k) ~= k
k = R_iter(i,k);
path_1 = [k, path_1];
end
k = R_iter(i,j);
path_2 = [];
while R_iter(k,j) ~= j
k = R_iter(k,j);
path_2 = [path_2, k];
end
path = [i, path_1, path_2, j];
end
disp([num2str(i),'到',num2str(j),'的最短路为',...
num2str(path),' 长度为',num2str(dist)])
end
end
结果:
D(7)=
0 3.0000 5.0000 10.0000 7.0000 5.5000 7.0000
3.0000 0 2.0000 7.0000 4.0000 2.5000 4.0000
5.0000 2.0000 0 5.0000 2.0000 4.5000 6.0000
10.0000 7.0000 5.0000 0 3.0000 7.0000 8.5000
7.0000 4.0000 2.0000 3.0000 0 4.0000 5.5000
5.5000 2.5000 4.5000 7.0000 4.0000 0 1.5000
7.0000 4.0000 6.0000 8.5000 5.5000 1.5000 0
R(7)=
1 2 2 5 3 2 6
1 2 3 5 3 6 6
2 2 3 5 5 2 6
5 5 5 4 5 5 6
3 3 3 4 5 6 6
2 2 2 5 5 6 7
6 6 6 6 6 6 7
1到1的最短路为1 1 长度为0
1到2的最短路为1 2 长度为3
1到3的最短路为1 2 3 长度为5
1到4的最短路为1 2 3 5 4 长度为10
1到5的最短路为1 2 3 5 长度为7
1到6的最短路为1 2 6 长度为5.5
1到7的最短路为1 2 6 7 长度为7
2到1的最短路为2 1 长度为3
2到2的最短路为2 2 长度为0
2到3的最短路为2 3 长度为2
2到4的最短路为2 3 5 4 长度为7
2到5的最短路为2 3 5 长度为4
2到6的最短路为2 6 长度为2.5
2到7的最短路为2 6 7 长度为4
3到1的最短路为3 2 1 长度为5
3到2的最短路为3 2 长度为2
3到3的最短路为3 3 长度为0
3到4的最短路为3 5 4 长度为5
3到5的最短路为3 5 长度为2
3到6的最短路为3 2 6 长度为4.5
3到7的最短路为3 2 6 7 长度为6
4到1的最短路为4 5 3 2 1 长度为10
4到2的最短路为4 5 3 2 长度为7
4到3的最短路为4 5 3 长度为5
4到4的最短路为4 4 长度为0
4到5的最短路为4 5 长度为3
4到6的最短路为4 5 6 长度为7
4到7的最短路为4 5 6 7 长度为8.5
5到1的最短路为5 3 2 1 长度为7
5到2的最短路为5 3 2 长度为4
5到3的最短路为5 3 长度为2
5到4的最短路为5 4 长度为3
5到5的最短路为5 5 长度为0
5到6的最短路为5 6 长度为4
5到7的最短路为5 6 7 长度为5.5
6到1的最短路为6 2 1 长度为5.5
6到2的最短路为6 2 长度为2.5
6到3的最短路为6 2 3 长度为4.5
6到4的最短路为6 5 4 长度为7
6到5的最短路为6 5 长度为4
6到6的最短路为6 6 长度为0
6到7的最短路为6 7 长度为1.5
7到1的最短路为7 6 2 1 长度为7
7到2的最短路为7 6 2 长度为4
7到3的最短路为7 6 2 3 长度为6
7到4的最短路为7 6 5 4 长度为8.5
7到5的最短路为7 6 5 长度为5.5
7到6的最短路为7 6 长度为1.5
7到7的最短路为7 7 长度为0
若视为有向图问题,则如图:
Matlab代码:
%% 有向图的带权邻接矩阵
D = [0 3 inf inf inf inf inf;
inf 0 2 inf 18 2.5 inf;
inf inf 0 6 2 inf inf;
inf inf inf 0 3 inf inf;
inf inf inf inf 0 4 inf;
inf inf inf inf inf 0 1.5;
inf inf inf inf inf inf 0];
R_iter=[];
for i=1:length(D)
R_iter = [R_iter;1:length(D)];
end
D_iter = D;
k = 1;
while k <= length(D)
D_new = D_iter;
for i=1:length(D)
for j=1:length(D)
t = D_iter(i,k)+D_iter(k,j);
if t < D_iter(i,j)
D_new(i,j) = t;
R_iter(i,j) = k;
end
end
end
D_iter = D_new;
k = k+1;
end
disp(['D(',num2str(k-1),')='])
disp(D_iter)
disp(['R(',num2str(k-1),')='])
disp(R_iter)
%% 打印出最短路径和相应的距离
for i=1:length(D)
for j=1:length(D)
dist = D_iter(i,j);
if R_iter(i,j) == j
path = [i,j];
else
k = R_iter(i,j);
path_1 = [k];
while R_iter(i,k) ~= k
k = R_iter(i,k);
path_1 = [k, path_1];
end
k = R_iter(i,j);
path_2 = [];
while R_iter(k,j) ~= j
k = R_iter(k,j);
path_2 = [path_2, k];
end
path = [i, path_1, path_2, j];
end
disp([num2str(i),'到',num2str(j),'的最短路为',...
num2str(path),' 长度为',num2str(dist)])
end
end
结果:
D(7)=
0 3.0000 5.0000 11.0000 7.0000 5.5000 7.0000
Inf 0 2.0000 8.0000 4.0000 2.5000 4.0000
Inf Inf 0 6.0000 2.0000 6.0000 7.5000
Inf Inf Inf 0 3.0000 7.0000 8.5000
Inf Inf Inf Inf 0 4.0000 5.5000
Inf Inf Inf Inf Inf 0 1.5000
Inf Inf Inf Inf Inf Inf 0
R(7)=
1 2 2 3 3 2 6
1 2 3 3 3 6 6
1 2 3 4 5 5 6
1 2 3 4 5 5 6
1 2 3 4 5 6 6
1 2 3 4 5 6 7
1 2 3 4 5 6 7
1到1的最短路为1 1 长度为0
1到2的最短路为1 2 长度为3
1到3的最短路为1 2 3 长度为5
1到4的最短路为1 2 3 4 长度为11
1到5的最短路为1 2 3 5 长度为7
1到6的最短路为1 2 6 长度为5.5
1到7的最短路为1 2 6 7 长度为7
2到1的最短路为2 1 长度为Inf
2到2的最短路为2 2 长度为0
2到3的最短路为2 3 长度为2
2到4的最短路为2 3 4 长度为8
2到5的最短路为2 3 5 长度为4
2到6的最短路为2 6 长度为2.5
2到7的最短路为2 6 7 长度为4
3到1的最短路为3 1 长度为Inf
3到2的最短路为3 2 长度为Inf
3到3的最短路为3 3 长度为0
3到4的最短路为3 4 长度为6
3到5的最短路为3 5 长度为2
3到6的最短路为3 5 6 长度为6
3到7的最短路为3 5 6 7 长度为7.5
4到1的最短路为4 1 长度为Inf
4到2的最短路为4 2 长度为Inf
4到3的最短路为4 3 长度为Inf
4到4的最短路为4 4 长度为0
4到5的最短路为4 5 长度为3
4到6的最短路为4 5 6 长度为7
4到7的最短路为4 5 6 7 长度为8.5
5到1的最短路为5 1 长度为Inf
5到2的最短路为5 2 长度为Inf
5到3的最短路为5 3 长度为Inf
5到4的最短路为5 4 长度为Inf
5到5的最短路为5 5 长度为0
5到6的最短路为5 6 长度为4
5到7的最短路为5 6 7 长度为5.5
6到1的最短路为6 1 长度为Inf
6到2的最短路为6 2 长度为Inf
6到3的最短路为6 3 长度为Inf
6到4的最短路为6 4 长度为Inf
6到5的最短路为6 5 长度为Inf
6到6的最短路为6 6 长度为0
6到7的最短路为6 7 长度为1.5
7到1的最短路为7 1 长度为Inf
7到2的最短路为7 2 长度为Inf
7到3的最短路为7 3 长度为Inf
7到4的最短路为7 4 长度为Inf
7到5的最短路为7 5 长度为Inf
7到6的最短路为7 6 长度为Inf
7到7的最短路为7 7 长度为0