图论算法理论、实现及应用 数学建模第四章 图论 part4.2最短路径问题-Dijkstra算法

文章目录:

  1. 数学建模第四章 图论 part4.2最短路径问题-Dijkstra算法
  2. 算法有哪些分类
  3. 图遍历算法之最短路径Dijkstra算法

一、数学建模第四章 图论 part4.2最短路径问题-Dijkstra算法

1.Dijkstra算法介绍

算法特点:

迪科斯彻算法使用了广度优先搜索解决赋权有向图或者无向图的单源最短路径问题,算法最终得到一个最短路径树。该算法常用于路由算法或者作为其他图算法的一个子模块。

算法的思路

Dijkstra算法采用的是一种贪心的策略,声明一个数组dis来保存源点到各个顶点的最短距离和一个保存已经找到了最短路径的顶点的集合:T,初始时,原点 s 的路径权重被赋为 0 (dis[s] = 0)。若对于顶点 s 存在能直接到达的边(s,m),则把dis[m]设为w(s, m),同时把所有其他(s不能直接到达的)顶点的路径长度设为无穷大。初始时,集合T只有顶点s。 

然后,从dis数组选择最小值,则该值就是源点s到该值对应的顶点的最短路径,并且把该点加入到T中,OK,此时完成一个顶点, 

然后,我们需要看看新加入的顶点是否可以到达其他顶点并且看看通过该顶点到达其他点的路径长度是否比源点直接到达短,如果是,那么就替换这些顶点在dis中的值。 

然后,又从dis中找出最小值,重复上述动作,直到T中包含了图的所有顶点。

2、Dijkstra算法示例演示

我求下图,从顶点v1到其他各个顶点的最短路径.

首先第一步,我们先声明一个dis数组,该数组初始化的值为:

我们的顶点集T的初始化为:T={v1}

既然是求 v1顶点到其余各个顶点的最短路程,那就先找一个离 1 号顶点最近的顶点。通过数组 dis 可知当前离v1顶点最近是 v3顶点。当选择了 2 号顶点后,dis[2](下标从0开始)的值就已经从“估计值”变为了“确定值”,即 v1顶点到 v3顶点的最短路程就是当前 dis[2]值。将V3加入到T中。 

为什么呢?因为目前离 v1顶点最近的是 v3顶点,并且这个图所有的边都是正数,那么肯定不可能通过第三个顶点中转,使得 v1顶点到 v3顶点的路程进一步缩短了。因为 v1顶点到其它顶点的路程肯定没有 v1到 v3顶点短.

OK,既然确定了一个顶点的最短路径,下面我们就要根据这个新入的顶点V3会有出度,发现以v3 为弧尾的有: < v3,v4 >,那么我们看看路径:v1–v3–v4的长度是否比v1–v4短,其实这个已经是很明显的了,因为dis[3]代表的就是v1–v4的长度为无穷大,而v1–v3–v4的长度为:10+50=60,所以更新dis[3]的值,得到如下结果: 

因此 dis[3]要更新为 60。这个过程有个专业术语叫做“松弛”。即 v1顶点到 v4顶点的路程即 dis[3],通过 < v3,v4> 这条边松弛成功。这便是 Dijkstra 算法的主要思想:通过“边”来松弛v1顶点到其余各个顶点的路程。

然后,我们又从除dis[2]和dis[0]外的其他值中寻找最小值,发现dis[4]的值最小,通过之前是解释的原理,可以知道v1到v5的最短距离就是dis[4]的值,然后,我们把v5加入到集合T中,然后,考虑v5的出度是否会影响我们的数组dis的值,v5有两条出度:< v5,v4>和 < v5,v6>,然后我们发现:v1–v5–v4的长度为:50,而dis[3]的值为60,所以我们要更新dis[3]的值.另外,v1-v5-v6的长度为:90,而dis[5]为100,所以我们需要更新dis[5]的值。更新后的dis数组如下图: 

然后,我们使用同样原理,分别确定了v6和v2的最短路径,最后dis的数组的值如下: 

因此,从图中,我们可以发现v1-v2的值为:∞,代表没有路径从v1到达v2。所以我们得到的最后的结果为:

二、算法有哪些分类

算法的分类分为七类,分别是:

1、基本算法 : 包括枚举和搜索两种,分为深度优先搜索,广度优先搜索,启发式搜索和遗传算法;

2、数据结构的算法数论;

3、代数算法;

4、计算几何的算法,求凸包;

5、图论算法:包括哈夫曼编码,树的遍历,最短路径算法,最小生成树算法,最小树形图,网络流算法和匹配算法 ;

6、动态规划;

7、其他算法:包括数值分析,加密算法,排序算法,检索算法和随机化算法。

三、图遍历算法之最短路径Dijkstra算法

最短路径问题是图论研究中一个经典算法问题,旨在寻找图中两节点或单个节点到其他节点之间的最短路径。根据问题的不同,算法的具体形式包括:

常用的最短路径算法包括:Dijkstra算法,A 算法,Bellman-Ford算法,SPFA算法(Bellman-Ford算法的改进版本),Floyd-Warshall算法,Johnson算法以及Bi-direction BFS算法。本文将重点介绍Dijkstra算法的原理以及实现。

Dijkstra算法,翻译作戴克斯特拉算法或迪杰斯特拉算法,于1956年由荷兰计算机科学家艾兹赫尔.戴克斯特拉提出,用于解决赋权有向图的 单源最短路径问题 。所谓单源最短路径问题是指确定起点,寻找该节点到图中任意节点的最短路径,算法可用于寻找两个城市中的最短路径或是解决著名的旅行商问题。

问题描述 :在无向图 中, 为图节点的集合, 为节点之间连线边的集合。假设每条边 的权重为 ,找到由顶点 到其余各个节点的最短路径(单源最短路径)。

为带权无向图,图中顶点 分为两组,第一组为已求出最短路径的顶点集合(用 表示)。初始时 只有源点,当求得一条最短路径时,便将新增顶点添加进 ,直到所有顶点加入 中,算法结束。第二组为未确定最短路径顶点集合(用 表示),随着 中顶点增加, 中顶点逐渐减少。

以下图为例,对Dijkstra算法的工作流程进行演示(以顶点 为起点):

注:

01) 是已计算出最短路径的顶点集合;

02) 是未计算出最短路径的顶点集合;

03) 表示顶点 到顶点 的最短距离为3

第1步 :选取顶点 添加进

第2步 :选取顶点 添加进 ,更新 中顶点最短距离

第3步 :选取顶点 添加进 ,更新 中顶点最短距离

第4步 :选取顶点 添加进 ,更新 中顶点最短距离

第5步 :选取顶点 添加进 ,更新 中顶点最短距离

第6步 :选取顶点 添加进 ,更新 中顶点最短距离

第7步 :选取顶点 添加进 ,更新 中顶点最短距离

示例:node编号1-7分别代表A,B,C,D,E,F,G

(s.paths <- shortest.paths(g, algorithm = "dijkstra"))输出结果:

(s.paths <- shortest.paths(g,4, algorithm = "dijkstra"))输出结果:

示例:

找到D(4)到G(7)的最短路径:

[1] 维基百科,最短路径问题: https://zh.wikipedia.org/wiki/%E6%9C%80%E7%9F%AD%E8%B7%AF%E9%97%AE%E9%A2%98 ;

[2]CSDN,Dijkstra算法原理: https://blog.csdn.net/yalishadaa/article/details/55827681 ;

[3]RDocumentation: https://www.rdocumentation.org/packages/RNeo4j/versions/1.6.4/topics/dijkstra ;

[4]RDocumentation: https://www.rdocumentation.org/packages/igraph/versions/0.1.1/topics/shortest.paths ;

[5]Pypi: https://pypi.org/project/Dijkstar/

以上是问答百科为你整理的3条关于图论算法的问题,希望对你有帮助!更多相关图论算法的内容请站内查找。

你可能想看:
标签: 图论算法
分享给朋友: