最短路径 Dijkstra算法的Matlab代码实现
为了搞清楚最短路径的算法过程,自己编写代码实现dijkstra算法寻找路径
% 文件名:dijkstra.m
% 时间:2020年9月12日
% 来源:https://blog.csdn.net/lishan132/article/details/108527271
% 功能:利用dijkstra算法计算两点间的最短路径
% dist:起点与终点之间的最短距离值
% path:最短路径索引
% Distance:最短路径下的距离值
% A:邻接矩阵
% strat:起点编号
% dest:终点编号
function [dist,path,Distance] = dijkstra(A,start,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];
% 测试数据 start = 1;
% 测试数据 dest = 4;
% 计算程序运行时间
tic %开始计时% 初始化操作
p = size(A,1); %计算顶点数目
S(1) = dest; %初始化集合S,已加入到路径中的顶点编号
U = 1:p; %初始化集合U,未加入到路径中的顶点编号
U(dest) = []; %删除终点编号
Distance = zeros(2,p); %初始化所有顶点到终点dest的距离
Distance(1,:) = 1:p; %重赋值第一行为各顶点编号
Distance(2,1:p) = A(dest,1:p); %重赋值第二行为邻接矩阵中各顶点到终点的距离
new_Distance = Distance;
D = Distance; %初始化U中所有顶点到终点dest的距离
D(:,dest) = []; %删除U中终点编号到终点编号的距离
path = zeros(2,p); %初始化路径
path(1,:) = 1:p; %重赋值第一行为各顶点编号
path(2,Distance(2,:)~=inf) = dest; %距离值不为无穷大时,将两顶点相连% 寻找最短路径
while ~isempty(U) %判断U中元素是否为空index = find(D(2,:)==min(D(2,:)),1); %剩余顶点中距离最小值的索引k = D(1,index); %发现剩余顶点中距离终点最近的顶点编号%更新顶点S = [S,k]; %将顶点k添加到S中U(U==k) = []; %从U中删除顶点k %计算距离new_Distance(2,:) = A(k,1:p)+Distance(2,k); %计算先通过结点k,再从k到达终点的所有点距离值D = min(Distance,new_Distance); %与原来的距离值比较,取最小值 %更新路径path(2,D(2,:)~=Distance(2,:)) = k; %出现新的最小值,更改连接关系,连接到结点k上 %更新距离Distance = D; %更新距离表为所有点到终点的最小值D(:,S) = []; %删除已加入到S中的顶点
end
dist = Distance(2,start); %取出指定起点到终点的距离值
toc %计时结束% 输出结果
fprintf('找到的最短路径为:');
while start ~= dest %到达终点时结束fprintf('%d-->',start); %打印当前点编号next = path(2,start); %与当前点相连的下一顶点start = next; %更新当前点
end
fprintf('%d\n',dest);
fprintf('最短路径对应的距离为:%d\n',dist);
end
此函数共有3个输入参数,3个输出参数
输入参数说明
A:邻接矩阵,存储各顶点之间的距离值,是一个大小为顶点个数的方阵,对角线元素为0
strat:起点编号
dest:终点编号
输出参数说明
dist:指定起点与终点之间的最短距离值
path:最短路径索引,一共两行,第一行的值依次为各顶点编号,第二行的值为与第一行顶点相连的顶点编号
Distence:最短路径下的距离值,一共两行,第一行的值依次为各顶点编号,第二行的值为对应顶点到终点的最小距离值
算法有效性的测试如下:
根据上图,想计算A点到D点的最短路径和距离,经过理论分析,其最短路径应为A-->F-->E-->D,最短距离为16+2+4=22
下面输入代码进行验证
输入代码
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];
start = 1;
dest = 4;
[dist,path,Distance] = dijkstra(A,start,dest)
时间已过 0.005424 秒。
找到的最短路径为:1-->6-->5-->4
最短路径对应的距离为:22
dist =
22
path =
1 2 3 4 5 6 7
6 3 4 4 4 5 5
Distance =
1 2 3 4 5 6 7
22 13 3 0 4 6 12
输入其他任意两个点,换一个距离矩阵,依然能正确输出最短路径和相应的距离值,算法的有效性得到验证
输入以下代码可生成最终的最短路径图,输出结果与起点值无关,任意点到D点的最短路径均可从图中找到
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];
start = 1;
dest = 4;[~,path,Distance] = dijkstra(A,start,dest)path(:,dest) = [];
Distance(:,dest) = [];
s = path(1,:);
t = path(2,:);
weights = Distance(2,:);
names = {'A' 'B' 'C' 'D' 'E' 'F' 'G'};g = digraph(s,t,weights,names);plot(g,'EdgeLabel',g.Edges.Weight)
可以看到,图中所有点均向D点聚集,且显示了每一个点到D点的最短距离
下面,使用matlab图论工具箱的函数寻找最短路径,再进行一个对比验证
图论工具箱中求最短路径的函数有以下3个,本文使用shortestpath,matlab命令窗口中输入doc shortestpath即可查看用法
shortestpath 两个单一节点之间的最短路径
shortestpathtree 从节点的最短路径树
distances 所有节点对组的最短路径距离
% 文件名:shortpath.m
% 时间:2020年9月12日
% 来源:https://blog.csdn.net/lishan132/article/details/108527271
% 功能:利用matlab自带的shortestpath函数计算两点间的最短路径
% dist:起点与终点之间的最短距离值
% path:最短路径
function [dist,path] = shortpath(A,start,dest)
%使用matlab自带的函数计算最短路径
tic
A(A==inf) = 0; %将无穷大值变为0
[t,s,weights] = find(A); %邻接矩阵中非零值的列、行号索引,及对应值
G = digraph(s,t,weights); %生成一幅带权值的有向图
[path,dist] = shortestpath(G,start,dest); %计算最短路径
toc%展示结果
plot(G,'EdgeLabel',G.Edges.Weight)
fprintf('找到的最短路径为:');
fprintf('%d ',path);
fprintf('\n');
fprintf('最短路径对应的距离为:%d\n',dist);
end
命令窗口输入以下代码验证结果
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];
start = 1;
dest = 4;
[dist,path] = shortpath(A,start,dest)
时间已过 0.002112 秒。
找到的最短路径为:1 6 5 4
最短路径对应的距离为:22
dist =
22
path =
1 6 5 4
两者结果一致,再次验证算法的有效性,而且自己写的Dijkstra算法的代码还能够一次输出所有点到终点的距离及路径表
仅一次测试以及少量的数据规模N不足以说明算法的解决效率,为了对两个算法性能进行一个比较,特地写了一个测试程序,输入的数据规模N从10到2000变化,并注释dijkstra.m、shortpath.m两个文件中的计时和输出结果部分的代码,程序如下
% 文件名:compar1.m
% 时间:2020年9月12日
% 来源:https://blog.csdn.net/lishan132/article/details/108527271
% 功能:比较自己实现的dijkstra算法与matlab图论工具箱函数的效率性能
% 说明:请先将dijkstra.m、shortpath.m文件与本文件放在同一目录下
clear
close
clc
iter = 200; %测试次数
t1 = zeros(1,iter); %算法1时间
t2 = zeros(1,iter); %算法2时间
for i = 1:iter%% 第一步:生成测试数据,距离矩阵A,起点start,终点destclearvars -except iter i t1 t2 %清空除iter,i,t1,t2外的所有变量N = i*10; %输入数据规模ub = 15; %输入数据距离上限A = unifrnd (0, ub, N, N); %生成一个服从均匀分布的矩阵,数值范围[0,ub],矩阵大小n×nA = A - A';A(A<0) = inf;start = round(rand(1,1)*(N-1))+1;dest = round(rand(1,1)*(N-1))+1;while start == destdest = round(rand(1,1)*(N-1))+1;end%% 第二步:计算自己编写的dk算法的运行时间tic %开始计时dijkstra(A,start,dest);t1(i) = toc; %计时结束%% 第三步:计算使用matlab自带图论工具箱算法的运行时间tic %开始计时shortpath(A,start,dest);t2(i) = toc; %计时结束
end%% 第四步:绘制算法所需时间图
plot(1:iter,t1);
hold on
plot(1:iter,t2);
legend("文中dijkstra算法","图论工具shortestpath函数")
title("算法耗费时间比较")
惊喜地发现,随着数据规模的增大,自己写的Dijkstra算法与图论工具函数shortestpath相比,耗时更低,而且差距越来越大。
当然,此处还是有些不严谨,因为我在使用图论工具函数shortestpath解决问题时,前面自己还写了三条参数的处理语句,这部分语句的处理过程也是算入时间的
结论
本文实现了dijkstra算法的Matlab代码,并封装成一个函数,给定一个邻接矩阵,以及指定一个终点,可以直接输出任意点到终点的最短路径和相应的距离值,相对matlab自带的图论工具箱函数,其运算速度快,输出数据全,方便二次开发,提高效率。但自己写的程序中每次只寻找一个新的结点加入,有多少个结点,while中的循环体就要执行多少次,每一次循环均要更新一次所有结点到终点的距离值,当结点数据非常大时,时间复杂度为O(N^2),因此还有继续优化的空间,根据相关文献,可用堆进行优化,也可从能否一次加入多个新结点,而不是一个来考虑加快搜索速度。
参考文章:
[1] 数据结构--Dijkstra算法最清楚的讲解 数据结构--Dijkstra算法最清楚的讲解_heroacool的博客-CSDN博客
[2] 通俗易懂理解——dijkstra算法求最短路径 (七)通俗易懂理解——dijkstra算法求最短路径 - 知乎
[3] Dijkstra算法及其matlab实现 Dijkstra算法及其matlab实现_Anonymoushi的博客-CSDN博客
[4] 李建东,盛敏编著. 通信网络基础. 北京:高等教育出版社, 2004.08.
[5] 迪杰斯特拉 & 堆优化 迪杰斯特拉 & 堆优化_ExRoc的博客-CSDN博客
最短路径 Dijkstra算法的Matlab代码实现相关推荐
- 最短路径——Dijkstra算法与Floyd算法
最短路径 Dijkstra算法 C语言代码实现 代码解析 Floyd算法 算法解析 C语言代码实现 最短路径问题 最短路径问题是我们经常会面临的一种决策问题.在图论中,非网图(边没有权值)的最短路径就 ...
- 【数据结构】图(最短路径Dijkstra算法)的JAVA代码实现
最短路径的概念 最短路径的问题是比较典型的应用问题.在图中,确定了起始点和终点之后,一般情况下都可以有很多条路径来连接两者.而边或弧的权值最小的那一条路径就称为两点之间的最短路径,路径上的第一个顶点为 ...
- matlab 流星雨,dijkstra算法及其matlab实现
http://blog.sina.com.cn/lyqmath 简介 dijkstra算法(迪杰斯特拉算法)是一种经典的优化算法.以其应用的广泛性与简便性,值得我们去研究. Dijkstra算法是典型 ...
- 最短路径-Dijkstra算法与Floyd算法
最短路径-Dijkstra算法与Floyd算法 原文:https://www.cnblogs.com/smile233/p/8303673.html 一.最短路径 ①在非网图中,最短路径是指两顶点之间 ...
- 分支限界法:单源最短路径--dijkstra算法
单源最短路径–dijkstra算法 前面已经多次介绍过dijkstra算法是贪心算法,是动态规划,实际上可以从分支限界的角度来理解: 分支限界法 分支限界法,实际上就是回溯法,一般意义的回溯法是基于深 ...
- 最短路径——Dijkstra算法以及二叉堆优化(含证明)
一般最短路径算法习惯性的分为两种:单源最短路径算法和全顶点之间最短路径.前者是计算出从一个点出发,到达所有其余可到达顶点的距离.后者是计算出图中所有点之间的路径距离. 单源最短路径 Dijkstra算 ...
- PSO-LSSVM算法及其MATLAB代码
挺完整的一篇博客,这里转载记录一下. 原文链接:PSO-LSSVM算法及其MATLAB代码 一.PSO 1.概念 粒子群优化算法(PSO:Particle swarm optimization)是一种 ...
- python棋盘最短路径_Python数据结构与算法之图的最短路径(Dijkstra算法)完整实例...
本文实例讲述了Python数据结构与算法之图的最短路径(Dijkstra算法).分享给大家供大家参考,具体如下: # coding:utf-8 # Dijkstra算法--通过边实现松弛 # 指定一个 ...
- 使用邻接矩阵实现有向图最短路径Dijkstra算法
题目描述: 用邻接矩阵存储有向图,实现最短路径Dijkstra算法,图中边的权值为整型,顶点个数少于10个. 输入描述 首先输入图中顶点个数和边的条数: 再输入顶点的信息(字符型): 再输入各边及其权 ...
最新文章
- elasticsearch 安装
- Cling旨在提供一款高性能的C++ REPL
- linux下安装sniffit
- vc++ 将可执行文件链接到 DLL
- Java 条件运算符
- 电子路考容易犯错的五大细节
- 图书管理系统可行性分析报告范例_会做可行性分析报告贺州专家团队*金
- structs2拦截器详解
- 云原生架构沙龙(成都站)圆满结束(附胶片下载)
- 深度学习自学(三十四):换衣场景下行人重识别
- Java加密压缩文件
- No package 'libxml-2.0' found
- 机械精度设计与检测|尺寸精度
- C语言中的free函数
- VGA、DVI、HDMI都是什么意思?
- 查询递归表SQL,分类表查询,递归表数据结构转平级查询优化SQL
- 如何在Python中四舍五入数字
- 看完知乎上500条答案,我为大家整理了这21个B站学习类UP主
- 植物大战僵尸android11,植物大战僵尸自创版APK
- 公司挖来一个阿里Java大神,生产环境故障调优很溜
热门文章
- 黑盒测试和白盒测试技术总结
- 【速达软件】【速达3000】3系底稿(年销售表)
- java毕业设计开题报告javaweb敬老院管理系统的设计和实现|养老院
- Xilinx HLS 仿真报错ERROR: [SIM 211-100] CSim failed with errors.
- mesos java_mesos 入门
- 博弈论 - 状态图-推导必胜必败态
- 武汉大学 杨必胜教授学术报告“点云三维信息提取与应用”心得体会与理解分析
- 04.10. 实战Kaggle比赛:预测房价
- LBM盖顶驱动流C++代码
- Distilled sesing