本文同时作为北京大学《数据结构与算法》课程论文提交。转载请注明出处。
算法(Algorithm)一词来源于公元九世纪的波斯数学家、天文学家及地理学家花拉子米(Muhammad ibn Musa al-Khwarizmi)(「Algorithm」一词本身兴起于 1950 年左右。虽然对其起源的考证有很多不同的观点,但一种较为可靠的说法是「Algorism」,由此可以追溯到花拉子米。比较有趣的是,「代数」(Algebra)一词亦与花拉子米有关 —— 这来源于他的一本与代数没有什么联系的著作)。而世界上最早的算法,出现的甚至比这更早 —— 欧几里得的辗转相除法,诞生于公元三世纪。今日我们所说的算法,可以参见高德纳(Donald Ervin Knuth)在他的著作《计算机程序设计艺术(The Art of Computer Programming)》里的描述(可参阅《计算机程序设计艺术(中文版)第一卷第三版:基本算法》的第 3 至 4 页):
- 输入:一个算法必须有零个或以上输入量。
- 输出:一个算法应有一个或以上输出量,输出量是算法计算的结果。
- 明确性:算法的描述必须无歧义,以保证算法的实际执行结果是精确地匹配要求或期望,通常要求实际运行结果是确定的。
- 有限性:依据图灵的定义,一个算法是能够被任何图灵完全系统模拟的一串运算,而图灵机只有有限个状态、有限个输入符号和有限个转移函数(指令)。而一些定义更规定算法必须在有限个步骤内完成任务。
- 有效性:又称可行性。能够实现,算法中描述的操作都是可以通过已经实现的基本运算执行有限次来实现。
本文将要介绍的二十世纪十大算法,最早由 Jack Dongarra 和 Francis Sullivan 在 2000 年提出(SIAM 上的一篇报道使其广泛传播)。他们选择了「对 20 世纪科学与工程的发展和实践影响最大的 10 种算法」,分别是:
- 蒙特卡洛方法(Monte Carlo method),John von Neumann, Stan Ulam 和 Nick Metropolis 在 1946 年提出
- 线性规划的单纯形法(Simplex method for linear programming),George Dantzig 在 1947 年提出
- Krylov 子空间迭代法(Krylov subspace iteration methods),Magnus Hestenes, Eduard Stiefel 和 Cornelius Lanczos 在 1950 年提出
- Householder 形式化矩阵计算(Decompositional approach to matrix computations),Alston Householder 在 1951 年提出
- 优化的 Fortran 编译器(Fortran optimizing compiler),John Backus 在 1957 年提出
- QR 分解(QR algorithm),J.G.F. Francis 在 1959-61 年提出
- 快速排序(Quicksort),Tony Hoare 在 1962 年提出
- 快速傅里叶变换(Fast Fourier transform),James Cooley 和 John Tukey 在 1965 年提出
- 整数关系探测算法(Integer relation detection algorithm),Helaman Ferguson 和 Rodney Forcade 在 1977 年提出
- 快速多极算法(Fast multipole algorithm),Leslie Greengard 和 Vladimir Rokhlin 在 1987 年提出
下面将逐一介绍这些算法。为了明确地表达思想,这里会给出一些示例代码。