数据集:City of Oldenburg (OL) Road Network
9组查询均为相距较远的结点
最近一直在围绕双向迪杰斯特拉转,对其中重要的优先队列数据结构,尝试了用无索引的二叉堆实现、有索引的二叉堆实现以及无索引的斐波那契实现三种方式。其中无索引的优先队列允许出现相同的节点,而有索引的优先队列中不允许。不同实现方式运行时间如表2-1所示,其中每个查询都运行了10000次,单位ms。
表2-1 双向迪杰斯特拉不同优先队列实现方式运行结果
查询 |
双向迪杰斯特拉 |
|||
二叉堆无索引t1 |
二叉堆有索引t2 |
t2/t1 |
斐波那契堆无索引 |
|
1 |
873 |
1716 |
1.96 |
1982 |
2 |
4103 |
8065 |
1.96 |
11466 |
3 |
6615 |
10842 |
1.63 |
17207 |
4 |
2106 |
3448 |
1.63 |
5460 |
5 |
5444 |
8674 |
1.59 |
14804 |
6 |
3666 |
6052 |
1.65 |
10046 |
7 |
655 |
1092 |
1.66 |
1264 |
8 |
4212 |
6662 |
1.58 |
11840 |
9 |
6272 |
9578 |
1.52 |
16365 |
问题1: 无索引的二叉堆比有索引实现优先队列最短路径求解快了平均1.7倍。其中对于索引部分尝试了两种方式:数组索引与哈希(cmap)索引,两种方式效果相似。
分析: 建立、调整索引的时间与存储结点的时间是一样的,因此加入索引必然增加优先队列的时间消耗。
另外,对于无索引的优先队列,相同的结点会同时出现在队列中。对于相同的节点,先出来的肯定是最小的,当其它结点出来时到该节点的最短路径已经求出,只需一次判断即可。而实际中只有小于20%的出队列操作是无效的。
无索引的二叉堆双向迪杰斯特拉主要函数运行时间分析如图2-1所示。函数调用关系如图2-2所示。
图2-1 各主要函数运行时间
图2-2 重要路径
对于迪杰斯特拉来说,使用优先队列比普通方法快近60倍。因此对比中直接忽略该种方式实现的迪杰斯特拉。表3-1列出了查询时间,其中每组查询都运行了10000次,其中优先队列的实现方式为无索引的二叉堆。
表3-1 无索引的双向迪杰斯特拉与迪杰斯特拉时间对比
|
双向迪杰斯特拉 |
迪杰斯特拉 |
1 |
873 |
2262 |
2 |
4103 |
6911 |
3 |
6615 |
7425 |
4 |
2106 |
1092 |
5 |
5444 |
7207 |
6 |
3666 |
1872 |
7 |
655 |
1154 |
8 |
4212 |
7051 |
9 |
6272 |
7489 |
问题2:对于查询4与查询7双向迪杰斯特拉比迪杰斯特拉慢。
分析: 双向迪杰斯特拉相比于迪杰斯特拉减少了一些结点的最短路径计算,即减少了处理结点。但是,前者需要多次的加法操作,也消耗了大量的时间。
问题3: 当求解所有点对的最短路径时,floyd比迪杰斯特拉与双向迪杰斯特拉都快。
分析: floyd求解的时候不存在重复计算问题;而多次运行单源点最短路径问题求解所有对的最短路径时,存在很多重复的计算。因此,求解所有对或者多对最短路径时floyd算法优于迪杰斯特拉和双向迪杰斯特拉。最短路径之迪杰斯特拉与双向迪杰斯特拉实验结果,布布扣,bubuko.com
原文地址:http://blog.csdn.net/woniu317/article/details/25795081