定义
Dijkstra算法是一种单向的最短路径算法,有研究者就提出了一种优化方法,即双向Dijkstra算法。其主要思想就是从起点和终点同时开始搜索,这样应该能够提升算法效率。事实证明,在大部分情况下,双向Dijkstra算法还是要优于单向的Dijkstra算法。
去看原文
算法介绍
Dijkstra算法是单点源的形式往外搜索,它的搜索空间长这样:
双向Dijkstra算法顾名思义,就是从两个方向同时开始搜索,它的搜索空间长这样:
Dijkstra算法一个方向搜索需要一个优先队列,那双向Dijkstra算法也就需要两个优先队列了。两个优先队列交替取出最小的元素来扩展,扩展的时候需要检测是否包含环,其扩展过程与Dijkstra算法一样。其原理是从起点和终点依次执行单向的Dijkstra算法,即前向和后向Dijkstra扩展搜索。当两个方向第一次相遇时,会得到一条候选最短路径(第一次相遇时的路径不是最优路径,见下图)。当起点终点分别为节点1和9时,前向和后向优先队列节点的出队列顺序分别为
[
1
,
2
,
3
,
4
]
[1,2,3,4]
[1,2,3,4]和
[
9
,
6
,
8
,
4
]
[9,6,8,4]
[9,6,8,4],第一个相遇的节点为4,此时得到的路径为
p
=
{
1
,
2
,
3
,
4
,
8
,
9
}
p=\{1,2,3,4,8,9\}
p={1,2,3,4,8,9},然而该路径并非第一条最短路径(最优路径为
p
b
e
s
t
=
{
1
,
6
,
9
}
p_{best} = \{1,6,9\}
pbest={1,6,9})。因此第一次相遇时得到的路径并非最优路径。
第一次相遇后,后续节点继续扩展时,只需访问已经出过队列的那些节点即可。在这个过程中,全局最优路径就是所有相遇节点的正向代价和方向代价之和的最小值。
实验对比
测试部分比较了单向Dijkstra算法、双向Dijkstra算法、A*算法的计算效率。此处优先队列采用斐波那契堆,随机取了100对OD,分别记录每对OD最短路径计算的运行时间以及扩展节点数量。
使用路网1时的计算结果:
Construct network adjacent list ...
Construct network adjacent finished! It consumes 0.931 seconds.
Start to calculate 1th shortest path from 1129 to 167 ...
Dijkstra Algo: The shortest path cost is 17289.119, It consumes 0.048 seconds and selects 832 nodes
AStar Algo: The shortest path cost is 17289.119, It consumes 0.003 seconds and selects 48 nodes
Bi-Dijkstra Algo: The shortest path cost is 17289.119, It consumes 0.016 seconds and selects 366 nodes
Start to calculate 2th shortest path from 769 to 3498 ...
Dijkstra Algo: The shortest path cost is 5522.333, It consumes 0.016 seconds and selects 301 nodes
AStar Algo: The shortest path cost is 5522.333, It consumes 0.005 seconds and selects 93 nodes
Bi-Dijkstra Algo: The shortest path cost is 5522.333, It consumes 0.032 seconds and selects 447 nodes
Start to calculate 3th shortest path from 2801 to 2504 ...
Dijkstra Algo: The shortest path cost is 31011.622, It consumes 0.071 seconds and selects 1217 nodes
AStar Algo: The shortest path cost is 31011.622, It consumes 0.069 seconds and selects 832 nodes
Bi-Dijkstra Algo: The shortest path cost is 31011.622, It consumes 0.080 seconds and selects 1394 nodes
Start to calculate 4th shortest path from 2100 to 161 ...
Dijkstra Algo: The shortest path cost is 29805.903, It consumes 0.080 seconds and selects 1285 nodes
AStar Algo: The shortest path cost is 29805.903, It consumes 0.008 seconds and selects 117 nodes
Bi-Dijkstra Algo: The shortest path cost is 29805.903, It consumes 0.022 seconds and selects 459 nodes
Start to calculate 5th shortest path from 3473 to 3440 ...
Dijkstra Algo: The shortest path cost is 2693.313, It consumes 0.008 seconds and selects 156 nodes
AStar Algo: The shortest path cost is 2693.313, It consumes 0.002 seconds and selects 25 nodes
Bi-Dijkstra Algo: The shortest path cost is 2693.313, It consumes 0.009 seconds and selects 170 nodes
...
The mean consumption times is: Dijkstra: 0.042, Bi-Dijkstra: 0.034, A*: 0.019
The mean expanded nodes is: Dijkstra: 680.260, Bi-Dijkstra: 619.000, A*: 267.760
以下是在路网1中100对OD的平均计算时间和扩展节点数:
Dijkstra算法 | 双向Dijkstra算法 | A*算法 | |
---|---|---|---|
平均计算时间(s) | 0.042 | 0.034 | 0.019 |
平均扩展节点数 | 680.26 | 619.00 | 267.76 |
使用路网2时的计算结果:
Construct network adjacent list ...
Construct network adjacent finished! It consumes 24.804 seconds.
Start to calculate 1th shortest path from 12443 to 12627 ...
Dijkstra Algo: The shortest path cost is 20328.300, It consumes 0.577 seconds and selects 5741 nodes
AStar Algo: The shortest path cost is 20328.300, It consumes 0.087 seconds and selects 966 nodes
Bi-Dijkstra Algo: The shortest path cost is 20328.300, It consumes 0.683 seconds and selects 6779 nodes
Start to calculate 2th shortest path from 4144 to 10838 ...
Dijkstra Algo: The shortest path cost is 22007.953, It consumes 0.389 seconds and selects 3578 nodes
AStar Algo: The shortest path cost is 22007.953, It consumes 0.085 seconds and selects 787 nodes
Bi-Dijkstra Algo: The shortest path cost is 22007.953, It consumes 0.475 seconds and selects 4833 nodes
Start to calculate 3th shortest path from 8114 to 11581 ...
Dijkstra Algo: The shortest path cost is 19407.315, It consumes 0.771 seconds and selects 6845 nodes
AStar Algo: The shortest path cost is 19407.315, It consumes 0.035 seconds and selects 356 nodes
Bi-Dijkstra Algo: The shortest path cost is 19407.315, It consumes 0.592 seconds and selects 6615 nodes
Start to calculate 4th shortest path from 6406 to 10489 ...
Dijkstra Algo: The shortest path cost is 20019.205, It consumes 1.020 seconds and selects 7920 nodes
AStar Algo: The shortest path cost is 20019.205, It consumes 0.134 seconds and selects 1184 nodes
Bi-Dijkstra Algo: The shortest path cost is 20019.205, It consumes 0.612 seconds and selects 6426 nodes
Start to calculate 5th shortest path from 6822 to 8476 ...
Dijkstra Algo: The shortest path cost is 25945.571, It consumes 0.424 seconds and selects 3912 nodes
AStar Algo: The shortest path cost is 25945.571, It consumes 0.085 seconds and selects 762 nodes
Bi-Dijkstra Algo: The shortest path cost is 25945.571, It consumes 0.674 seconds and selects 6890 nodes
...
The mean consumption times is: Dijkstra: 0.624, Bi-Dijkstra: 0.560, A*: 0.126
The mean expanded nodes is: Dijkstra: 5437.020, Bi-Dijkstra: 5419.480, A*: 1018.031
以下是在路网2中100对OD的平均计算时间和扩展节点数:
Dijkstra算法 | 双向Dijkstra算法 | A*算法 | |
---|---|---|---|
平均计算时间(s) | 0.624 | 0.560 | 0.126 |
平均扩展节点数 | 5437.02 | 5419.48 | 1018.03 |
为了方便阅读,上述路网1和路网2中各自的两幅图结果都根据Dijkstra算法的测试结果进行了排序。可以看出,整体来说,双向Dijkstra算法较单向Dijkstra算法有一定优势,例如,在路网2中,每对OD的平均计算时间Dijkstra算法需要0.624s,双向Dijkstra算法只需0.560s。但是也存在部分情况双向Dijkstra算法计算效率慢于单向Dijkstra算法。同理,大部分情况下,双向DIjkstra算法的搜索空间比Dijkstra算法要小。在这三个算法中,A*算法还是最快的。
更多精彩内容,请关注“探索GIS的小蜗牛”。如需源码,请后台留言。