用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

11的最短路为1  1 长度为0
12的最短路为1  2 长度为3
13的最短路为1  2  3 长度为5
14的最短路为1  2  3  5  4 长度为10
15的最短路为1  2  3  5 长度为7
16的最短路为1  2  6 长度为5.5
17的最短路为1  2  6  7 长度为7
21的最短路为2  1 长度为3
22的最短路为2  2 长度为0
23的最短路为2  3 长度为2
24的最短路为2  3  5  4 长度为7
25的最短路为2  3  5 长度为4
26的最短路为2  6 长度为2.5
27的最短路为2  6  7 长度为4
31的最短路为3  2  1 长度为5
32的最短路为3  2 长度为2
33的最短路为3  3 长度为0
34的最短路为3  5  4 长度为5
35的最短路为3  5 长度为2
36的最短路为3  2  6 长度为4.5
37的最短路为3  2  6  7 长度为6
41的最短路为4  5  3  2  1 长度为10
42的最短路为4  5  3  2 长度为7
43的最短路为4  5  3 长度为5
44的最短路为4  4 长度为0
45的最短路为4  5 长度为3
46的最短路为4  5  6 长度为7
47的最短路为4  5  6  7 长度为8.5
51的最短路为5  3  2  1 长度为7
52的最短路为5  3  2 长度为4
53的最短路为5  3 长度为2
54的最短路为5  4 长度为3
55的最短路为5  5 长度为0
56的最短路为5  6 长度为4
57的最短路为5  6  7 长度为5.5
61的最短路为6  2  1 长度为5.5
62的最短路为6  2 长度为2.5
63的最短路为6  2  3 长度为4.5
64的最短路为6  5  4 长度为7
65的最短路为6  5 长度为4
66的最短路为6  6 长度为0
67的最短路为6  7 长度为1.5
71的最短路为7  6  2  1 长度为7
72的最短路为7  6  2 长度为4
73的最短路为7  6  2  3 长度为6
74的最短路为7  6  5  4 长度为8.5
75的最短路为7  6  5 长度为5.5
76的最短路为7  6 长度为1.5
77的最短路为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

11的最短路为1  1 长度为0
12的最短路为1  2 长度为3
13的最短路为1  2  3 长度为5
14的最短路为1  2  3  4 长度为11
15的最短路为1  2  3  5 长度为7
16的最短路为1  2  6 长度为5.5
17的最短路为1  2  6  7 长度为7
21的最短路为2  1 长度为Inf
22的最短路为2  2 长度为0
23的最短路为2  3 长度为2
24的最短路为2  3  4 长度为8
25的最短路为2  3  5 长度为4
26的最短路为2  6 长度为2.5
27的最短路为2  6  7 长度为4
31的最短路为3  1 长度为Inf
32的最短路为3  2 长度为Inf
33的最短路为3  3 长度为0
34的最短路为3  4 长度为6
35的最短路为3  5 长度为2
36的最短路为3  5  6 长度为6
37的最短路为3  5  6  7 长度为7.5
41的最短路为4  1 长度为Inf
42的最短路为4  2 长度为Inf
43的最短路为4  3 长度为Inf
44的最短路为4  4 长度为0
45的最短路为4  5 长度为3
46的最短路为4  5  6 长度为7
47的最短路为4  5  6  7 长度为8.5
51的最短路为5  1 长度为Inf
52的最短路为5  2 长度为Inf
53的最短路为5  3 长度为Inf
54的最短路为5  4 长度为Inf
55的最短路为5  5 长度为0
56的最短路为5  6 长度为4
57的最短路为5  6  7 长度为5.5
61的最短路为6  1 长度为Inf
62的最短路为6  2 长度为Inf
63的最短路为6  3 长度为Inf
64的最短路为6  4 长度为Inf
65的最短路为6  5 长度为Inf
66的最短路为6  6 长度为0
67的最短路为6  7 长度为1.5
71的最短路为7  1 长度为Inf
72的最短路为7  2 长度为Inf
73的最短路为7  3 长度为Inf
74的最短路为7  4 长度为Inf
75的最短路为7  5 长度为Inf
76的最短路为7  6 长度为Inf
77的最短路为7  7 长度为0
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

此账号已停更

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值