最短路径Dijkstra算法的Matlab代码实现

本文深入解析Dijkstra算法原理,详细阐述算法步骤,并提供Matlab代码实现,通过实例验证算法有效性,同时对比Matlab自带函数,展示算法优势。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 说明:

2024年11月6日更新代码

主要修改:

  1. 增加了对输入参数的判断
  2. 简化了部分变量的大小
  3. 明确了数据的使用范围
  4. 增加了对输入邻接矩阵的连通性判断
  5. 扩展节点遇到多个距离相同的节点时,只选择其中编号最小的节点
% 文件名:dijkstra.m
% 时间:2024年11月06日
% 来源:https://blog.csdn.net/lishan132/article/details/108527271
% 功能:利用dijkstra算法计算两点间的最短路径
% dist:起点与终点之间的最短距离值
% path:最短路径索引
% Dist:最短路径下的距离值
% A:邻接矩阵
% strat:起点编号
% dest:终点编号
%{
连通邻接矩阵测试数据
A = [0,12,inf,inf,inf,16,14;
    12,0,10,inf,inf,7,inf;
    inf,10,0,3,5,6,inf;
    inf,inf,3,0,4,inf,inf;
    inf,inf,5,4,0,2,8;
    16,7,6,inf,2,0,9;
    14,inf,inf,inf,8,9,0];

不连通邻接矩阵测试数据
A = [0,1,inf,inf,inf;
    1,0,1,inf,inf;
    inf,1,0,inf,inf;
    inf,inf,inf,0,1;
    inf,inf,inf,1,0];

start = 1;
dest = 4;
[dist, path, Distance] = dijkstra(A, start, dest);
%}
function [dist, path, Dist] = dijkstra(A, start, dest)
if size(A, 1) <= 1
    error('邻接矩阵A至少需要两个节点构成');
end

if start == dest
    error('起点和终点重合了');
end

if size(A, 1) ~= size(A, 2)
    error('邻接矩阵A的行列数不一致');
end

if (start < 1 || start > size(A, 1))
    error('起点start超出了节点范围');
end

if (start ~= round(start))
    error('起点start不是整数');
end

if (dest < 1 || dest > size(A, 1))
    error('终点dest超出了节点范围');
end

if (dest ~= round(dest))
    error('终点dest不是整数');
end

for i = 1:size(A, 1)
    for j = 1:size(A, 1) - i + 1
        if A(i, j) < 0
            error('邻接矩阵A中的权应该为非负值');
        end
        if A(i, j) ~= A(j, i)
            error('邻接矩阵A不是对称矩阵');
        end
    end
end

m = (1);
n = 1:size(A, 1);
while size(m, 1) < size(A, 1)
    idx = A(m(end), n) > 0 & A(m(end), n) < inf;
    idx(1, m) = 0;
    if sum(idx) > 0
        m = [m, n(1, find(idx > 0, 1))];
    else
        warning('输入的邻接矩阵不连通,请确认以下两部分节点的连接情况\n')
        disp(m)
        disp(setdiff(n, m))
        break
    end
end
 
% 计算程序运行时间
tic  %开始计时
 
% 初始化操作
p = size(A, 1);                %计算顶点数目 
S = (dest);                    %初始化集合S, 已加入到路径中的顶点编号
U = setdiff(1:p, S);           %初始化集合U, 未加入到路径中的顶点编号
Dist(1, 1:p) = A(dest, 1:p);   %初始化所有顶点到终点dest的距离
D(1, 1:p) = Dist(1, 1:p);      %初始化所有顶点到当前顶点再到终点dest的距离
path(1, 1:p) = 0;              %初始化最短路径节点连接记录表
path(1, D~=inf) = dest;        %距离值不为无穷大时,将两顶点相连
 
% 寻找最短路径
while ~isempty(U)  %判断U中元素是否为空
    D(1, S) = inf;                    %忽略已处理顶点的距离值
    if all(isinf(D))
        break;
    end

    k = find(D(1:p) == min(D(1:p)), 1);  %剩余顶点中距离终点最近的顶点编号
    
    %更新顶点
    S = [S, k];              %将顶点k添加到S中
    U(U == k(1)) = [];       %从U中删除顶点k  
    
    %计算距离
    D(1, 1:p) = A(k, 1:p) + D(1, k);    %先通过结点k,再到终点的距离值
    D(1, 1:p) = min(D(1, 1:p), Dist(1, 1:p));  %取最小距离
   
    %更新路径
    path(1, D(1, 1:p) ~= Dist(1, 1:p)) = k;  %更改连接关系,连接到结点k上 
    
    %更新距离
    Dist(1, 1:p) = D(1, 1:p);  %更新距离表为所有点到终点的最小值
end
dist = Dist(1, start);  %取出指定起点到终点的距离值
toc %计时结束
 
% 输出结果
flag = 0;
fprintf('找到的最短路径为:')
while start ~= dest    %到达终点时结束
    next = path(1, start);    %与当前点相连的下一顶点
    if (next ~= 0)
        fprintf('%d-->', start);  %打印当前点编号
        start = next;            %更新当前点
    else
        flag = 1;
        break;
    end
end

if (flag ~= 0)
    fprintf('没有找到想要的最短路径\n')
else
    fprintf('%d\n', dest)
    fprintf('最短路径对应的距离为:%d\n', dist)
end

前言

Dijkstra是一种用于计算最短路径的常用算法,由荷兰科学家Dijkstra在1956年提出

该算法主要适用于单源非负权边的无向图,其中:

(1)单源表示只有一个源节点,然后计算其它所有节点到该源节点的最短路径和距离

(2)非负权表示两个节点之间的权重是非负数

(3)无向表示节点之间没有方向的区别,从节点A到节点B与从节点B到A的权重值相同

求解示例

假如有A、

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

乐观的lishan

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

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

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

打赏作者

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

抵扣说明:

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

余额充值