Dijkstra单源最短路径算法

一、算法原理

迪杰斯特拉算法(Dijkstra)是由荷兰计算机科学家狄克斯特拉于1959 年提出的,因此又叫狄克斯特拉算法。是从一个顶点到其余各顶点的最短路径算法,解决的是有权图中最短路径问题。迪杰斯特拉算法主要特点是从起始点开始,采用贪心算法的策略,每次遍历到始点距离最近且未访问过的顶点的邻接节点,直到扩展到终点为止
以下图为例,首先介绍Dijstra的原理。
在这里插入图片描述
红字为各结点的编号,黑字为各结点之间的距离。

  1. 首先定义几个变量:
    节点个数 n n n
    二维矩阵 W ( n × n ) W(n×n) W(n×n):距离(权值)矩阵。连通的结点间即为距离,不连通的结点间为正无穷( I n f Inf Inf),和自己的距离为0;
    一维矩阵 v i s i t ( 1 × n ) visit(1×n) visit(1×n):访问矩阵。若第 i i i个节点已找到最短路径,则 v i s i t ( i ) = 0 visit(i)=0 visit(i)=0,否则等于1,对于初始节点, v i s i t = 0 visit=0 visit=0
    距离矩阵 d ( 1 × n ) d(1×n) d(1×n):若第 i i i个节点已找到最短路径,则 d ( i ) d(i) d(i)为这条路径的距离,否则为0,初始节点 d = 0 d=0 d=0
    上一节点矩阵 p a t h ( 1 × n ) path(1×n) path(1×n):若第 i i i个节点找到了最短路径,则 p a t h path path存放这一条最短路径的前一个节点,通过对每一节点的回溯,可以找到最短路径。
  2. 根据距离写出以下距离矩阵 W = [ 0 6 3 i n f i n f i n f 6 0 2 5 i n f i n f 3 2 0 3 4 i n f i n f 5 3 0 2 3 i n f i n f 4 2 0 5 i n f i n f i n f 3 5 0 ] W=\begin{bmatrix} 0 & 6 & 3 & inf & inf & inf \\ 6 & 0 & 2 & 5 & inf & inf \\ 3 & 2 & 0 & 3 & 4 & inf \\ inf & 5 & 3 & 0 & 2 & 3 \\ inf & inf & 4 & 2 & 0 & 5 \\ inf & inf & inf & 3 & 5 & 0 \\ \end{bmatrix} W=063infinfinf6025infinf32034infinf53023infinf4205infinfinf350
  3. 确定初始点为 v 1 v_1 v1,则 v i s i t ( 1 ) = 0 visit(1)=0 visit(1)=0;
    在图中,结点上,我们将已找到最短路径的点标为它的最短距离,(可以理解为 v 1 v_1 v1点已找到最短路径,距离为0),未找到的其余点表为正无穷(即表示不连通)。
    这里写图片描述
    在与 v 1 v_1 v1连通的点中,即在矩阵 W W W的第1行,寻找最小值,最小值所在列即确定的最短路径的节点,此时 v 3 v_3 v3最短, v i s i t ( 3 ) = 0 visit(3)=0 visit(3)=0 d ( 3 ) = 3 d(3)=3 d(3)=3,对于已找到最短路径的 v 3 v_3 v3上一节点为 v 1 v_1 v1 p a t h ( 3 ) = 1 path(3)=1 path(3)=1
    在这里插入图片描述
    接着,在
    v 1 v_1 v1连通的,且未找到最短距离的节点的距离,以及
    v 3 v_3 v3连通的,且未找到最短距离节点的距离+ v 3 v_3 v3的最短距离
    以上两种中寻找最短距离,最短为 v 2 v_2 v2 v i s i t ( 2 ) = 0 visit(2)=0 visit(2)=0 d ( 2 ) = 5 d(2)=5 d(2)=5 p a t h ( 2 ) = 3 path(2)=3 path(2)=3
    在这里插入图片描述
    重复以上步骤,在
    v 1 v_1 v1连通的,且未找到最短距离的节点的距离
    v 3 v_3 v3连通的,且未找到最短距离节点的距离+ v 3 v_3 v3的最短距离
    v 2 v_2 v2连通的,且未找到最短距离节点的距离+ v 2 v_2 v2的最短距离
    以上三种中寻找最短路径,最短为 v 4 v_4 v4 v i s i t ( 4 ) = 1 visit(4)=1 visit(4)=1 d ( 4 ) = 6 d(4)=6 d(4)=6 p a t h ( 4 ) = 3 path(4)=3 path(4)=3
    这里写图片描述
    我们可以发现,所要寻找的最短路径即为对于已找到最短路径的点(包括初始结点),在与其连通的,未找到最短路径的结点中,将之间距离与圆圈中的距离(即上一结点已找到的最短路径)相加,求得的最小值。 如果有多个相同的最短距离,任取其中一个。 最终最短路径和距离如下图所示。
    在这里插入图片描述

二、MATLAB实现

dijkstra函数如下:

function [distance, path] = dijkstra(W, st, e)
%% dijkstra单源最短路径算法
% 输入:W  权值矩阵   st 搜索的起点   e 搜索的终点
% 输出:distance 路径距离  path  最短路径
n = length(W);          % 节点数
D = W(st, :);
visit = ones(1, n);
visit(st) = 0;          % 已访问  0;未访问  1
parent = zeros(1, n);   % 记录每个节点的上一个节点
path = [ ];
for i = 1:n-1
    temp = [ ];  
    % 从起点出发,找最短距离的下一个点,每次不会重复原来的轨迹,设置visit判断节点是否访问
    for j = 1:n
        if visit(j)
            temp = [temp, D(j)];
        else
            temp = [temp, inf];
        end
    end
    [value, index] = min(temp);
    visit(index) = 0; 
    % 更新:如果经过index节点,从起点到每个节点的路径长度更小,则更新,记录前驱节点,方便后面回溯循迹
    for k = 1:n
        if D(k) > D(index)+W(index, k)
            D(k) = D(index)+W(index, k);
            parent(k) = index;
        end
    end
end
distance = D(e);             % 最短距离
% 回溯法:从尾部往前寻找搜索路径
t = e;
while t ~= st && t > 0
    path =[t, path];
    p = parent(t);
    t = p;
end
path = [st, path];           % 最短路径

测试用例代码如下:

clear;clc;
% 权值表
W = [0 6 3 inf inf inf;
    6 0 2 5 inf inf;
    3 2 0 3 4 inf;
    inf 5 3 0 2 3;
    inf inf 4 2 0 5;
    inf inf inf 3 5 0];
[distance, path] = dijkstra(W, 1, 4)

Command Window中显示的结果为:

distance =

     6


path =

     1     3     4

三、参考文献

[1] 小东和小凤. 最短路径Dijkstra算法原理及Matlab实现. CSDN博客.
[2] 郝搞笑. 详解 Dijkstra算法以及实现. CSDN博客.

  • 4
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

心️升明月

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

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

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

打赏作者

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

抵扣说明:

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

余额充值