《具体数学》笔记:给 TAOCP 打地基的那门课,把“算得出来”变成一种信仰
- 约 24 分钟读完 - 全文 9480 字《具体数学》笔记:给 TAOCP 打地基的那门课,把“算得出来”变成一种信仰
目标读者:被算法复杂度“大概是个 n log n”糊弄过、想学会把账算清楚的工程师;以及啃不动 TAOCP 数学小节、想找一本更友好的前传的人。 参考书籍:Ronald L. Graham、Donald E. Knuth、Oren Patashnik《具体数学:计算机科学基础》(Concrete Mathematics: A Foundation for Computer Science,1989 年初版,1994 年第二版)。 阅读目标:不是把九章全部复刻一遍——那等于重抄一本书——而是把每章的“核心技术”蒸馏成一张地图:每章解决什么问题、哪几个技巧值得练成肌肉记忆、哪些结论在工程里真的能变现。
一、定位:continuous + discrete,一门为“具体”正名的课
先解书名的梗。Concrete 是 CONtinuous + disCRETE 的拼接文字游戏:这门课讲的是连续数学与离散数学之间那片“受控的混合地带”——和式、递推、取整、组合数、生成函数,全是既不离散得纯粹也不连续得抽象的对象。作者们在前言里说得很直白:这门课要教的是**“具体”的数学——能算出来的、能推广成闭式(closed form)的数学**,而不是那种只证明存在性、给不出数值的数学。
这门课有真实的血统:它源自斯坦福自 1970 年起开设的同名课程,Knuth 本人讲过很多轮,最初就是为了给学计算机的学生补 TAOCP 所需的数学地基。三位作者里,Graham 是组合数学大家(“Graham 数”那个 Graham),Knuth 不必介绍,Patashnik 是 Knuth 的学生、BibTeX 的作者。这本书和 TAOCP 是天然的姊妹篇——TAOCP 里那些“易证,留给读者”的数学推导,这本书把它们摊开揉碎讲透。
这本书还有一个别的教科书没有的特征:页边涂鸦(margin graffiti)。每一页的页边都印着当年选课学生的批注、玩笑、吐槽和妙语——这是 Knuth 从课程助教的课堂记录里精选出来的,让整本书读起来像一间热闹的研讨室而不是一座庙。严肃内容与页边段子并置,本身就是作者的表态:数学是可以玩得起来的手艺,不是供奉起来的神像。
这本书的习题也自成体系,按用途分六档:热身题(warmups,读完正文就该会做)、基本题(basics,巩固事实)、作业题(homework,加深理解)、考试题(exam problems,一题多概念)、加分题(bonus problems,超出正文范围)、研究题(research problems,出题时可能没有已知答案)。这个分档本身就是一张阅读路线图:时间紧就只做热身题和基本题,想深挖再往下走。另外交代一句版本差异:1994 年的第二版除了修订错误,还新增了超几何求和机械化(Zeilberger 对 Gosper 算法的扩展)等新材料——入手时注意对应第二版。
阅读难度上给一个实话提示:这本书推导密度很高,但没有一处是“为难而难”——所有推导都服务于一个能算出来的结果。第一遍只读正文、把结论划线即可,习题先挑热身题做;真正让人回不去的是第二遍:当你发现工作里那个“算不清的复杂度”其实就是第 2 章的一道例题时,这本书就长在手边了。
flowchart TD
CM["具体数学 Concrete Mathematics<br/>continuous + discrete"] --> R["第 1-3 章 基本功<br/>递归 / 和式 / 整值函数"]
CM --> N["第 4-6 章 组合核心<br/>数论 / 二项式系数 / 特殊数"]
CM --> G["第 7-9 章 分析武器<br/>生成函数 / 离散概率 / 渐近"]
R -.->|"三板斧<br/>小情形-猜测-归纳"| TAOCP["TAOCP 的数学地基<br/>算法精确分析"]
N -.->|"计数与恒等式"| TAOCP
G -.->|"从递推到闭式到量级"| TAOCP
style TAOCP fill:#fff3cd
二、递归问题:小规模情形 → 猜测 → 归纳证明
第 1 章用三个经典问题立起全书的方法论:先算小规模情形,大胆猜测一般规律,再用数学归纳法钉死它。 这三板斧听起来朴素,但全书后面所有“神来之笔”都是这个套路的放大版。
flowchart LR
A["小规模情形<br/>手算 n 等于 0,1,2,3"] --> B["大胆猜测<br/>一般规律或闭式"]
B --> C["数学归纳法<br/>严格证明"]
C -->|"证不出来<br/>回头修正猜测"| B
C --> D["得到可迁移的洞察<br/>而不只是数据"]
style D fill:#fff3cd
- 汉诺塔:$n$ 个盘子的最少移动次数满足 $T_n = 2T_{n-1} + 1$,$T_0 = 0$,算几项猜出 $T_n = 2^n - 1$,归纳法一行收尾。这题的标准价值在于示范了“把大问题化归成同构的小问题”这个递归思维本身。
- 汉诺塔变体:书中接着玩规则——若规定盘子每次只能在相邻柱子间移动,答案变成 $3^n - 1$。同一个游戏,约束一改,闭式的底数从 2 变 3:递推结构决定一切。
- 平面分割直线(切披萨):$n$ 条直线最多把平面分成几块?第 $n$ 条直线最多与前面 $n-1$ 条各交一点,被切成 $n$ 段,每段多劈出一个区域:$L_n = L_{n-1} + n$,展开得 $L_n = n(n+1)/2 + 1$。
- 高维推广:书中顺势把切披萨推到高维——$n$ 张平面最多把空间切成 $\binom{n}{0} + \binom{n}{1} + \binom{n}{2} + \binom{n}{3}$ 块,一般维度的答案都是二项式系数的截断和。这是二项式系数在第 5 章正式登场前的第一次亮相。
- 约瑟夫问题(Josephus problem):$n$ 人围圈,每隔一人杀一人,最后幸存者的编号 $J(n)$ 是多少?这是全章的高潮。算小情形发现 $J(n)$ 总是奇数且按 $2$ 的幂分段线性,猜出并证明:
$$J(2^m + \ell) = 2\ell + 1, \qquad 0 \le \ell < 2^m$$
真正的神来之笔是它的二进制形态:把 $n$ 写成二进制 $n = (1\, b_{m-1} b_{m-2} \ldots b_0)_2$,则 $J(n)$ 就是把最高位的 $1$ 循环移到最低位——$J(n) = (b_{m-1} b_{m-2} \ldots b_0\, 1)_2$。一个看起来要模拟整个过程的问题,答案是一次循环左移。这个结果是“猜小情形”方法论能给的最高奖赏:不光有闭式,还有一个看一眼就忘不掉的结构。
书里也诚实地泼了冷水:把规则改成每隔两人杀一人,约瑟夫问题就没有这么漂亮的闭式了——漂亮的闭式是运气,小情形-猜测-归纳的方法论才是常态。这个提醒对工程实践同样适用:先问有没有结构,再决定要不要追闭式。
章末还埋了一个进阶武器:套招法(repertoire method)。遇到带一般常数项的递推(比如 $f(1) = \alpha$、$f(2n) = 2f(n) + \beta$ 这类约瑟夫问题的推广式),先找一批函数已知、常数项也已知的“招式”作为基,再把目标常数项表成这些基的线性组合——解也就跟着线性组合出来。它和线性代数里“基展开”是同一件事,只不过向量换成了递推的解。
感悟:工程师遇到递推的第一反应常是“写个程序跑一下”。这一章的立场是:跑程序只能给你数据,归纳-猜测-证明才能给你洞察——而洞察是可以迁移的,数据不能。
三、和式:扰动法与 Iverson 括号
第 2 章把“求和”从小学算术升级成一套形式演算。
**扰动法(perturbation method)**是本章的招牌技巧,以求几何级数为例:设 $S_n = \sum_{k=0}^{n} a x^k$,把最后一项拆出来再重新配齐下标,得到
$$S_n + a x^{n+1} = a + x S_n \quad\Longrightarrow\quad S_n = \frac{a - a x^{n+1}}{1 - x}$$
整个过程没有一个“聪明的灵感”,纯粹是把和式当作可以代数操作的符号对象——这就是“形式方法”的力量:把直觉题变成机械题。等差数列和、算术-几何混合级数,同一个套路通吃。本质上它是“把未知量凑进自己的方程里再解出来”,和代数里的移项是同一个思想,只是操作对象从数换成了和式。
同一个动作还能解递推。书中用**求和因子法(summation factor)**处理 $a_n T_n = b_n T_{n-1} + c_n$ 型的一阶递推,并用它解出快速排序的平均比较次数:递推 $C_n = n + 1 + \frac{2}{n}\sum_{k<n} C_k$ 的精确解是 $C_n = 2(n+1)H_n - 4n$——教科书里“快排平均 $O(n \log n)$”这句话的完整账,就长这样。
多重和式交换求和次序是另一项基本功:$\sum_i \sum_j a_{ij}$ 先加哪个,取决于哪个方向好算——这和数据库优化器决定 join 顺序是同构的思维。配上 Iverson 括号,这个技巧变得完全机械:界限互相依赖的双重和可以写成
$$\sum_j \sum_k a_{j,k}\,[1 \le j \le k \le n]$$
界限信息全部进括号之后,交换次序就退化成对括号里的条件做代数变换,不再需要在脑子里维护“哪一层界限依赖哪个下标”。
然后是全书影响力最大的记号发明之一:Iverson 括号(Iverson’s convention)。对任意命题 $P$:
$$[P] = \begin{cases} 1, & P \text{ 为真} \\ 0, & P \text{ 为假} \end{cases}$$
(源码里上面 cases 环境的换行写作 \\\\,这是本站 KaTeX 渲染链路的转义要求,不是笔误。)Iverson 括号的威力在于消灭求和界限上的特例讨论:比如“小于 $n$ 的素数个数”可以不带任何附加条件地写成 $\sum_{0 \le k < n}[k \in \mathbb{P}]$,求和范围随便切,条件全部进括号。这个记号源自 Ken Iverson 的 APL 语言,由 Knuth 大力推广——它是编程思想(布尔值即 0/1)反哺数学记号的典范。
第 2 章的后半还有一套常被跳过的重武器:有限微积分(finite calculus)。定义差分算子 $\Delta f(x) = f(x+1) - f(x)$,它是导数的离散对应;再定义下降阶乘幂 $x^{\underline{m}} = x(x-1)\cdots(x-m+1)$(共 $m$ 个递减因子),则有一条漂亮的平行定理:$\Delta(x^{\underline{m}}) = m\,x^{\underline{m-1}}$,对应的不定和公式 $\sum_{0 \le k < n} k^{\underline{m}} = n^{\underline{m+1}}/(m+1)$ 就是幂函数积分的离散版。普通幂拆成下降幂(比如 $k^2 = k^{\underline{2}} + k^{\underline{1}}$)之后,平方和公式三行就出来了;章末的**分部求和(summation by parts)**则把分部积分整套搬了过来。有限微积分的意义在于:一整类多项式与阶乘幂的求和变成了查表,不再需要每题一灵感。
最后补一条书中反复强调的边界:以上所有形式操作默认和式是有限或绝对收敛的。对无穷和式随意交换次序、随意套用扰动,会撞上经典悖论——形式方法的自由是有边界的,边界叫收敛性。
四、整值函数与数论:floor、ceiling 与欧几里得
第 3 章处理一个工程师天天用、却很少细想的对象:下取整 $\lfloor x \rfloor$ 与上取整 $\lceil x \rceil$。核心性质几条就够日常防身:
- 界定:$x - 1 < \lfloor x \rfloor \le x$;镜像关系 $\lceil x \rceil = -\lfloor -x \rfloor$;
- 判定式:$\lfloor x \rfloor = n$ 当且仅当 $n \le x < n+1$——这条“把取整翻译成不等式”的等价式是证明一切 floor 恒等式的钥匙;
- 整数进出:$\lfloor x + n \rfloor = \lfloor x \rfloor + n$(整数可以自由进出取整号)——看似显然,却是 floor 恒等式证明里被用得最多的动作;
- 取模的定义式:$x \bmod y = x - y\lfloor x/y \rfloor$,它让 $\bmod$ 在负数和小数上也有确定含义;
- 同余的代数:$(a + b) \bmod m$ 可以先各自取模再相加(乘法同理)——这是大数计算不溢出、哈希设计不散架的基本功。
第 3 章还有一类硬功夫是含 floor/ceiling 的和式:把求和区间按 floor 值的变化点切开(“区间划分”技巧),一个看似无规律的取整和就被拆成几段普通和式。本章最让人意外的收尾是瑞利定理(Beatty 序列,又称谱定理):若 $\alpha, \beta$ 是正无理数且 $1/\alpha + 1/\beta = 1$,则两个序列 $\lfloor n\alpha \rfloor$ 与 $\lfloor n\beta \rfloor$($n = 1, 2, 3, \ldots$)不重不漏地恰好划分全体正整数——取整这种“坑坑洼洼”的运算,竟然能产出完美的划分。
第 4 章进入数论,主线清晰:整除与最大公约数、素数与唯一分解定理、互素与欧拉 $\varphi$ 函数、模运算。章首的技术核心是欧几里得算法:
$$\gcd(m, n) = \gcd(n,\, m \bmod n)$$
及其扩展形式(把 $\gcd$ 表成 $m’ m + n’ n$ 的线性组合)。唯一分解定理(每个正整数分解为素数幂的乘积且方式唯一)是全章的地基,阶乘中素因子次数的计算(Legendre 公式:$n!$ 中素数 $p$ 的次数为 $\sum_{k \ge 1} \lfloor n/p^k \rfloor$)是它的漂亮应用。$\varphi(n)$ 计“与 $n$ 互素的剩余类个数”,乘性公式 $\varphi(n) = n \prod_{p \mid n}(1 - 1/p)$ 一条就够记住。
这一章还有三件值得单独记住的东西:一是约数求和恒等式 $\sum_{d \mid n} \varphi(d) = n$——把 $1$ 到 $n$ 按“与 $n$ 的最大公约数”分桶即可一行证出;二是 Stern-Brocot 树:从 $0/1$ 与 $1/0$ 两个哨兵出发,不断插入相邻分数的中位分数(mediant)$\frac{m+m’}{n+n’}$,能生成全部正有理数,每个恰好一次且自动是最简形式——这是连分数与有理逼近理论的入口;三是中国剩余定理的一个具体例子:模 3 余 2、模 5 余 3 的数,在模 15 意义下被唯一确定(就是 8)——一般定理不过是这个例子的机械推广,书里强调的思想是局部余数信息可以无损拼出全局。
五、二项式系数:恒等式的丛林与机械化证明
第 5 章是全书最厚、也最容易迷路的一章:二项式系数的恒等式多到像丛林。正确的读法是抓住少数几条“母恒等式”,其余都是它们的子女。
- 定义与基本款:$\binom{n}{k} = \binom{n}{n-k}$(对称),加法公式 $\binom{n}{k} = \binom{n-1}{k} + \binom{n-1}{k-1}$(帕斯卡三角的生成规则),吸收恒等式 $k\binom{n}{k} = n\binom{n-1}{k-1}$(把下标里的 $k$ 吸出去)。
- 平行求和(曲棍球棒恒等式):$\sum_{0 \le k \le n} \binom{r+k}{k} = \binom{r+n+1}{n}$——沿帕斯卡三角斜着加,和落在下一行,是处理“带前缀的二项式求和”的第一反应。
- 二项式定理:
$$(x + y)^n = \sum_{k=0}^{n} \binom{n}{k} x^k y^{n-k}$$
令 $x = y = 1$ 得全体二项系数之和为 $2^n$;令 $x = -1$ 得交错和为 $0$——“代入特殊值”本身就是制造恒等式的流水线。
- 三项式系数与多项式定理是二项式的直接推广,拆开字母逐个分配即可。
丛林里还有两条路标值得记住:范德蒙德卷积 $\sum_{k} \binom{r}{k}\binom{s}{n-k} = \binom{r+s}{n}$——组合解释是“从 $r+s$ 个元素里选 $n$ 个,按从第一堆里选了几个分类”,它展示了组合论证与代数恒等式的互译;上指标取反 $\binom{r}{k} = (-1)^k \binom{k-r-1}{k}$,把上指标推广到负数,是生成函数展开里处理负幂的常备变换。
这一章真正的“现代”内容在末尾:大量二项式恒等式可以写成超几何级数的标准形式,而 Gosper 算法能机械地判定一个超几何项是否有闭式不定和、有就直接算出来——也就是说,曾经需要灵感的恒等式证明,有相当大一类已经被算法化了。这是全书精神最锋利的一次展示:连“证明数学恒等式”这件事本身都可以具体化、机械化。
六、特殊数:给高频出现的数建档案
第 6 章给一批在计数问题里反复冒头的“特殊数”立档案,每个都值一行记住:
- 斯特林数分两类,记住口诀“子集与轮换”:第二类 $\left\{ {n \atop k} \right\}$ 是把 $n$ 个元素划分成 $k$ 个非空子集的方案数;第一类 $\left[ {n \atop k} \right]$ 是把 $n$ 个元素排成 $k$ 个轮换的方案数。第二类的递推是 $\left\{ {n \atop k} \right\} = k \left\{ {n-1 \atop k} \right\} + \left\{ {n-1 \atop k-1} \right\}$——第 $n$ 个元素要么自立门户,要么加入已有 $k$ 个子集之一。
- 斯特林数还是翻译器:$x^n = \sum_{k} \left\{ {n \atop k} \right\} x^{\underline{k}}$,普通幂与下降阶乘幂之间的互译靠它完成——这一式把第 2 章的有限微积分和本章的计数数列缝在了一起。
- 欧拉数数的是排列中“上升”的个数——这是分析插入类排序时会自然冒出来的数。
- 调和数 $H_n = \sum_{k=1}^{n} \frac{1}{k}$,全书最重要的渐近式之一:$H_n = \ln n + \gamma + O(1/n)$,其中 $\gamma$ 是欧拉常数。快速排序平均比较次数、优惠券收集问题,答案里全是 $H_n$。
- 斐波那契数:$F_n = F_{n-1} + F_{n-2}$,下一章用生成函数一次性解出闭式;顺记其渐近:$F_n$ 最接近 $\phi^n/\sqrt{5}$,增长率由黄金比例封顶。
- 卡塔兰数 $C_n = \frac{1}{n+1}\binom{2n}{n}$:合法括号序列、二叉树形状数、栈置换数——凡是“任意前缀中左括号不少于右括号”的计数,答案都是它。
这一章的读法是当字典用:不必一次背下所有递推,但要建立“这个长相的问题答案里会出现哪种数”的条件反射。
七、生成函数:把数列打包成幂级数
第 7 章是全书皇冠。思想一句话:把数列 $g_0, g_1, g_2, \ldots$ 打包成幂级数 $G(z) = \sum_{n \ge 0} g_n z^n$。打包之后,对数列的操作全部翻译成对级数的代数运算——这就是我私下叫它“数列的 DSL”的原因:
flowchart LR
S["数列操作"] --> T["生成函数对应物"]
S1["整体平移下标"] --> T1["乘或除以 z"]
S2["逐项乘 n"] --> T2["求导再乘 z"]
S3["两个数列卷积"] --> T3["两个级数相乘"]
S4["前缀和"] --> T4["乘 1/(1-z)"]
style T fill:#e8f5e9
常用生成函数其实就一小张表:$\frac{1}{1-z} = \sum_{n \ge 0} z^n$ 对应全 1 数列,$\frac{1}{(1-z)^2} = \sum_{n \ge 0} (n+1) z^n$ 对应自然数序列,$e^z = \sum_{n \ge 0} z^n/n!$ 是指数生成函数的入口。背下这三条,再配上平移、求导、卷积三个操作,大多数有理型生成函数都能徒手展开。
解递推的标准流水线因此变成纯机械三步:递推两边乘 $z^n$ 求和 → 解出 $G(z)$ 的有理式 → 部分分式展开读系数。斐波那契是标准演示:递推代入得 $F(z) = \frac{z}{1 - z - z^2}$,分母用黄金比例 $\phi = \frac{1+\sqrt{5}}{2}$ 与 $\hat{\phi} = \frac{1-\sqrt{5}}{2}$ 因式分解,部分分式后读出比内公式(Binet formula):
$$F_n = \frac{\phi^n - \hat{\phi}^n}{\sqrt{5}}$$
卡塔兰数则是卷积解法的标准演示:由递推 $C_{n+1} = \sum_{k} C_k C_{n-k}$ 知生成函数满足二次方程 $C(z) = 1 + z\,C(z)^2$,解出 $C(z) = \frac{1 - \sqrt{1-4z}}{2z}$,再用广义二项式定理展开读系数,$\frac{1}{n+1}\binom{2n}{n}$ 就掉出来了。
整章的信息量很大,但骨架就是这一句:递推是数列的“源码”,生成函数是编译器,闭式是编译产物。 卷积对应乘法则让生成函数同时成为计数工具——把“选法”按规模分母,乘起来就读出组合方案数。
八、离散概率与渐近:期望的算术与 O 的纪律
第 8 章把概率论限制在离散空间重做一遍:随机变量是样本空间上的函数,期望线性性(哪怕变量不独立也成立)是本章最锋利的工具,方差度量散布。三个工程味十足的计算实例:
- 优惠券收集:集齐 $n$ 种优惠券的期望购买次数是 $E = n H_n$——把过程按“已收集到 $k$ 种”切成 $n$ 个阶段,每阶段是几何分布,期望直接相加。这是期望线性性最经典的演示:变量不独立也没关系,期望照样可加。
- 生日悖论:$n$ 个人生日全不同的概率是 $P = \prod_{k=1}^{n-1}(1 - k/365)$,代入数值可知 23 人左右就跌破一半——所有用随机 ID 的系统都该对这个数有直觉。
- 哈希分析:拉链法下,设装填因子 $\alpha = n/m$,成功查找的平均探查次数用期望线性性直接算出,约为 $1 + \alpha/2$——装填因子是唯一旋钮,这个式子就是哈希表扩容阈值的理论出处。
概率生成函数 $G_X(z) = \sum_{k} P(X = k)\, z^k$ 把第 7 章的机器整套搬进概率:分布的各阶矩可以从导数里读出,均值 $E(X) = G’_X(1)$,方差 $\mathrm{Var}(X) = G’’_X(1) + G’_X(1) - (G’_X(1))^2$——算矩变成了求导加代值的机械操作。注意一个不对称:期望可加不需要独立性,方差可加却需要(准确说是不相关)——这是实战里最容易踩的坑。
独立随机变量之和的概率生成函数等于各自生成函数的乘积——“独立和”在生成函数世界里就是乘法,这是卷积对应的概率版本,也是分析“多次独立试验总代价”的标准入口。
第 9 章给“量级”立规矩。大 O 的精确定义:$f(n) = O(g(n))$ 当且仅当存在常数 $C$ 使 $|f(n)| \le C|g(n)|$ 在定义域上成立。运算规则要当语法记:$O(f) + O(g) = O(f + g)$,$O(f) \cdot O(g) = O(f \cdot g)$,常数因子被吸收即 $O(C f) = O(f)$。常见坑书里都点了名:等号只能从左往右读——$n^2 = O(n^3)$ 合法,反过来写是语法错误;O 里藏着看不见的常数,所以“两个实现同为 O(n)”不包含任何比较信息。O 不是一个值,是一个吸收记号。
书里顺带给出一张该背下来的量级阶梯:$\log n \prec n \prec n \log n \prec n^2 \prec 2^n \prec n!$($\prec$ 表示“渐近意义上严格小”)。遇到复杂表达式先把各项归到这条阶梯上,主次立刻分明——这是渐近分析的第一直觉训练。
尾式交换(tail swap)是本章一个漂亮的通用技巧:当一个和式的尾部难算时,利用被求和量的对称性或单调性,把尾部换成结构相同但好算的镜像部分——很多“首尾呼应”的恒等式证明背后都是这一招。
章尾是两件重器:欧拉求和公式和斯特林渐近公式。欧拉求和公式的一阶形态是
$$\sum_{a \le k < b} f(k) = \int_a^b f(x)\, dx + \frac{f(a) + f(b)}{2} + \cdots$$
它把“用积分逼近和式”从粗略估计变成带修正项的严格展开;令 $f(x) = \ln x$ 代入并对误差项做渐近分析,就得到斯特林公式:
$$n! \sim \sqrt{2\pi n}\, (n/e)^n$$
取对数即 $\ln n! = n\ln n - n + O(\log n)$——排序下界 $n \log n$ 里的那个 $n \log n$ 就是从这里来的,接上了 TAOCP 卷 3 的信息论论证。
九、落到工程实践:这本书改变了什么
九章的武器收拢成日常纪律,一共七条:
- 什么时候值得求闭式解。 容量规划、复杂度精算、协议参数推导——凡是“答案要进 Excel 或设计文档”的场合,闭式解比模拟程序值钱:它能代入、能求导、能看出参数敏感度。反过来,一次性的、答案只用一个数值的问题,别硬求闭式,直接算。
- Iverson 括号是代码评审的语言。 “当 x 为偶数且未越界时累加”这类口头描述歧义丛生,写成 $\sum_k a_k [k \text{ 为偶数}][k < n]$ 就没有歧义。评审里坚持“把条件写成显式谓词”,是从这一章借来的纪律。
- 生成函数当 DSL 用。 遇到“按规模计数”的需求(消息组合数、状态转移路径数),先想能不能写出递推;能写出递推,生成函数流水线就是确定的求解路径,不必靠灵感。
- 渐近思维的纪律与大 O 滥用。 “这是 O(n²)”不是分析的终点:常数多大、输入规模落在哪个区间、低阶项什么时候反超,第 9 章训练的就是这种追问。见过太多拿大 O 当挡箭牌、把 $100n$ 和 $n^2/100$ 在 $n = 1000$ 下混为一谈的事故。
- 扰动法与区间划分可以直接进性能分析。 循环里带取整、带分支条件的代价累加,本质上就是含 floor 的和式:按跳跃点切开区间分段求和,比“拍个上界”准确得多。第 2、3 章的技巧是精确复杂度分析的扳手。
- 机械化证明改变了“恒等式”的处境。 Gosper 算法的存在意味着:评审一个组合恒等式时先问“这能不能机判”,能机判的就不值得人肉推导——把人的精力留给机判不了的部分。这个分工原则对一切“已被算法化的技能”都成立。
- 对“算得出来”的信仰。 这本书最深的影响是态度上的:遇到和式、递推、取整,默认它是可以算的,只是还没找到对的技巧。把“大概”“估计”换成“我算算看”,是这本书送给工程师最好的礼物。
本篇小结
- 书名 Concrete 是 continuous + discrete 的文字游戏:教的是“能算出来、能推广成闭式”的数学;源自斯坦福课程,是 TAOCP 的数学地基;页边涂鸦与习题六档分级是这本书独有的气质与路线图。
- 第 1 章立方法论:小情形 → 猜测 → 归纳证明,外加套招法;约瑟夫问题的答案是二进制循环左移,$J(2^m+\ell) = 2\ell+1$;漂亮闭式是运气,方法论是常态。
- 第 2-3 章是基本功:扰动法与求和因子(快排平均比较次数 $2(n+1)H_n - 4n$ 就是这么算出来的)、Iverson 括号消灭特例讨论、有限微积分把求和变查表、floor/ceiling 的不等式翻译与区间划分、瑞利定理。
- 第 4-6 章是组合核心:欧几里得算法与唯一分解、Stern-Brocot 树、二项式恒等式丛林与 Gosper 机械化证明、斯特林数/调和数/斐波那契/卡塔兰数档案。
- 第 7-9 章是分析武器:生成函数把递推编译成闭式(Binet 公式是标准产物)、期望线性性算优惠券收集与生日悖论、概率生成函数算矩、大 O 的精确定义与运算语法、欧拉求和公式推出斯特林渐近。
- 工程落地一句话:该求闭式时别满足于模拟,该谈常数时别躲进大 O。
这本书和 TAOCP 放在一起读效果最好:TAOCP 告诉你账要算,这本书教你账怎么算。读完后我写性能分析报告的习惯变了——先递推,再闭式,最后才轮到 profiler。
参考资料
- Ronald L. Graham, Donald E. Knuth, Oren Patashnik, Concrete Mathematics: A Foundation for Computer Science, 2nd ed., Addison-Wesley, 1994(初版 1989)。中译本《具体数学:计算机科学基础》,人民邮电出版社。
- Donald E. Knuth, “Two Notes on Notation”, American Mathematical Monthly, 1992(Iverson 括号与斯特林数记号的推广短文)。
- Ralph W. Gosper, Jr., “Decision procedure for indefinite hypergeometric summation”, Proceedings of the National Academy of Sciences, 1978(第 5 章机械化证明的原始论文)。
- Donald E. Knuth, The Art of Computer Programming, Volume 1(本书是其中数学预备知识的完整展开)。