本文使用 Python 实现了 Dijkstra 算法求解最短路径问题。在算法实现中,使用数组存储网络中各结点之间的距离,使用二叉堆存储 T 集合,并尽量使用向量化计算加快运行速度。
最终在三种网络结构下的运行时间为:
输入文件
grid_150_150
random_20000_40000
dense_1000
运行时间
302.93ms
292.14ms
135.29ms
但在最开始实现 Dijkstra 算法时,我的程序需要花 5 秒才能完成计算。经过逐步优化,运行时间可以降为 3 秒甚至 0.13 秒。把算法效率优化到极致的过程是非常有收获的,既加深了对算法本身的理解,又学习了许多优化算法的经验。
优化算法的经验
多考虑用向量化计算,尽量避免使用 for 循环。
想清楚算法的终止条件是什么。例如,在 One-to-all 问题中,可以把“遍历完T集合中的所有元素,直到 T 集合为空集”作为终止条件,也可以把“ P 集合中的元素个数等于网络中的结点个数”作为终止条件。虽然两者都能得到正确的结果,但当 P 集合中的元素个数等于网络中的结点个数时,T 集合中的元素是不需要再更新的,所以后者比前者所需要的运算次数少得多。
熟悉 NumPy
等科学计算库的实现细节。例如,在 NumPy
中,np.ones
和 np.empty
都可以用来创建指定形状的数组,其中 np.ones
会创建一个填充 1 的数组,而 np.empty
会在一块内存上创建一个未初始化的数组。由于 np.empty
不会进行初始化,因此生成速度要比 np.ones
更快。
使用合适的数据类型。例如,若问题中的变量可以肯定为整数,则可以考虑用 dtype=np.int32
或者 dtype=np.int16
,节约内存空间。不同整数数据类型所能表示的整数范围如下:
Type
Capacity
Int16
(-32,768 to +32,767)
Int32
(-2,147,483,648 to +2,147,483,647)
Int64
(-9,223,372,036,854,775,808 to +9,223,372,036,854,775,807)
继续阅读