数学建模常用算法—迪杰斯特拉算法求最短路径(Dijkstra)

解决问题

迪杰斯特拉算法是从一个顶点到其余各顶点的最短路径算法,解决的是有权图中最短路径问题。迪杰斯特拉算法主要特点是从起始点开始,采用贪心算法的策略,每次遍历到始点距离最近且未访问过的顶点的邻接节点,直到扩展到终点为止。

优点

  • 原理简单
  • MATLAB有现成函数
  • 算法时间复杂度低

缺点

在单源最短路径问题的某些实例中,可能存在权为负的边,这时不能采用迪杰斯特拉算法,而应采用贝尔曼‐福特(Bellman‐Ford)算法。

算法原理

这个链接里有迪杰斯特算法(Dijkstra)和弗洛伊德算法(Floyd)的动画演示,前五分钟是迪杰斯特算法(Dijkstra)的动画演示,能够帮助读者直观地了解算法原理。

https://www.bilibili.com/video/av54668527
数学建模常用算法—迪杰斯特拉算法求最短路径(Dijkstra)_第1张图片
遍历完所有节点后我们得到以上表格,从目标点开始,一步一步寻找它的父节点,即可找出图论的最短路径。以0节点到4节点为例,4节点的父节点为5节点,5节点的父节点为2节点,以此类推,我们得到它的最短路径为:
0→1→7→8→2→5→4
最短路径长度为:24

注意事项

前面提到,迪杰斯特拉算法可以用于有向图,但不能处理负权重。贝尔曼‐福特算法(Bellman‐Ford)可以处理带有负权重的有向图,但不能处理含有负权回路的图。
数学建模常用算法—迪杰斯特拉算法求最短路径(Dijkstra)_第2张图片

MATLAB算法实现

以下图为例
数学建模常用算法—迪杰斯特拉算法求最短路径(Dijkstra)_第3张图片

1. MATLAB作图

%% Matlab作无向图
%1)无权重(每条边的权重默认为1% 函数graph(s,t):可在 s 和 t 中的对应节点之间创建边,并生成一个图
% s 和 t 都必须具有相同的元素数;这些节点必须都是从1开始的正整数,或都是字符串元胞数组。
s1 = [1,2,3,4];
t1 = [2,3,1,1];
G1 = graph(s1, t1);
plot(G1)
% 注意哦,编号最好是从1开始连续编号,不要自己随便定义编号
s1 = [1,2,3,4];
t1 = [2,3,1,1];
G1 = graph(s1, t1);
plot(G1)

% 注意字符串元胞数组是用大括号包起来的哦
s2 = {'学校','电影院','网吧','酒店'};
t2 = {'电影院','酒店','酒店','KTV'};
G2 = graph(s2, t2);
plot(G2, 'linewidth', 2)  % 设置线的宽度
% 下面的命令是在画图后不显示坐标
set( gca, 'XTick', [], 'YTick', [] );  

%2)有权重
% 函数graph(s,t,w):可在 s 和 t 中的对应节点之间以w的权重创建边,并生成一个图
s = [1,2,3,4];
t = [2,3,1,1];
w = [3,8,9,2];
G = graph(s, t, w);
plot(G, 'EdgeLabel', G.Edges.Weight, 'linewidth', 2) 
set( gca, 'XTick', [], 'YTick', [] );  

%% Matlab作有向图
% 无权图 digraph(s,t)
s = [1,2,3,4,1];
t = [2,3,1,1,4];
G = digraph(s, t);
plot(G)
set( gca, 'XTick', [], 'YTick', [] );  

% 有权图 digraph(s,t,w)
s = [1,2,3,4];
t = [2,3,1,1];
w = [3,8,9,2];
G = digraph(s, t, w);
plot(G, 'EdgeLabel', G.Edges.Weight, 'linewidth', 2) 
set( gca, 'XTick', [], 'YTick', [] );  

用MATLAB实现案例中的图

% 注意哦,Matlab中的图节点要从1开始编号,所以这里把0全部改为了9
% 编号最好是从1开始连续编号,不要自己随便定义编号
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);
plot(G, 'EdgeLabel', G.Edges.Weight, 'linewidth', 2) 
set( gca, 'XTick', [], 'YTick', [] ); 

数学建模常用算法—迪杰斯特拉算法求最短路径(Dijkstra)_第4张图片

2. MATLAB计算最短路径

数学建模常用算法—迪杰斯特拉算法求最短路径(Dijkstra)_第5张图片
数学建模常用算法—迪杰斯特拉算法求最短路径(Dijkstra)_第6张图片

在以上案例中

[P,d] = shortestpath(G, 9, 4)  %注意:该函数matlab2015b之后才有哦

数学建模常用算法—迪杰斯特拉算法求最短路径(Dijkstra)_第7张图片

3. 高亮最短路径

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

数学建模常用算法—迪杰斯特拉算法求最短路径(Dijkstra)_第8张图片

4. 其他

  • 我们可以通过以下函数返回任意两点的距离矩阵

数学建模常用算法—迪杰斯特拉算法求最短路径(Dijkstra)_第9张图片

  • 我们可以通过以下函数找给定范围内所有点
    数学建模常用算法—迪杰斯特拉算法求最短路径(Dijkstra)_第10张图片

最后

放入数学建模论文中的图论图不建议用MATLAB绘制出来的,建议采用以下网站绘制:https://csacademy.com/app/graph_editor/
数学建模常用算法—迪杰斯特拉算法求最短路径(Dijkstra)_第11张图片

你可能感兴趣的:(数学建模,数学建模,matlab,算法)