资讯详情

资讯详情

级数、p级数与调和级数:收敛判断、斜率与算法复杂度

1. 级数到底是什么无限次加法这件反直觉的事先说结论级数就是把一个数列的项一路加下去。如果你只记住一句话就记这句。数列是 (a_1, a_2, a_3, \dots)级数是 (a_1 a_2 a_3 \cdots)。写成数学符号是 (S \sum_{k1}^{\infty} a_k)。这个操作在直觉上就让人不安——东西越加越多最后还能剩下一个有限的数吗p级数、调和级数、等比数列求和公式和等差数列求和、斜率这几个概念看上去散落在不同章节其实是同一条线上的东西都在回答怎么把一堆离散的量汇总成一个结论。斜率是在回答两个汇总之间谁增长得更快等差和等比求和公式是怎么快速汇总而级数是汇总到无穷还收得住吗。我在做算法复杂度评估和实验数据拟合的时候这几个东西几乎每周都会撞见一次。判断一段代码跑不跑得动要看循环次数累加出来是 O(n) 还是 O(log n)判断一个采样序列的误差能不能被压住其实就是在判断某个级数收不收敛在双对数坐标下画一条趋势线那条线的斜率直接告诉你增长幂次。这些都是同一套底层语言。那么这篇适合谁看如果是刚接触数列极限的大学生可以把它当作一条把课本散点串起来的线索如果是已经工作、需要算复杂度、做数据拟合、写数值程序的开发者可以重点看后面关于收敛速度、边界条件、浮点误差那几节那是我真正踩过坑的地方。先澄清一个概念很多人卡在这一步数列和级数是两件事。数列是一个个孤立的数级数是这些数的累加结果。数列的通项可以无限趋于 0但级数照样可能发散——调和级数就是最经典的反例。这一点后面会重点拆开说。2. p级数一个指数决定了收敛还是发散2.1 p级数的定义与三个标杆p级数的标准写法是[ \sum_{n1}^{\infty} \frac{1}{n^p} 1 \frac{1}{2^p} \frac{1}{3^p} \frac{1}{4^p} \cdots ]判据非常干脆(p 1) 收敛(p \le 1) 发散。就这么一条线把一个家族劈成两半。这个结论不需要背理解了积分判别法自然就记住了。我平时用三个标杆来判断量级p 取值级数形式结果常被用来做什么p 1调和级数发散极慢反例、下界估计p 2(\sum 1/n^2)收敛和 ≈ 1.644934误差平方和、能量估计p 略大于 1(\sum 1/n^{1\varepsilon})收敛但余项衰减很慢理论收敛性证明p 0.5(\sum 1/\sqrt{n})发散说明趋于0不够最后一行特别值得盯一眼。(1/\sqrt{n} \to 0)但它的和发散。这就是为什么判断收敛不能只看通项是否趋于零——通项趋于零是必要条件不是充分条件。这个坑我在给一个模拟项目做误差分析时真的掉进去过当时看到每一项都在变小就默认总和有上界结果跑了几万次迭代发现累积量一直在涨回头一查衰减速度是 (1/\sqrt{n}) 量级根本不收敛。2.2 为什么临界点偏偏是 p 1积分判别法把这个为什么讲得很干脆。函数 (f(x) 1/x^p) 在 ([1, \infty)) 上单调递减所以级数的和与积分 (\int_1^{\infty} x^{-p} dx) 同进退。当 (p \ne 1) 时(\int_1^{N} x^{-p} dx \dfrac{N^{1-p} - 1}{1-p})当 (p 1) 时(\int_1^{N} x^{-p} dx \ln N)看这个结果就明白临界点的来历了。(N^{1-p}) 当 (N \to \infty) 时如果 (1-p 0) 也就是 (p1)它趋近于 0积分收敛如果 (p1)它爆炸积分发散。而 (p1) 正好落进了 (\ln N) 这个裂缝里对数增长没有上界所以发散。用生活化的话说(\ln N) 是慢到离谱的无限它无限大但大得非常吝啬。每翻一倍(\ln N) 只多一点点。这种温柔的发散正是调和级数最折磨人的地方也是它区别于 (1/\sqrt{n}) 那种粗暴发散的关键——你可以靠增加项数去收敛 (1/\sqrt{n}) 之外的某些东西但调和级数你无论加多少项它终究会超过任何一个目标值只是可能慢到你等不到。2.3 关于q级数这个叫法这里必须插一句因为检索资料里这个说法经常混着出现容易把人绕晕。我在几个不同来源里都见过q级数这个词但它不是标准术语通常有两种含义第一种是有人把 p级数里的字母 p 换成 q写成 (\sum 1/n^q)本质完全一样就是 p级数。这种写法多见于一些教材喜欢用 q 表示指数。第二种是指等比级数也叫几何级数(\sum_{n0}^{\infty} a q^n)这里的 q 是公比。这个解释更常见因为 q 作为 ratio比的首字母在英文教材里非常通用。区分方法很简单看下标在指数位置还是底数位置。(\frac{1}{n^q}) 是 p级数变体(a q^n) 是等比级数。前者收敛条件是 (q1)后者收敛条件是 (|q|1)——恰恰相反。我在给某实验室做算法收敛性评审时就见过一份文档里两种含义混用导致后面推导出来的阈值是反的团队跑了一周才发现方向错了。这种低级但致命的错误往往就藏在符号不统一上。等比级数的收敛结论值得单独记住[ \sum_{n0}^{\infty} q^n \frac{1}{1-q}, \quad |q| 1 ]当 (|q| \ge 1) 时发散。注意 (q 1) 时每一项都是 1和显然爆炸(q -1) 时和是 (1-11-1\cdots)部分和在 0 和 1 之间跳不收敛。(|q|1) 这条边界上两个方向都不收敛这点很多人只记得 (q1) 而忘了 (q-1) 也麻烦。3. 调和级数这个名字到底从哪里来3.1 三股来源汇成的一个名字调和两个字最容易让人一头雾水——它明明就是 (1 1/2 1/3 1/4 \cdots)看起来跟和谐调合没有任何关系。我查过也琢磨过这个名字至少有三股来源它们最后拧在了一起。第一股是音乐。英文的 harmonic 源自希腊语 harmonia本义是接合、协调。古希腊人研究弦长和音高的关系时发现把一根弦按 1:2、2:3、3:4 的比例分割能得到八度、五度、四度这几个最悦耳的音程。这些比例对应的频率正是 2:1、3:2、4:3也就是整数比的倒数关系。一组弦如果长度分别是 (1, 1/2, 1/3, 1/4\dots)它们发出的音就构成天然的泛音列基频的整数倍。这串长度比写出来就是调和级数。第二股是调和平均。给定若干正数 (a_1, \dots, a_n)它们的调和平均定义为[ H \frac{n}{\dfrac{1}{a_1} \dfrac{1}{a_2} \cdots \dfrac{1}{a_n}} ]两个数时简化成熟悉的 (H \frac{2ab}{ab})。分子是 (n)分母是所有数的倒数之和。注意看这个分母——它就是调和级数的部分和。所以调和级数的部分和本质上是调和平均的分母。名字就这么传下来了。第三股是最直观的它是等差数的倒数。(1, 1/2, 1/3, 1/4, \dots) 的倒数分别是 (1, 2, 3, 4, \dots)这是一个标准的等差数列。数学上的命名传统是如果一个数列的倒数构成等差数列就称它为调和数列。它的累加就是调和级数。这三股来源我建议都记住因为考试和应用场景不一样。做理论的时候用第三股倒数成等差最快做信号处理看频谱的时候用第一股泛音列最直观做均值计算的时候用第二股调和平均最顺手。3.2 为什么它明明在变小却发散这是初学阶段最大的认知坎。通项 (1/n \to 0)可和却是无穷大。我给几个证明从最容易理解到最严谨排列。分组法最快的直观。把项按 (1/2, 1/4, 1/8\dots) 分组[ \begin{aligned} 1 \frac{1}{2} \ \left(\frac{1}{3} \frac{1}{4}\right) \frac{1}{2} \ \left(\frac{1}{5} \cdots \frac{1}{8}\right) \frac{1}{2} \ \left(\frac{1}{9} \cdots \frac{1}{16}\right) \frac{1}{2} \end{aligned} ]每一组都有 (2^{k}) 项每项都不小于组内最小的那项 (1/2^{k1})所以每组之和都大于 (1/2)。组数无限总和自然无限。这个证明漂亮在它只用了最基本的放缩不需要任何工具。反证法结构上优雅。假设 (S) 收敛。把项按分母奇偶分成两部分[ S \left(1 \frac{1}{3} \frac{1}{5} \cdots\right) \left(\frac{1}{2} \frac{1}{4} \frac{1}{6} \cdots\right) O \frac{S}{2} ]右边第二块提个 (1/2) 出来正好是 (S/2)。再看奇数组 (O)每一项 (1/(2k-1)) 都大于 (1/(2k))所以 (O S/2)。代回去得到 (S S)矛盾。这里有个细节必须提醒也是我给学生讲题时的重点只有先假设 (S) 收敛才能做这种拆分和重排。条件收敛的级数在重排后可能改变和这是个大坑。如果你直接对调和级数的项做重排然后比较逻辑是站不住的。4. 等差与等比两种求和公式背后的巧劲4.1 等差数列倒序相加是怎么想出来的等差数列求和公式人人都会背[ S_n \frac{n(a_1 a_n)}{2} n a_1 \frac{n(n-1)}{2} d ]但为什么能写成这样值得多花两分钟。这个方法叫倒序相加思路是把同一列数正着写一遍、倒着写一遍对应项相加[ \begin{aligned} S_n a_1 (a_1d) \cdots (a_1(n-1)d) \ S_n a_n (a_n-d) \cdots (a_n-(n-1)d) \end{aligned} ]两式相加对应项之和恒为 (a_1 a_n)你减 (d) 我加 (d)正好抵消共有 (n) 对于是 (2S_n n(a_1a_n))。这个技巧能成立的核心条件是等差数列的对称性从两端往中间走每一步的增量完全抵消。这就是为什么它不能直接套到等比数列上——等比数列对应的抵消方式是乘法消除不是加法消除。这个区别后面讲错位相减时会讲透。我给一个实际用得到的场景估算一段固定步长的循环总共执行了多少次操作。比如从第 100 次循环开始每次加 3跑到第 500 次问总操作数。这就是 (a_1100, d3, n401)直接套 (S 401 \times 100 \frac{401 \times 400}{2} \times 3 40100 240600 280700)。手算三十秒的事写代码跑一遍要调试五分钟。4.2 等比数列错位相减的乘法版等比数列求和[ S_n \begin{cases} \dfrac{a_1(1 - q^n)}{1 - q}, q \ne 1 \[6pt] n a_1, q 1 \end{cases} ]推导路径是错位相减。设 (S_n a_1 a_1 q a_1 q^2 \cdots a_1 q^{n-1})两边同乘 (q)把新式子往右错一位[ \begin{aligned} S_n a_1 a_1 q a_1 q^2 \cdots a_1 q^{n-1} \ q S_n \phantom{a_1 {}} a_1 q a_1 q^2 \cdots a_1 q^{n-1} a_1 q^n \end{aligned} ]相减中间一大片全部销掉只剩头尾两项[ (1-q)S_n a_1 - a_1 q^n ]这个错一位的动作是全部关键。为什么错一位因为做题人真正想干的是制造对齐后的消去。等比数列每项都是前一项的 (q) 倍所以你乘一个 (q) 之后新序列的每一项都和原序列的后一项完全相等——这不就是为消去量身定做的吗。这里有个极易翻车的边界条件(q1)。公式里分母 (1-q) 会变成 0。很多人写代码时直接照抄公式结果当比值恰好等于 1 时程序抛除零异常或者返回 NaN。我在一个数据缩放模块里见过这个 bug缩放因子默认取 1 表示不缩放一路跑得好好的直到某个边界输入真的触发了 (q1)整批数据变成 NaN而且这些 NaN 会沿着后续计算一路污染下去。修复方法就一行先判 (q \approx 1)走 (S n a_1) 分支。别忘了用容差判断浮点数里的 1 很少是精确的 1。如果 (|q| 1) 且 (n \to \infty)(q^n \to 0)无穷等比级数的和收敛到[ S \frac{a_1}{1 - q} ]这条公式是被用滥的但用滥不代表用错——很多场景下的总收益总误差总缓存占比估算就是这条公式在撑着。比如一个缓存的命中率每轮衰减到上一轮的 (q) 倍问累计能命中多少次直接套这个。4.3 两种求和方式的对照与迁移把这两个方法放在一起看规律就出来了对比项等差数列等比数列结构特征相邻项差恒定相邻项比恒定求和技巧倒序相加错位相减消除机制加减法抵消乘除法抵消临界情况无(d0) 时退化为常数(q1) 时分母为零无穷和一般不收敛除非 (d0)(|q|1) 时收敛这张表我建议自己手画一遍画的过程比看的过程印象深得多。表格之外还有一个更高阶的用法差比混合数列的求和。比如 (\sum_{k1}^{n} k \cdot q^{k-1})这是等差数列乘等比数列求和仍然用错位相减但要减两次。这个技巧在算期望值、算加权平均衰减时经常碰到。我处理过一组带权重的历史数据平滑权重随时间指数衰减做加权求和的时候就是这种结构一开始硬算后来发现公式化以后直接从 (O(n)) 降到 (O(1))。5. 斜率把谁涨得快翻译成一个数5.1 定义很简单理解不容易斜率的标准定义[ k \frac{\Delta y}{\Delta x} \frac{y_2 - y_1}{x_2 - x_1} ]它的含义是横轴每走一个单位纵轴平均变化多少。这个每单位是关键很多人做题时算了半天比值却说不清这个数到底代表什么。斜率为 3意思是横轴每走 1纵轴就走了 3斜率为 -0.5意思是横轴走 1纵轴反而退 0.5。几何上斜率就是直线与横轴正方向夹角的正切值(k \tan\theta)。这个关系把代数和几何接上了好处是有的问题从图形上一眼能看出来。比如两条直线垂直斜率乘积是 -1这就是 (\tan\theta \cdot \tan(\theta 90°) -1) 的推论。有个必须记住的边界垂直于横轴的直线没有斜率。因为 (\Delta x 0)除零。它的方程必须写成 (x c) 的形式。写程序的时候这一点尤其要紧——用 ((\Delta y/\Delta x)) 拟合直线遇到两个点横坐标相同就会直接崩。我的处理习惯是拟合前先按 (x) 排序检查有没有重复 (x)如果有要么合并去重要么改用其他参数化方式。5.2 斜率和前面几个概念的真实联系这一节是我最想写的因为大部分人学到斜率就停住了不知道它跟级数、跟复杂度分析是怎么串起来的。第一层联系斜率和等差数列关系最直接。在直角坐标系里画等差数列所有点都落在同一条直线上这条直线的斜率就是公差 (d)。所以判断一个序列是不是等差等价于判断它的散点是否共线而斜率就是公差。反过来给一个点的位置和斜率就能推出整个等差数列。这个视角转换在做数据校验的时候特别好用把序列画出来肉眼扫一眼是不是直线比逐项算差值快得多。第二层联系对数坐标下斜率变成了幂次。这一条对做算法的人价值极大。如果实际关系是 (T c \cdot n^{p})那么两边取对数[ \log T \log c p \log n ]在双对数坐标系里这是一条直线斜率正好等于指数 (p)。所以只要把不同规模下的耗时数据画在双对数图上量一下斜率就能直接读出时间复杂度双对数图斜率对应复杂度典型场景约 0O(1)哈希表查找约 1.0O(n)单层遍历约 1.1 ~ 1.2O(n log n)排序对数项影响斜率微增约 2.0O(n²)双重循环约 3.0O(n³)矩阵乘法朴素实现这张表是我在实际做性能评估时用的最笨也最可靠的办法。理论分析容易漏掉常数项和隐藏循环实测斜率是骗不了人的。有一次我把一个算法标称成 O(n log n)画出来斜率接近 1.8继续往上爬没收敛到 1.2 附近最后发现里面嵌了一层我没注意到的哈希冲突扫描实际接近 O(n²)。靠观察数据趋势而不是依靠文档描述这个习惯帮我省了很多返工。第三层联系级数的余项衰减速度可以看成某种平均斜率。(p) 级数的余项 (R_n \sum_{kn} 1/k^p)当 (p2) 时大约按 (1/n) 衰减衰减指数就是 (p-1)。这个衰减指数在工程上就是误差收敛速率换句话说它就是某种意义上的斜率。所以你看从级数到斜率中间根本不需要绕路。6. 常见问题与排查技巧实录6.1 一张速查表顶十次翻书下面这些是我在答疑和自查中反复碰到的错误整理成表遇到问题先扫一眼症状可能原因排查动作通项趋于 0 就断定级数收敛混淆了必要条件和充分条件检查是否有 (1/n) 或其量级的分母(q1) 时程序返回 NaN等比求和公式分母为零加分支判断用容差而非精确相等等比级数在 (q-1) 时判断不出结果只检验了 (q1)用 (|q|) 判断别用 (q)拟合直线斜率为无穷两个采样点横坐标相同排序查重或改用隐式方程等比求和误差随 (n) 增大直接对大数做幂运算后相减变形为 (a_1 \cdot q^{n-1} \cdot (q - 1)/(q-1)) 或分段计算调和级数部分和估算差距很大用小 (n) 硬算、没考虑 (\ln n) 项用 (H_n \approx \ln n 0.5772) 快速估计p级数判断收敛但实际数值跑不出来收敛太慢(n) 不够大看 (p) 是否接近 1接近就换更快的加速法这张表里最后两行是我最想强调的下面展开。6.2 关于调和级数的那点慢值得单独说调和级数的部分和有个非常好用的近似[ H_n 1 \frac{1}{2} \cdots \frac{1}{n} \approx \ln n \gamma, \quad \gamma \approx 0.5772 ]这个 (\gamma) 叫欧拉常数就是实际和与 (\ln n) 之间稳定存在的那个差。它到底有没有更简单的表达式到现在还是开放问题但工程上用这三位小数绰绰有余。有了这个式子很多事情可以秒算。比如问部分和什么时候能超过 10解 (\ln n 0.5772 10)得到 (\ln n 9.4228)(n e^{9.4228} \approx 12367)。也就是说你需要加一万两千多项和才勉强爬到 10。这个数字第一次看到的时候挺震撼的——一万多项的累加结果才刚刚到两位数。这就是温柔发散的具象化。你要是想让它超过 100需要 (e^{99.4}) 量级的项数这个数比宇宙里的原子总数还多得多。这一条经验直接指导了我的实现选择凡是需要精确计算调和级数部分和的场景不要指望通过加大迭代次数改善精度因为误差是按 (\ln n) 增长的加大 (n) 收益极低。要么用近似公式要么在数学上改写问题绕过它。6.3 三条从实操里磨出来的心得第一条数值求和一定要考虑累加顺序。计算 (\sum 1/k^2) 时如果从 (k1) 开始顺着加到很大的 (n)前面的项数值大会把后面很小的项在浮点数精度上吃掉——加进去毫无变化。正确做法是从大 (k) 往小 (k) 反向累加或者用 Kahan 求和这类补偿技术。我在一个误差分析的模拟程序里吃过这个亏算出来的和一直比理论值 (\pi^2/6 \approx 1.6449) 差一点查了半天公式都对最后发现是累加顺序的问题。改成反向累加后误差立刻降了一个数量级。第二条区分数学上收敛和数值上算得出来。p 级数当 (p 1.001) 时理论收敛但收敛速度慢到几乎看不到头余项的衰减是 (n^{-0.001}) 量级(n) 翻一倍余项几乎不动。所以工程判断不能只看收敛性判据还要看收敛速率。我的经验阈值是如果 (p 1.5)就要警惕可能需要解析解或者变换方法别硬算。第三条做斜率分析前先确认坐标轴是否真的线性。这一条听起来很蠢但我确实见过有人在普通的线性坐标上画数据然后拿手量的斜率去猜复杂度得出完全错误的结论。复杂度分析必须在双对数坐标下做因为只有取了对数幂函数才会被拉成直线。同样的道理如果一个关系不是幂律双对数图上也不会是直线斜率随时在变——这时候讨论斜率本身就没意义了得另找模型。先验证模型假设成立再谈参数估计这个顺序不能反。7. 收个尾我的个人习惯如果只让我带走一句话我会说遇到越加越多的问题先判断是收敛还是发散遇到谁涨得快的问题去算斜率遇到要算多少轮的问题去找等价的首项和公比。这三条几乎覆盖了我日常九成的数学直觉调用。我自己养成了一个很土但很管用的习惯拿一张纸把问题里的序列前五六项手写出来。1、1/2、1/3、1/4……写出来的那一刻它在变小和它会发散这两件事同时摆在眼前那种认知冲突会强迫我去想清楚背后的判别依据而不是扫一眼公式就下结论。公式是别人的手写出来的这几项才是自己的。还有一个建议给正在学的朋友不要放过名字背后的故事。调和级数为什么叫调和、斜率为什么叫斜率这些命名里藏着前人做这道题时的原始思路。搞明白名字往往比刷十道题更能建立真正的直觉。
觉得有用,分享给同行:

为您的企业打造数字门面

稳重轻奢商务风格,端正雅致视觉,长效耐看不易过时。

立即咨询 →