首页 > 代码库 > 最短路径之迪杰斯特拉与双向迪杰斯特拉实验结果
最短路径之迪杰斯特拉与双向迪杰斯特拉实验结果
1. 实验数据
数据集:City of Oldenburg (OL) Road Network
9组查询均为相距较远的结点
2. 实验结果一
最近一直在围绕双向迪杰斯特拉转,对其中重要的优先队列数据结构,尝试了用无索引的二叉堆实现、有索引的二叉堆实现以及无索引的斐波那契实现三种方式。其中无索引的优先队列允许出现相同的节点,而有索引的优先队列中不允许。不同实现方式运行时间如表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 重要路径
3. 实验结果二
对于迪杰斯特拉来说,使用优先队列比普通方法快近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双向迪杰斯特拉比迪杰斯特拉慢。
分析: 双向迪杰斯特拉相比于迪杰斯特拉减少了一些结点的最短路径计算,即减少了处理结点。但是,前者需要多次的加法操作,也消耗了大量的时间。
4. 实验结果三
问题3: 当求解所有点对的最短路径时,floyd比迪杰斯特拉与双向迪杰斯特拉都快。
分析: floyd求解的时候不存在重复计算问题;而多次运行单源点最短路径问题求解所有对的最短路径时,存在很多重复的计算。因此,求解所有对或者多对最短路径时floyd算法优于迪杰斯特拉和双向迪杰斯特拉。