用matlab实现Dijkstra算法,内附函数详解

这篇具有很好参考价值的文章主要介绍了用matlab实现Dijkstra算法,内附函数详解。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

        学习数学建模清风大佬课程时,在图论章节中清风大佬留下了让我们手搓dijkstra算法的任务,笔者翻阅了CSDN和B站视频,再加上自己对代码和matlab的理解,手搓了一版dijkstra算法函数,代码如果有考虑不周,欢迎各位看官指出!!!

1.理论粗讲

        首先,还是来先了解一下dijkstra算法是啥。这个相信大家在点进来之前已经翻阅过相应资料了,毕竟已经到了手搓阶段。不了解的小伙伴们也不要急,我们先看看这个算法到底是个啥,手搓阶段的大佬们可以直接跳过,不过当作复现算法的参考也是不错的啦。

        dijkstra算法解决的是图论中的最短距离问题,从它的解决过程中,可以看到贪心算法的影子,就是只关心最短的距离(也就是程序中的最小值,在最小值所在节点的基础上,加上距离,然后循环往复,最终达到终点)

dijkstra算法matlab仿真,数学建模,数学建模,matlab,算法

        就如我们假设从零节点出发,很显然只有两条路,到1距离为4,到7距离为8,取最小也就是1节点,再在1节点基础上加距离,也就是到2距离为12(注意这个12是从起始点开始的距离),到7距离为7,再取最小也就是7再次加距离,依次循环后到达终点。

        这时我们不难看出,从上面这个例子,7这个节点有两个距离,一个8,一个7,不要忘了我们的目的是求最小距离,所有我们直接将7这个节点到初始点的距离由8更新到了7。看到这里了,不妨停下来品一品,是不是可以看出一些这个算法的奥秘?没错,这个算法是在不断循环中更新的,而且更新的距离,是当前节点到初始点的最短距离,也就是说,如果我们设置一个结束节点它满足在运算过程中能访问所有节点的话,所有节点到初始点的最短距离就可以求出来了!是不是很神奇!!!

2.代码前置内容

        好了,我们在之前浅浅讲了一下dijstra算法,那后面就是手搓阶段了。众所周知,学习了理论知识可不够,程序和理论之间可是还有差别滴。在手搓阶段,我参考了清风大佬和B站视频图论最短距离(Shortest Path)算法动画演示-Dijkstra和Floyd。让我们截取其中一帧画面来更好的讲述后续操作。

dijkstra算法matlab仿真,数学建模,数学建模,matlab,算法

可以看到这里定义了三个数组:

Visited:用于标志已访问数组,访问后的节点后续遍历是当然不能使用啦,已经是最小距离了,可不能乱加距离。访问后要屏蔽靠的就是这个数组。

Distance:顾名思义,用于标记最短距离

Parent:用来标记从起点开始,此节点的上一级节点是啥。可以看这张截屏的红线(忽略2~3节点的那条和7~6的那条),这条红线表示的就是0-4节点的最短距离,那我们从paraent的4号位置看起,4的上一级是5,5的上一级是2,以此类推,是不是串联起来了一条0-1-7-8-2-5-4的最短距离。

3.代码实现

ok!!那接下来进入function time!

本例题使用例子就是上图截屏中使用的图

D代表此图的权重邻接矩阵

dijkstra算法matlab仿真,数学建模,数学建模,matlab,算法

function [P1,d1] = Dijkstra(D,start,end_)
    % clear;clc
    % load D.mat
    % start = 9
    % end_ = 4
    n = size(D,1);                                                         %确定节点个数      
    Dis = zeros(2,n);                                                      %创建一个二维数组,第一行表示当前循环下节点序号,第二行表示对应距离
    %e.g:
    %以此次权重邻接矩阵第一次循环为例:
    %—————————————————————————————————————————————————
    %|  1    2    3    4    5    6    7    8    9    |
    %|———————————————————————————————————————————————|
    %|  4   inf  inf  inf  inf  inf   8   inf  inf   |
    %|———————————————————————————————————————————————|
    % Dis数组表示从9号节点出发,每个节点与之距离的数组(注意在循环内有另外的含义,在后续循环中有注释!)
    Dis(1,:) = [1:n];                                                      %这一行将Dis第一行设置成1到n的节点序号
    Dis(2,:) = inf;                                                        %这一行将Dis第二行设置成无限大小(初始化:因为后续要有比小操作,设置成inf不会对后续操作有影响)
    Visited = zeros(1,n);                                                  %Visited数组用来标记对应节点是否已访问
    Distance = inf(1,n);                                                   %这是记录距离的数组,与Dis的区别在循环中体现
    Parents = inf(1,n);                                                    %Parents数组用来标记对应节点父节点,也就是该节点与哪一个节点串联                                    
    k = [start];                                                           %k数组用于存放对应节点是否已访问
    % 初始化
    Visited(start) = 1;                                                    %将初始节点设置成已访问
    for i = 1:n                                                            %此循环为初始化循环,用于从初始点开始第一次遍历
        Distance(i) = D(start,i);                                          %之所以和大循环分开主要考虑了这句语句,由于此程序Distan数组设置成inf数组,所以若用大循环中的处理会导致第一次遍历无效
        Parents(i) = start
    end
    Dis(2,:) = Distance;                                                   %将变换后的Distance数组录入Dis数组第二行
    Dis(:,start) = []                                                      %删去已访问的节点(为什么要删去?因为我们之后操作要取最小距离,若不删去已访问节点,会干扰取值时的准确性)
    while Visited(end_) ~= 1
        [~,min_index] = min(Dis(2,:));                                    
        min_index = Dis(1,min_index);                                      %这句话就很好的体现了Dis数组第一行的作用,由于每次循环,Dis数组都会删去已访问节点,Dis数组第二行下标并不对应对应节点序号,第一行的目的就是为了存放最小距离对应节点序号
        Visited(min_index) = 1
        for i = 1:n
            if D(min_index,i) ~= inf && Visited(i) ~= 1                    %防止程序对已访问节点的距离做变更,D(min_index,i) ~= inf条件可省略
                    if D(min_index,i) + Distance(min_index) < Distance(i)  %判断距离大小
                        Distance(i) = D(min_index,i) + Distance(min_index);%若小于已有距离,更新Distance数组,并更新Parents数组
                        Parents(i) = min_index
                    end
            end
        end
        k = [k,Dis(1,find(Dis(1,:) == min_index,1))];                      %k的更新逻辑和Visited数组一样,已访问的节点存入k数组
        Dis = [[1:n];Distance];                                            %更新Dis数组,先更新距离,用重新赋值数组的方式
        Dis(:,k) = [];                                                     %再删除已访问的节点,防止对min操作产生影响
    end
    %输出  最短路径经过的节点 和 最短距离
    node = Parents(end_);
    P1 = [end_];
    while node ~= start
        P1 = [P1;node];
        node = Parents(node);
    end
    P1 = [P1;start];
    d1 = Distance(end_);
end

再在主函数调用一下,和matlab库函数compete一下

clear;clc
load D.mat

s = [9 9 1 1 2 2 2 7 7 6 6  5  5 4];
t = [1 7 7 2 8 3 5 8 6 8 5  3  4 3];
w = [4 8 3 8 2 7 4 1 6 6 2 14 10 9];
G = graph(s,t,w);
figure(1)
plot(G, 'EdgeLabel', G.Edges.Weight, 'linewidth', 2) 
set( gca, 'XTick', [], 'YTick', [] );  
[P,d] = shortestpath(G, 9, 4)  %注意:该函数matlab2015b之后才有哦

% 在图中高亮我们的最短路径
myplot = plot(G, 'EdgeLabel', G.Edges.Weight, 'linewidth', 2);  %首先将图赋给一个变量
highlight(myplot, P, 'EdgeColor', 'r')   %对这个变量即我们刚刚绘制的图形进行高亮处理(给边加上r红色)


%手搓的Dijkstra算法
figure(2)
plot(G, 'EdgeLabel', G.Edges.Weight, 'linewidth', 2) 
set( gca, 'XTick', [], 'YTick', [] );  
[P1,d1] = Dijkstra(D,9,4)
myplot = plot(G, 'EdgeLabel', G.Edges.Weight, 'linewidth', 2);  %首先将图赋给一个变量
highlight(myplot, P1, 'EdgeColor', 'r')   %对这个变量即我们刚刚绘制的图形进行高亮处理(给边加上r红色)

库函数效果:

dijkstra算法matlab仿真,数学建模,数学建模,matlab,算法

手搓函数效果:

dijkstra算法matlab仿真,数学建模,数学建模,matlab,算法文章来源地址https://www.toymoban.com/news/detail-767476.html

到了这里,关于用matlab实现Dijkstra算法,内附函数详解的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • MATLAB轻松绘制地图路线——Dijkstra(迪杰斯特拉)算法最短路径规划

    利用MATLAB绘制地图需要三个基本数据: 节点 节点坐标 节点间相通的路线 以11B交通巡警平台调度问题中的A区数据为例: (数据及工程文件下载链接见文末) Demo1: 可通过已知节点的坐标,计算出各节点之间的距离,有Matlab基础的同学可以尝试Demo2, 也可通过Excel自行实现;

    2023年04月21日
    浏览(38)
  • Dijkstra算法实现(java)

      Dijkstra(迪杰斯特拉)算法是求解单源最短路径的经典算法,其原理也是基于贪心策略的。   Dijkstra算法设置一个集合 S S S 记录已求得的最短路径的顶点,初始时把源点 v 0 v_{0} v 0 ​ 放入 S S S ,集合 S S S 每并入一个新顶点 v i v_{i} v i ​ ,都要修改源点 v 0 v_{0} v 0 ​

    2023年04月08日
    浏览(19)
  • 【最短路算法】一篇文章彻底弄懂Dijkstra算法|多图解+代码详解

    博主简介: 努力学习的大一在校计算机专业学生,热爱学习和创作。目前在学习和分享:算法、数据结构、Java等相关知识。 博主主页: @是瑶瑶子啦 所属专栏: 算法 ;该专栏专注于蓝桥杯和ACM等算法竞赛🔥 近期目标: 写好专栏的每一篇文章 Dijkstra算法适用于 最短路问题

    2023年04月08日
    浏览(31)
  • Dijkstra算法——邻接矩阵实现+路径记录

    本文是在下面这篇文章的基础上做了一些补充,增加了路径记录的功能。具体Dijkstra的实现过程可以参考下面的这篇文章。 [jarvan:Dijkstra算法详解 通俗易懂](Dijkstra算法详解 通俗易懂 - jarvan的文章 - 知乎 https://zhuanlan.zhihu.com/p/338414118) 创建 GraphAdjMat 类 GraphAdjMat 类用来实现图的

    2024年01月18日
    浏览(31)
  • 自动驾驶算法(一):Dijkstra算法讲解与代码实现

    目录 0 本节:栅格地图、算法、路径规划 1 Dijkstra算法详解 2 Dijkstra代码详解         用于图中寻找最短路径。节点是地点,边是权重。         从起点开始逐步扩展,每一步为一个节点找到最短路径:         While True:                 1.从未访问的节

    2024年02月06日
    浏览(32)
  • 图搜索算法详解 - DFS、BFS、Bellman-Ford、Dijkstra

    图搜索算法是许多应用程序的基础,例如社交网络分析、路径规划、数据挖掘和推荐系统。在本文中,我们将深入探讨图搜索算法的世界,探索它们的定义、重要性和实际应用。 图搜索算法是一种用于遍历图的技术,图是由 关系 连接的 节点集合 。在社交网络、网页或生物

    2024年02月16日
    浏览(32)
  • 详解图的最短路径算法(BFS、Dijkstra、Floyd)(附上图解步骤)

    最短路径分为两种: (1)单源路径:从某顶点出发,到其他全部顶点的最短路径 (2)顶点间的最短路径:任意两个顶点之间的最短路径 最短路径的结果主要有两个方面: (1)顶点之间最短路径的长度 (2)从源顶点到目标顶点的路径 只有边权为 1 时才能用BFS求最短路。

    2024年02月05日
    浏览(38)
  • 基于Dijkstra算法实现无人机三维路径规划

    基于Dijkstra算法实现无人机三维路径规划 无人机在飞行任务中往往需要寻找一条最优路径以达到最佳的飞行效果。而在三维空间中,路径规划问题变得更加复杂。本文将介绍如何基于Dijkstra算法来解决无人机三维路径规划问题,并且提供相应的matlab代码。 一、Dijkstra算法简介

    2024年02月14日
    浏览(43)
  • 【路径规划】全局路径规划算法——Dijkstra算法(含python实现 | c++实现)

    路径规划与轨迹跟踪系列算法学习 最短路径算法-迪杰斯特拉(Dijkstra)算法 迪杰斯特拉dijkstra算法的python实现 Python实现迪杰斯特拉算法 迪杰斯特拉算法(Dijkstra)是由荷兰计算机科学家狄克斯特拉于1959 年提出的,因此又叫狄克斯特拉算法。是从一个节点遍历其余各节点的最短路

    2024年02月08日
    浏览(33)
  • java实现迪杰斯特拉(Dijkstra)算法求解最短路问题

    迪杰斯特拉(Dijkstra)算法是由荷兰计算机科学家狄克斯特拉于1959年提出的。是寻找从一个顶点到其余各顶点的最短路径算法,可用来解决最短路径问题。 迪杰斯特拉算法采用贪心算法的策略,将所有顶点分为已标记点和未标记点两个集合,从起始点开始,不断在未标记点中寻

    2024年02月12日
    浏览(33)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包