线性差分方程及其通解的一般求法,这个题目摆在面前的时候,大多数人脑子里浮现的是考研数学或者离散数学的那几页公式。但真正做过递推算法优化、写过动态规划的状态转移、算过分期还款表、推过马尔可夫链稳态的人会知道,线性差分方程根本不是纸上的东西,它是离散世界里最基础的一套"运动学"。连续世界用微分方程描述变化率,离散世界用差分方程描述步与步之间的增量关系,两者几乎是一一对应的孪生兄弟。区别在于,微分方程的解是函数,差分方程的解是数列;微分方程用特征方程找指数解,差分方程照样用特征方程找几何数列解。这套方法能帮你把"一步一步往前推"的暴力迭代,压缩成"一步到位"的闭式表达,从而看清一个系统的长期走势、收敛速度、是否存在周期振荡。不管你是刚开始学离散数学的学生,还是需要为算法做复杂度推导的工程师,或者只是想搞明白为什么某类递推式一定有解、解长什么样,把这套通解求法吃透,后面的路都会顺很多。接下来我会从最朴素的一阶模型开始,一层层推到高阶、推到非齐次、推到实际踩坑的排查流程,把"通解一般求法"这件事拆到可以照着抄的程度。
1. 先把差分方程这件事说清楚
1.1 从斐波那契说起:为什么"离散"需要自己的方程
斐波那契数列 aₙ = aₙ₋₁ + aₙ₋₂,这个式子就是最典型的二阶线性差分方程。它没有给出 aₙ 的显式公式,只给了相邻几项之间的关系,这叫递推关系。递推关系的优点是写起来直观,缺点是算第 100 项就得从第 1 项一路推过去,而且你根本看不出这个数列是越跑越快还是最终收敛。差分方程理论要解决的核心问题,就是把"递推关系"翻译成"通项公式",也就是所谓的通解。
这里有个概念必须先立住:微分方程里我们比较的是函数值对自变量的变化率,而差分方程里比较的是数列相邻项之间的差。记 Δaₙ = aₙ₊₁ − aₙ,那么 Δ 就是一阶差分算子,Δ²aₙ = Δ(Δaₙ) 是二阶差分算子。有了这个算子,任何递推关系都能写成算子的形式,比如 aₙ₊₂ − 2aₙ₊₁ + aₙ = 0 其实就是 Δ²aₙ = 0。这种写法之所以重要,是因为它让离散问题和连续问题在结构上对齐了:微分方程的标准形是各阶导数线性组合等于一个已知函数,差分方程的标准形是各阶差分或各阶移位项的线性组合等于一个已知数列。对齐之后,两边的方法论几乎可以平行搬运。
提示:初学者最容易混的是"移位形式"和"差分形式"。移位形如 aₙ₊₂ + p aₙ₊₁ + q aₙ = f(n),差分形如 Δ²aₙ + α Δaₙ + β aₙ = f(n)。两者可以互相转换,解题时用哪种要看你手上数据长什么样。工程里递推式天然是移位形式,所以本篇文章默认都用移位形式展开。
1.2 阶数、线性、齐次:三个标签决定解题路线
拿到一个差分方程,第一件事不是急着算,而是给它贴标签。贴完标签,解题路线基本就定了。
阶数:方程里出现的最大移位间隔。aₙ₊₁ = 2aₙ 是一阶,aₙ₊₂ = aₙ₊₁ + aₙ 是二阶,以此类推。阶数决定了特征方程的次数,也决定了通解里自由常数的个数。一个 k 阶线性差分方程的通解一定含有 k 个独立常数,这是因为它的解空间是 k 维线性的,跟 k 阶微分方程完全一致。
线性:方程里 aₙ, aₙ₊₁ … 这些项都是一次幂,没有互相乘、没有平方、没有三角函数套在里面。线性意味着叠加原理成立——如果 y₁ 和 y₂ 都是齐次方程的解,那么任意常数组合 C₁y₁ + C₂y₂ 也是解。这是整个通解理论的基石,没有它,后面所有"先求齐次通解再叠加特解"的套路都站不住脚。反过来,像 aₙ₊₁ = aₙ² + 1 这种就是非线性,只能用不动点、周期点这些工具单独分析,不在本篇范围内。
齐次与非齐次:等式右边等于零的叫齐次,等于非零数列 f(n) 的叫非齐次。非齐次方程的通解结构是"齐次通解 + 非齐次特解",这个结构也是从线性代数的解空间理论直接搬过来的。理解这一点很重要:非齐次项 f(n) 只影响特解那一部分,不影响系统的"自由运动模式",而自由模式完全由齐次部分决定。这就是为什么分析系统稳定性时,我们只看齐次方程的特征根。
注意:判断线性时,小心 f(n) 里出现 aₙ 的情况。如果非齐次项里含有未知数列本身,那方程就不是标准意义上的非齐次,需要先移项合并。这类"隐性非齐次"在应用题里特别常见,比如 aₙ₊₁ = 2aₙ + 3aₙ₋₁ + 5 看起来乱,其实是 aₙ₊₁ − 2aₙ − 3aₙ₋₁ = 5,右边是常数 5,属于非齐次。
2. 一阶线性差分方程:最小模型藏着最多直觉
2.1 齐次一阶:几何数列是怎么冒出来的
先看最简的齐次一阶方程 aₙ₊₁ = r aₙ。这个式子不用任何理论,直接迭代就能看出 aₙ = a₀ rⁿ,是等比数列。但我想强调的是,这个"猜"的过程其实有严格的逻辑:假设解具有 aₙ = λⁿ 的形式,代入 aₙ₊₁ = r aₙ 得到 λⁿ⁺¹ = r λⁿ,约掉 λⁿ(λ ≠ 0)就得到 λ = r。这里的 λ 就是特征根,特征方程是 λ − r = 0。一阶只有一根,通解就是 aₙ = C rⁿ,C 由初始条件 a₀ 定出来。
这个"假设指数形式"的手法,是后面所有高阶问题的模板。为什么可以假设指数形式?因为线性方程的解在移位操作下要保持形式不变——aₙ 变成 aₙ₊₁ 只是把指数往前提了一位,整体函数形状不变。能满足这种"移位不变性"的函数,在离散情形下只有几何数列 λⁿ,在连续情形下只有指数函数 e^{λx}。这是一个非常本质的对应关系,理解了它,特征方程法就不再是死记硬背的技巧,而是唯一合理的猜测。
关于稳定性,一阶齐次模型给出了最干净的判据:|r| < 1 时解衰减到零,系统稳定;|r| > 1 时解发散;r = 1 时解是常数(临界);r = −1 时解在 a₀ 和 −a₀ 之间来回跳,是持续振荡。这个判据在算法分析里用得极多,比如迭代法求解方程组的收敛条件,本质上就是在要求迭代矩阵的谱半径小于 1,一阶标量情形下就是 |r| < 1。
2.2 非齐次一阶:常数变易法和"稳态 + 瞬态"的分解
加上非齐次项:aₙ₊₁ = r aₙ + b,其中 b 是常数。这是分期还款、复利储蓄、种群带固定补充的模型。解法有两条路,我建议两条都掌握。
第一条路是凑特解 + 叠加齐次通解。先找一个常数特解,令 aₙ = A(常数),代入得 A = rA + b,解得 A = b/(1−r)(r ≠ 1 时)。齐次通解是 C rⁿ,所以总通解是 aₙ = C rⁿ + b/(1−r)。代入初始条件 a₀ 定 C,得到 aₙ = (a₀ − b/(1−r)) rⁿ + b/(1−r)。这个结果特别有启发:aₙ 被拆成了两部分,C rⁿ 是随时间衰减的瞬态分量,b/(1−r) 是不随时间变化的稳态分量。当 |r| < 1 时,瞬态很快消失,系统最终稳定在 b/(1−r) 这个固定点上,这个点叫不动点。很多做数值迭代的人管它叫收敛值,本质是一个东西。
第二条路是常数变易法,也就是把齐次解里的常数 C 换成一个数列 Cₙ。设 aₙ = Cₙ rⁿ 代入原方程:Cₙ₊₁ rⁿ⁺¹ = r Cₙ rⁿ + b,整理得 Cₙ₊₁ − Cₙ = b / rⁿ⁺¹。右边是个几何数列,求和得到 Cₙ,再回代即可。这条路看起来绕,但它是通用方法,当非齐次项 f(n) 不是常数而是任意数列时,只有它能走通。我个人的经验是:非齐次项是多项式、指数、三角这类"好函数"时用待定系数法凑特解,非齐次项是任意数列时用常数变易法,这是最省事的分工。
实操心得:r = 1 这个边界千万不要漏。此时 aₙ₊₁ = aₙ + b,特解不再是常数,而是 aₙ = b n,通解是 aₙ = C + b n。这个特解形式为什么多了一个 n?因为 λ = 1 恰好是特征根,"常数试解"和齐次解撞车了,需要乘一个 n 来解除重复。这个规则在高阶非齐次里会反复出现,现在记住它是值得的。
2.3 一个能直接套的还款模型算例
举一个具体的算例,把参数选择的过程走一遍。假设你贷款 100000 元,月利率 0.5%,分 36 期等额本息还款,每月还 M 元,问 M 是多少。设第 n 期还款后剩余本金为 aₙ,则 aₙ₊₁ = aₙ (1 + 0.005) − M,初始 a₀ = 100000,要求 a₃₆ = 0。
套用通解 aₙ = (a₀ − M/(1−r)) rⁿ + M/(1−r),其中 r = 1.005。要求 a₃₆ = 0,代入:0 = (100000 − M/(1−r)) r³⁶ + M/(1−r)。整理得 M = 100000 r³⁶ (1−r) / (r³⁶ − 1)。算一下 r³⁶ ≈ exp(36 × ln1.005) ≈ exp(36 × 0.0049875) ≈ exp(0.17955) ≈ 1.1967。于是 M = 100000 × 1.1967 × (−0.005) / (0.1967) ≈ 100000 × 0.005 × 1.1967 / 0.1967 ≈ 3042 元。
这个数字和市面上任何等额本息计算器的结果一致。整个推导只用了"齐次通解加常数特解"这一个套路,没有循环,没有递推,直接闭式。这就是通解求法的价值:把 36 步迭代变成一次代数运算,而且能一眼看出提前还款、利率变化对结果的影响。类似的模型换个参数就能套用到库存周转、设备折旧、种群迁移上,方法论完全一样。
3. 二阶常系数线性差分方程:通解框架的核心战场
3.1 特征方程三种根型,对应三种解的形状
二阶齐次方程的标准形式是 aₙ₊₂ + p aₙ₊₁ + q aₙ = 0。照搬一阶的思路,假设 aₙ = λⁿ,代入得 λⁿ⁺² + p λⁿ⁺¹ + q λⁿ = 0,约掉 λⁿ 得到特征方程λ² + pλ + q = 0。这是一个一元二次方程,根的情况分三种,每种对应不同的通解形状,这张表必须刻在脑子里:
| 特征根情况 | 判别式 | 通解形式 |
|---|---|---|
| 两个不等实根 λ₁, λ₂ | Δ > 0 | aₙ = C₁λ₁ⁿ + C₂λ₂ⁿ |
| 两个相等实根 λ | Δ = 0 | aₙ = (C₁ + C₂n) λⁿ |
| 一对共轭复根 ρe^{±iθ} | Δ < 0 | aₙ = ρⁿ(C₁cos nθ + C₂sin nθ) |
三种形式背后的逻辑是一样的:解必须由两个线性无关的"基解"张成。实根情形下,λ₁ⁿ 和 λ₂ⁿ 在 λ₁ ≠ λ₂ 时线性无关,直接就是基。重根情形下,λⁿ 只有一个独立方向,第二个基解要乘一个 n 才和第一个线性无关——这个"乘 n"的操作在离散情形里恰好对应连续情形里"乘 x",不是巧合,而是两个理论在重根处的共同特征。复根情形下,实数列的解不能直接写成虚数幂,必须用欧拉公式把 ρe^{±iθ} 的幂展开成 ρⁿ 乘以三角函数的组合,这样得到的才是实序列。
提示:复根情形的 ρ 是模,θ 是辐角,ρ = √q(当特征方程为 λ² + pλ + q = 0 且 Δ < 0 时,两根之积等于 q,所以 ρ² = q)。这个关系在判断振荡是否衰减时很有用:ρ < 1 衰减震荡,ρ = 1 等幅振荡,ρ > 1 发散震荡。很多人算完通解却忘了看 ρ,其实稳定性信息全藏在 ρ 里。
3.2 重根情形的系数确定:一个容易翻车的细节
重根情形 aₙ = (C₁ + C₂n) λⁿ,初始化时要用两个初始条件联立。这里有个常见错误:代入 a₀ 和 a₁ 时,λ⁰ = 1 是常数,但 λ 本身如果是负数或分数,n = 0 和 n = 1 处的值要小心算。我见过太多人把 a₀ = C₁ 直接写出来,结果 λ 是负数时符号全错。稳妥的做法是老老实实代 n = 0 和 n = 1 两个方程解 C₁、C₂,不要跳步。
举个例子:aₙ₊₂ − 4aₙ₊₁ + 4aₙ = 0,特征方程 λ² − 4λ + 4 = 0,重根 λ = 2。通解 aₙ = (C₁ + C₂n)2ⁿ。设 a₀ = 1,a₁ = 3,代入 n = 0:C₁ = 1;n = 1:(C₁ + C₂)·2 = 3,得 C₂ = 0.5。于是 aₙ = (1 + 0.5n)2ⁿ。验算 n = 2:a₂ = (1 + 1)·4 = 8,而原式 a₂ = 4a₁ − 4a₀ = 12 − 4 = 8,吻合。
重根还有一个隐蔽的坑:如果方程是三阶或更高阶,重根的重数决定了要乘多少个 n 的幂。比如三阶特征方程有根 λ 重三次,对应的齐次基解是 λⁿ、nλⁿ、n²λⁿ。这条规则是通解求法里最容易记错的,我的记忆窍门是:重数减一就是 n 的最高次数。三重根最高次是 n²,二重根最高次是 n¹,单根就是 n⁰ = 1。
3.3 非齐次二阶:待定系数法的完整套路
非齐次方程 aₙ₊₂ + p aₙ₊₁ + q aₙ = f(n),通解 = 齐次通解 + 一个特解。特解怎么找,取决于 f(n) 的形式。工程和考试里最常出现的 f(n) 有三类:多项式、指数、三角。这三类都可以用待定系数法处理,核心思路是"猜出解的形式,带回方程定系数"。
| 非齐次项 f(n) | 试解形式 | 修正规则 |
|---|---|---|
| m 次多项式 | m 次多项式 | 0 是特征根时乘 n^s,s 为 0 作为特征根的重数 |
| c·λⁿ | A·λⁿ | λ 是特征根时乘 n^s,s 为重数 |
| 多项式 × λⁿ | 同次多项式 × λⁿ | 同上 |
| A cos(ωn) + B sin(ωn) | C cos(ωn) + D sin(ωn) | e^{±iω} 是特征根时乘 n |
修正规则是这张表的灵魂。为什么撞车要乘 n?因为如果试解形式和齐次解重复,代入后会被齐次方程部分吃掉,导致系数无解,只能靠乘 n 把它"顶出"齐次空间。这个规则和二阶微分方程的处理完全平行,唯一的区别是离散情形里"撞车"判据变成了"λ 是不是特征根"。
举个混合型的例子:aₙ₊₂ − 3aₙ₊₁ + 2aₙ = 4n。齐次特征方程 λ² − 3λ + 2 = 0,根 λ₁ = 1, λ₂ = 2,齐次通解 aₙ^h = C₁ + C₂·2ⁿ。非齐次项是 1 次多项式,而且 λ = 1 恰好是特征根(重数 1),所以试解要乘 n:设 aₙ* = n(An + B) = An² + Bn。代入原方程算一算,得到 A = 2, B = ...(具体算:设 aₙ* = An² + Bn,则 aₙ₊₂* = A(n+2)² + B(n+2),aₙ₊₁* = A(n+1)² + B(n+1),代进去化简可得 A = 2, B = 6)。于是 aₙ* = 2n² + 6n,通解 aₙ = C₁ + C₂·2ⁿ + 2n² + 6n。
注意:待定系数法在 f(n) 是"多项式乘指数"时,指数部分和多项式部分要一起处理,不能拆开分别试。比如 f(n) = (n+1)3ⁿ,试解是 (An + B)3ⁿ,如果 λ = 3 是特征根,就变成 n(An + B)3ⁿ。拆开处理会漏掉指数和多项式的耦合项,结果必然错。
4. 高阶与一般理论:把方法推广到任意阶
4.1 解空间的维数决定了通解里有多少个自由常数
k 阶线性差分方程的通解有 k 个独立常数,这不是凑数,而是线性代数里"k 维解空间"的直接体现。把数列的前 k 项看作初始向量,方程给出了从初始向量到后续项的线性映射,解空间自然就是 k 维的。这个结论有个很实用的推论:给定 k 个初始条件,解唯一确定。也就是说,如果你手上有 a₀, a₁, …, aₖ₋₁ 这 k 个数,那么整个数列就被完全锁定,通解里的 k 个常数也恰好被这 k 个条件定死。
验证 k 个解是否线性无关,要用Casorati 行列式(离散版的朗斯基行列式)。对二阶情形,W(n) = y₁(n) y₂(n+1) − y₁(n+1) y₂(n)。如果对某个 n 有 W(n) ≠ 0,则两个解线性无关。这个判据在常数变易法求特解时是必需品,因为它出现在分母上。关于 Casorati 行列式有一个漂亮的性质:它本身满足一个一阶差分方程 W(n+1) = (−1)^k a₀ W(n)(a₀ 是最高阶项系数),所以如果 W 在某点非零,它就恒非零,这保证了解的线性无关性不会中途"退化"。
实操心得:判断线性相关时,不要只看两个解是否"看起来不同"。λ₁ⁿ 和 λ₂ⁿ 在 λ₁ = λ₂ 时是同一个解,但 λ₁ = −λ₂ 时它们完全不同。真正要算 Casorati 行列式。我在做递推解的验证时,习惯先算 W(0),非零就放心往下走,零就说明选的基解有问题,得换。
4.2 常数变易法的一般形式:非齐次特解的万能公式
当 f(n) 是任意数列(不是多项式、指数、三角这些好函数)时,待定系数法就不管用了,必须用常数变易法。以二阶为例,设齐次方程的两个线性无关解为 y₁(n), y₂(n),则非齐次方程的一个特解可以写成:
y*(n) = −y₁(n) · Σ [ y₂(k) f(k) / W(k) ] + y₂(n) · Σ [ y₁(k) f(k) / W(k) ]
其中求和从某个起点到 n−1,W(k) 是 Casorati 行列式。这个公式形式上跟微分方程的常数变易公式一模一样,只是积分变成了求和。推导思路也一样:把齐次通解里的常数 C₁, C₂ 换成数列 C₁(n), C₂(n),并要求"额外项不引入新的差分阶",从而得到关于 C₁(n), C₂(n) 差分的方程组,解出来再累加即可。
这个公式看着吓人,但实际用起来是有套路的。我一般先把 W(k) 算出来看它是不是常数(对很多常见方程它确实是常数或简单几何数列),如果是,求和就退化成简单的数列求和,公式立刻变得好算。如果 W(k) 是复杂的 n 的表达式,那说明方程本身可能有更特殊的结构,这时候我会检查是不是可以用换元法把方程简化,而不是硬套公式。
4.3 复根与三角形式:把振荡说清楚
复根情形在应用里出现得比想象中频繁。任何带"来回摆动"特征的离散系统,特征方程大概率有复根。比如 aₙ₊₂ + aₙ = 0,特征方程 λ² + 1 = 0,根 λ = ±i,模 ρ = 1,辐角 θ = π/2。通解是 aₙ = C₁ cos(nπ/2) + C₂ sin(nπ/2),展开看就是 0, 1, 0, −1, 0, 1, … 这样的周期数列。振幅不衰减,说明系统是临界稳定的。
把复根情形写成极坐标形式 ρⁿ(C₁ cos nθ + C₂ sin nθ) 之后,稳定性的判据就非常直观了:ρ 就是每步振幅的缩放因子。ρ = 1.05 意味着每步振幅放大 5%,跑上一百步就是原来的 1.05¹⁰⁰ ≈ 131 倍,发散得很厉害;ρ = 0.95 则一百步后衰减到约 0.6%。这个 ρ 在工程里叫谱半径,是判断迭代算法收敛速度的核心指标。更细一点,θ 决定了振荡的"频率":θ 越大,每步转过的角度越多,振荡越快。如果 θ = π,就是纯粹的符号翻转振荡;如果 θ 很小,那就是缓慢的"过冲—回调"过程。
注意:用 ρ 判断稳定性时,前提是系统已经写成标准的齐次形式,所有项都移到等号左边。很多应用题里非齐次项 f(n) 本身也带指数增长,这时候系统的整体行为由"齐次部分最大模根"和"f(n) 的增长因子"共同决定,单纯看 ρ 会误判。判断长期趋势时,要看两者谁涨得快。
5. 常见问题与排查技巧实录
5.1 问题一:算出来的通解代回去不成立
这是最高频的问题,九成以上出在三个地方。第一,特征根算错,尤其是一元二次方程的符号,p、q 是"移位形式"里的系数,特征方程是 λ² + pλ + q = 0,不是 λ² − pλ + q。这个符号规则来自"约掉 λⁿ 后把最高阶项系数归一"。第二,重根情形下第二个基解忘了乘 n,导致两个基解线性相关,常数只有一个是自由的。第三,复根情形下忘了把虚数幂转成三角函数,直接写了 C₁(i)ⁿ + C₂(−i)ⁿ,这在实数问题里虽然数学上没错,但通常不是想要的实数列形式。
排查方法很简单:代入验证。把你求出的通解代回原方程,取 n = 0, 1, 2 三组值分别算左边和右边,只要有一组对不上,就说明形式错了。这个方法笨但绝对有效,我做了这么多年,每次推导完都习惯验算三组,从没让它坑过我。
5.2 问题二:特解试解形式和齐次解撞车导致无解
当你发现代入试解后,方程两边系数对不上、无解,那基本可以断定试解和齐次解撞车了。典型场景:非齐次项是常数,而 λ = 1 是特征根。这时候把试解乘以 n 再重来一遍即可。如果乘 n 之后还撞(说明重根重数至少是 2),就再乘一个 n。这个"逐次乘 n"的规则可以机械化执行:先判断 λ 作为特征根的重数 s,试解直接乘 n^s,一步到位,不要试一次乘一次。
5.3 问题三:初始条件代入后常数求出多个矛盾值
出现这种情况,通常是初始条件的个数和通解的阶数对不上。k 阶方程需要 k 个初始条件,少给了会导致常数无法完全确定,多给了则会出现矛盾。在应用题里,这意味着你对问题的建模可能漏了边界条件或重复使用了某个条件。我的排查顺序是:先确认方程阶数 = 初始条件个数,再确认每个条件是否独立(比如 a₀ = 1 和 2a₀ = 2 就是同一个条件,不算两个)。
5.4 常见问题速查表
| 现象 | 可能原因 | 处理方式 |
|---|---|---|
| 通解代回不成立 | 特征方程符号错 / 漏乘 n / 复根未转换 | 按 λ² + pλ + q = 0 重算,检查重根,复根转三角 |
| 特解无解 | 试解与齐次解撞车 | 试解乘 n^s,s 为撞车重数 |
| 常数矛盾 | 初始条件数与阶数不符 | 补足或去重初始条件 |
| 长期趋势判断错 | 忽略非齐次项的增长 | 比较齐次最大模根与非齐次增长因子 |
| 振荡不衰减但预期衰减 | ρ 计算错 | 用 ρ = √q(复根时)重新算 |
| 数值算出来和解析差一点 | 浮点精度或 λⁿ 溢出 | 用对数域计算,或改用同阶递推验证 |
实操心得:我在做长序列数值验证时,遇到 λ 绝对值大于 1 的情况,λⁿ 很快就会溢出浮点数范围。这时候不要硬算,改成先算对数再取指数,或者直接用递推关系小步验证前 20 项。前 20 项如果对得上,形式基本就没错。
6. 用代码把推导验证一遍
6.1 数值验证的最小脚本
推导完之后,我强烈建议写几行代码验算。下面这段 Python 用解析解和递推解对比前 15 项,两列一旦完全一致,通解就是对的。这个习惯能帮你省下大量检查时间。
import numpy as np # 例子:a_{n+2} - 3a_{n+1} + 2a_n = 4n, a0=1, a1=2 # 齐次特征根 1, 2;特解 2n^2 + 6n def analytic(n): # 通解 a_n = C1 + C2*2^n + 2n^2 + 6n # 由 a0=1, a1=2 定 C1, C2 # n=0: C1 + C2 = 1 # n=1: C1 + 2C2 + 8 = 2 -> C1 + 2C2 = -6 # 解得 C2 = -7, C1 = 8 return 8 - 7 * (2 ** n) + 2 * n**2 + 6 * n def numeric(terms=15): a = [1, 2] for n in range(terms - 2): # a_{n+2} = 3a_{n+1} - 2a_n + 4n a.append(3 * a[n+1] - 2 * a[n] + 4 * n) return a an = [analytic(n) for n in range(15)] num = numeric(15) for i, (x, y) in enumerate(zip(an, num)): print(i, x, y, "OK" if abs(x - y) < 1e-9 else "MISMATCH")跑一遍你会发现两列完全一致,这比手工验算三组值更彻底。我通常在每次推完一个新方程后都跑一遍,成本几秒钟,收益是避免把错误结论带到后续分析里。
6.2 稳定性扫描:一眼看出 ρ 的影响
对复根情形,我习惯写一个扫描脚本,把 ρ 从 0.9 到 1.1 扫一遍,画出前 30 项的包络,直观感受衰减和发散的速度差。虽然这篇不讲画图,但你可以用打印振幅的方式看:每一步振幅乘 ρ,三十步后 0.9³⁰ ≈ 0.04,1.1³⁰ ≈ 17.4,差距是四百多倍。这个数量级上的差别,就是为什么工程里那么在意谱半径比 1 大还是小——差一点点,长期行为天差地别。
提示:做数值验证时要注意,解析解和递推解都可能因为浮点误差在小数点后很多位出现分歧。判断标准不要设成"完全相等",而是设一个相对误差阈值,比如 1e-9。对大规模序列,阈值可以放宽到 1e-6。
7. 我从这套方法里提炼的几条经验
第一,永远先贴标签再动手。阶数、线性、齐次这三个标签花不了你十秒钟,但能决定你走哪条路。跳过这一步直接算,十有八九会在中途发现方法不对,回来重来。
第二,特征方程是核心中的核心。齐次解的稳定性、振荡性、重根现象,全都藏在特征根里。我见过很多人把特征方程当"中间步骤"草草算过,结果后面全乱。我的建议是,特征根算出来之后,先花一分钟分析它的模和辐角,把系统的长期行为预判出来,再继续往下求未知常数。这样即使后面常数算错了,你也能靠量级判断发现异常。
第三,特解形式的选择要有意识,不能靠试。待定系数法的表格要背,撞车乘 n 的规则要背,这两条记住了,非齐次问题就没有难的。很多"卡壳"其实是不知道试解该设成什么形式,而不是运算难。
第四,验证是必需品不是可选项。解析解 + 递推解双路对照,成本极低,收益极高。我做了这么多年,凡是跳过验证的推导,最后都出过问题;凡是老老实实验证的,基本一次就过。
第五,别把离散和连续割裂开想。差分方程和微分方程在结构上是一套东西,特征方程、通解结构、特解方法、稳定性判据全部平行对应。你把微分方程那套学扎实了,反过来看差分方程会无比熟悉;你用差分方程练熟了,再回头看微分方程的重根、复根,也会觉得理所当然。这两个理论互相印证,学一个是学,学两个还是学一个。
最后分享一个小技巧:遇到阶数大于 3 的方程,不用硬算特征方程的高次根。先用试根法找有理根(常数项因式除以最高次项因式),找到一个根就做多项式除法降阶,剩下的低次方程再用求根公式或判别式处理。这个思路和求解高次代数方程完全一样,把问题一步步降到能处理的规模,比正面硬刚高效得多。降阶之后再逐层套用前面的通解框架,任何阶数的线性差分方程都能拆到"一阶 + 二阶"的基本单元,剩下的就是耐心和仔细了。