图论:迪克斯特求解最短路径算法及MATLAB实现

18 篇文章 25 订阅

1. 按

Dijkstra算法用于求解一个顶点到另一顶点的最短路径,它采用了非暴力的贪心思想,因此时间复杂度较低,为O(N^2)。
Dijkstra算法是一种贪心算法,每一次都求最短路径,但与常见的贪心算法不同的是,Dijkstra算法是一种步步为营的贪心算法,因此能求解一个顶点到另一个顶点的最短路径。

2. 算法讲解

2.1. 理论讲解

  1. 约定AimedPathNodes为所要求解的从某一目标点HeadNode(为了便于理解,将此节点约定为HeadNode,即头结点,目标路径上开头的那个节点)到另一目标点TrailNode(为了便于理解,将此节点约定为TrailNode,即尾结点,目标路径上结尾的那个节点)的最短的目标路径。
  2. 目标路径是由多个点组成的,刚开始时目标路径AimedPathNodes仅包含起始点HeadNode
  3. 找出当前目标路径(AimedPathNodes)的最近的邻接点并将其加入到AimedPathNodes中,随后再次找出AimedPathNodes的最近邻接点,并将其加入到AimedPathNodes中,这样一直下去,直到AimedPathNodes包含结尾的那个点(TrailNode)为止。

2.2. 实例讲解

2.2.1. 初始化

给每个点进行编号v1、v2 … v11,这里的v是vertex的缩写,是点的意思,因此v1是点1的意思。
给每条边初始化一个权重,权重用数字表示,如下图中v1与v2两点间的边的权重为2。
此例用于求解v1到v11两点间的最短路径。
约定AimedPathNodes为一个存储目标路径上所有点的变量。
在这里插入图片描述

2.2.2. 执行算法

  1. 刚开始时AimedPathNodes仅包含v1
    在这里插入图片描述
  2. 此时AimedPathNodesv1
    AimedPathNodes最近的邻接点,即找v1的最近的邻接点。
    v1相邻的点为v2、v3、v4,因此v1的邻接点为v2、v3、v4
    其中v1v2的边权重位2v1v3的边权重位8v1v4的边权重位1
    易得:v1的最近邻接点为v4
    v4加入到AimedPathNodes
    在这里插入图片描述
  3. 此时AimedPathNodesv1, v4
    AimedPathNodes的最近邻接点,即先找出v1的不包含AimedPathNodes上的点的最短邻接点v2,再找出v4的不包含AimedPathNodes上的点的最近邻接点v3
    由于v1v2的距离为2v4v3的距离为7,因此v2为到此时AimedPathNodes的最近点,将v2加入到AimedPathNodes
    在这里插入图片描述
  4. 此时AimedPathNodesv1, v4, v2
    易得AimedPathNodes的最近邻接点为v5,将v5加入到AimedPathNodes
    在这里插入图片描述
  5. 此时AimedPathNodesv1, v4, v2, v5
    易得AimedPathNodes的最近邻接点为v8
    在这里插入图片描述
  6. 此时AimedPathNodesv1, v4, v2, v5, v8
    AimedPathNodes的最近邻接点为v6
    在这里插入图片描述
  7. 此时AimedPathNodesv1, v4, v2, v5, v8, v6
    AimedPathNodes的最近邻接点为v3
    在这里插入图片描述
  8. 此时AimedPathNodesv1, v4, v2, v5, v8, v6, v3
    AimedPathNodes的最近邻接点为v7
    在这里插入图片描述
  9. 此时AimedPathNodesv1, v4, v2, v5, v8, v6, v3, v7
    AimedPathNodes的最近邻接点为v10
    在这里插入图片描述
  10. 此时AimedPathNodesv1, v4, v2, v5, v8, v6, v3, v7, v10
    AimedPathNodes的最近邻接点为v9
    在这里插入图片描述
  11. 此时AimedPathNodesv1, v4, v2, v5, v8, v6, v3, v7, v10, v9
    AimedPathNodes的最近邻接点为v11
    在这里插入图片描述
  12. 停止找最近的邻接点。实际求解最短路径时,除了上面的之外,还要再声明一个变量用于存储最短路径,并且每一步还有一个对该变量进行退栈和入栈的操作。
    在这里插入图片描述

3. matlab实现

dijkstra.m

function [min,path]=dijkstra(w,start,terminal)
    n=size(w,1); label(start)=0; f(start)=start;
    for i=1:n
       if i~=start
           label(i)=inf;
    end, end
    s(1)=start; u=start;
    while length(s)<n
       for i=1:n
          ins=0;
          for j=1:length(s)
             if i==s(j)
                ins=1;
             end,  
          end
          if ins==0
             v=i;
             if label(v)>(label(u)+w(u,v))
                label(v)=(label(u)+w(u,v)); 
             f(v)=u;
             end, 
          end, 
       end   
    v1=0;
       k=inf;
       for i=1:n
             ins=0;
             for j=1:length(s)
                if i==s(j)
                   ins=1;
                end, 
             end
             if ins==0
                v=i;
                if k>label(v)
                   k=label(v);  v1=v;
                end,  
             end,  
       end
       s(length(s)+1)=v1;  
       u=v1;
    end
    min=label(terminal); path(1)=terminal;
    i=1; 
    while path(i)~=start
          path(i+1)=f(path(i));
          i=i+1 ;
    end
    path(i)=start;
    L=length(path);
    path=path(L:-1:1);

4. 测试

4.1. 测试一

  • 代码
    weight=[0     2     8     1   Inf   Inf   Inf   Inf   Inf   Inf   Inf;
         2     0     6   Inf     1   Inf   Inf   Inf   Inf   Inf   Inf;
         8     6     0     7     5     1     2   Inf   Inf   Inf   Inf;
         1   Inf     7     0   Inf   Inf     9   Inf   Inf   Inf   Inf;
       Inf     1     5   Inf     0     3   Inf     2     9   Inf   Inf;
       Inf   Inf     1   Inf     3     0     4   Inf     6   Inf   Inf;
       Inf   Inf     2     9   Inf     4     0   Inf     3     1   Inf;
       Inf   Inf   Inf   Inf     2   Inf   Inf     0     7   Inf     9;
       Inf   Inf   Inf   Inf     9     6     3     7     0     1     2;
       Inf   Inf   Inf   Inf   Inf   Inf     1   Inf     1     0     4;
       Inf   Inf   Inf   Inf   Inf   Inf   Inf     9     2     4     0;]
    [dis, path]=dijkstra(weight,1, 11)
    

  • 在这里插入图片描述
  • 结果
    dis = 13
    path = 1 2 5 6 3 7 10 9 11

4.2. 测试二

  • 代码
    weight=[0     8   Inf   Inf   Inf   Inf     7     8   Inf   Inf   Inf;
       Inf     0     3   Inf   Inf   Inf   Inf   Inf   Inf   Inf   Inf;
       Inf   Inf     0     5     6   Inf     5   Inf   Inf   Inf   Inf;
       Inf   Inf   Inf     0     1   Inf   Inf   Inf   Inf   Inf    12;
       Inf   Inf     6   Inf     0     2   Inf   Inf   Inf   Inf    10;
       Inf   Inf   Inf   Inf     2     0     9   Inf     3   Inf   Inf;
       Inf   Inf   Inf   Inf   Inf     9     0   Inf   Inf   Inf   Inf;
         8   Inf   Inf   Inf   Inf   Inf   Inf     0     9   Inf   Inf;
       Inf   Inf   Inf   Inf     7   Inf   Inf     9     0     2   Inf;
       Inf   Inf   Inf   Inf   Inf   Inf   Inf   Inf     2     0     2;
       Inf   Inf   Inf   Inf    10   Inf   Inf   Inf   Inf   Inf     0;];
    [dis, path]=dijkstra(weight,1, 11)
    

  • 在这里插入图片描述
  • 结果
    dis = 21
    path = 1 8 9 10 11
  • 10
    点赞
  • 56
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 7
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

COCO56(徐可可)

建议微信红包:xucoco56

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

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

打赏作者

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

抵扣说明:

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

余额充值