写这篇文章是因为前几日突然C同学给我打来电话,说自己的论文在计算一个问题时耗时过长。问题是:在不同城市间有固定的距离,某人从A城市出发到B城市的最短路径。C同学抱怨自己用了穷举法花了好久的时间才搞定,当时听完电话就说,你可以数学建模用路径寻优来做,分分钟就解决了啊。脑子里闪过的算法里面Dijkstra算法应该算是比较简单且实用的了,本文就来举个例子说明下这个算法,顺便写点脚本也可以用在自己玩的汽车仿真环境里面。
先介绍下这个算法,这个算法是荷兰info的科学家Dijkstra在1956年发明的,用来在图中寻找不同节点之间的最短路径,最简单的一个例子就是用来计算不同城市间的最短距离。如下图中的路网所示,
先来介绍下这个算法的基本概念,对于这个算法有以下几个变量:1. 集合V涵盖了图中的所有节点,2. 选取另一个集合M作为标记过的节点的集合(其中s作为开始的节点),3. 对于每个节点x都存在一个前序节点v(x), 4,除了前序节点v(x)之外对节点x还存在最佳路径c (s,x), 5. 选取h作为中间运行节点。
算法运行初始时:
•M = {s}
•v(x) = 所有为定义的 x
•c(s,s) = 0,对于时 x ≠ s c(s,x) = ∞
•h:= s
算法的工作流,如下图所示:
下面再来根据上文中提到的例子来进行寻优,如图所示图上有6个点,现在从a点出发到f点,求最短距离。
第一步取点a,
第二步,计算集合中除a之外所有的点到点a的距离,
第三步,以d为起点找出除a,d之外所有点到d点的距离,此时d点到b和c的距离大于a点到b和c的距离,所以d到b和c点的距离延用,e,f两点到d点的距离小于a点到e,f的距离所以分别更新。
第四步,以b为起点找出除a,d,b之外所有点到b点的距离,计算流程同上。此时未有更新,下一个节点选取最小的值e点开始。
第五步,以e为起点找出除a,d,b,e之外所有点到e点的距离,
第六步,以c为起点找出除a,d,b,e,c之外所有点到f点的距离,
在遍历完所有的节点后,此时我们可以得到a到f的最短距离为5,路径为a-d-e。此时最短路径的集合M中也包含了a点到各点的最短距离{a(0),b(2),c(3),d(1),e(2),f(5)}
下面是算法导论中的源代码
DIJKSTRA(G, w, s)
1 INITIALIZE-SINGLE-SOURCE(G, s)
2 S ← Ø
3 Q ← V[G]
4 while Q ≠ Ø
5 do u ← EXTRACT-MIN(Q)
6 S ← S ∪{u}
7 for each vertex v ∈ Adj[u]
8 do RELAX(u, v, w)
本文对Dijkstra算法做了举例说明,文中难免有疏忽的地方,欢迎大家交流指正。
欢迎大家关注我的公众号:踱步在六月十七大街