同余方程组


先把结论说在前面:

“同余方程组”就是:在模 (m_1,m_2,\dots) 下,一个未知数 (x) 同时满足好几个“余数条件”的方程组。 秦九韶在《数书九章》里提出的“大衍求一术”,就是一套系统求解这类方程组的算法,本质上就是中国版的“中国剩余定理 + 线性同余迭代算法”。

下面我分几层给你讲清楚:

  1. 什么是同余、同余方程、同余方程组
  2. 同余方程组什么时候有唯一解
  3. 秦九韶“大衍求一术”究竟在干嘛(从例子到一般原理)
  4. 和现代数论里的“中国剩余定理”是怎样一一对应的

一、从零讲:什么是“同余方程组”?

1.1 同余是啥?

在整数世界里,我们说:

[ a \equiv b \pmod m ]

读作“(a) 与 (b) 在模 (m) 意义下同余”,意思就是:

(a) 和 (b) 除以 (m) 的余数相同

或者更公式一点: [ m \mid (a-b) ]

例如:

  • (17 \equiv 2 \pmod 5)(因为 (17-2=15) 能被 5 整除)
  • (-3 \equiv 7 \pmod{10})(因为 (-3-7=-10) 能被 10 整除)

把“未知数”放进去,就得到同余方程,例如:

[ x \equiv 2 \pmod 5 ]

这就是:求所有整数 (x),使它除以 5 余 2, 解就是:(x=2+5k)。


1.2 同余方程是什么?

就是同时满足好几个模条件:

[ \begin{cases} x \equiv a_1 \pmod{m_1}
x \equiv a_2 \pmod{m_2}
\quad\vdots
x \equiv a_k \pmod{m_k} \end{cases} ]

举个直白的例子:

找一个数 (x) ,满足:

  • 除以 3 余 2
  • 除以 5 余 3
  • 除以 7 余 2

写成同余方程组就是:

[ \begin{cases} x \equiv 2 \pmod 3[2pt] x \equiv 3 \pmod 5[2pt] x \equiv 2 \pmod 7 \end{cases} ]

你可以理解成: 同一个整数,在不同“刻度尺”(模数)下的“刻度位置(余数)”都被规定好了,问这个整数是多少。


二、什么时候它有唯一解?(模乘积意义下)

结论(就是后来叫“中国剩余定理”的东西):

若各模数 (m_1,\dots,m_k) 两两互质(任何两 个的 gcd = 1),则:

  • 这样的同余方程组一定有解;
  • 并且在模 (M = m_1 m_2\cdots m_k) 意义下,解是唯一的。

也就是说,所有解都是:

[ x \equiv x_0 \pmod M ]

用白话说:

存在且仅存在一个 (0 \le x_0 < M) 满足这整套余数条件。

秦九韶的大衍求一术,就是在模 (M) 的范围内,把这个唯一解算出来的系统算法。


三、秦九韶的大衍求一术:直观版

《数书九章·大衍类》里,秦九韶提出“大衍求一术”,典型题型就是:

有物不知其数。 三三数之,余二; 五五数之,余三; 七七数之,余二。 问物若干?

这就是我们前面的系统:

[ \begin{cases} x \equiv 2 \pmod 3
x \equiv 3 \pmod 5
x \equiv 2 \pmod 7 \end{cases} ]

我们先用**慢一点的“理解版”**走一遍,然后再讲秦九韶的“公式化版”。


3.1 先用“叠加法”感受一下

从第一个方程:

[ x \equiv 2 \pmod 3 \Rightarrow x = 2 + 3k ]

把它代入第二个方程:

[ 2 + 3k \equiv 3 \pmod 5
\Rightarrow 3k \equiv 1 \pmod 5 ]

在模 5 下: 3 的逆元是 2(因为 (3\times 2 = 6 \equiv 1 \pmod 5))

所以:

[ k \equiv 2 \cdot 1 \equiv 2 \pmod 5 \Rightarrow k = 2 + 5t ]

于是:

[ x = 2 + 3(2+5t) = 8 + 15t ]

这时,我们已经合并成:

[ x \equiv 8 \pmod{15} ]

再把这个带入第三个条件:

[ 8 + 15t \equiv 2 \pmod 7
15t \equiv -6 \equiv 1 \pmod 7 ]

注意:15 ≡ 1 (mod 7),所以方程变成:

[ t \equiv 1 \pmod 7 \Rightarrow t = 1 + 7s ]

于是:

[ x = 8 + 15(1+7s) = 23 + 105s ]

在 (0 \le x < 105) 范围内的解就是:

[ x = 23 ]

这就是整组方程在模 (105 = 3 \cdot 5 \cdot 7) 意义下的唯一解。


3.2 秦九韶怎么做?——“大衍求一术”的结构

他当然不会写成现代“解一次同余方程”这种形式,而是用一整套口诀 + 表格算法。

核心思想其实就是:

  1. 把所有模数乘起来得到 (M);
  2. 对每个模数 (m_i),算出一个“局部权重” (M_i = M / m_i);
  3. 找到一个数 (e_i),使得 (M_i e_i \equiv 1 \pmod{m_i})(也就是 (M_i) 在模 (m_i) 下的逆元);
  4. 把各个“余数 × 局部权重 × 逆元”加起来,再对 (M) 取模,得到最终解。

这就是现代 CRT 的标准构造法,而秦九韶用“大衍求一术”把它“程式化”。


四、用“大衍求一术”的“模板”重算这个例子

我们再用刚才那组方程,按“秦九韶思路模板”来算一遍:

[ \begin{cases} x \equiv 2 \pmod 3
x \equiv 3 \pmod 5
x \equiv 2 \pmod 7 \end{cases} ]

4.1 第一步:求总模 (M)

[ M = 3 \cdot 5 \cdot 7 = 105 ]

4.2 第二步:求每一项的“局部模” (M_i)

  • 对模 3:(M_1 = 105 / 3 = 35)
  • 对模 5:(M_2 = 105 / 5 = 21)
  • 对模 7:(M_3 = 105 / 7 = 15)

4.3 第三步:求每个 (M_i) 在各自模下的逆元 (e_i)

  1. 在模 3 下: 求 (35 e_1 \equiv 1 \pmod 3) 由于 35 ≡ 2 (mod 3),所以: (2 e_1 ≡ 1 (mod 3)),逆元为 2(2×2=4≡1), → (e_1 = 2)。

  2. 在模 5 下: (21 e_2 ≡ 1 \pmod 5) 21 ≡ 1 (mod 5),所以 (e_2=1)。

  3. 在模 7 下: (15 e_3 ≡ 1 \pmod 7) 15 ≡ 1 (mod 7),所以 (e_3=1)。

4.4 第四步:线性组合求 (x)

公式型写法:

[ x \equiv a_1 M_1 e_1 + a_2 M_2 e_2 + a_3 M_3 e_3 \pmod M ]

代入数据:

[ x \equiv 2 \cdot 35 \cdot 2 + 3 \cdot 21 \cdot 1 + 2 \cdot 15 \cdot 1 ]

计算一下:

  • (2 \cdot 35 \cdot 2 = 140)
  • (3 \cdot 21 = 63)
  • (2 \cdot 15 = 30)

总和:

[ x \equiv 140 + 63 + 30 = 233 \pmod{105} ]

对 105 取模:

[ 233 - 2 \cdot 105 = 233 - 210 = 23 ]

所以:

[ x \equiv 23 \pmod{105} ]

这就是与刚才迭代法同样的结果。

这就是“大衍求一术”的数学内核。

古文中虽然用的是“乘除”、“倍数”、“等分”等词,但算法逻辑就是这样:

给每个同余条件一个“加权份额”,把它们合并成一个统一的解。


五、把秦九韶的思想翻译成现代“原理”表述

我们可以把大衍求一术的原理归纳成几个句子:

  1. 同余方程组的解可以写成一个线性组合:

[ x = \sum_{i=1}^{k} a_i M_i e_i ] 在模 (M) 意义下成立。

  1. 每个 (M_i) 在模 (m_i) 下是可逆的, 所以可以选择 (e_i) 使得 (M_i e_i \equiv 1 \pmod{m_i})。

这样:

  • 对第 (i) 个模数 (m_i) 来说: [ x \equiv a_i \pmod{m_i} ] 而对其他模数 (m_j) 来说,由于 (M_i) 被 (m_j) 整除,对它们的余数贡献为 0。
  1. 总模 (M = \prod m_i) 的唯一性: 因为模数两两互质,任何两个不同的组合会在模 (M) 下给出不同余数,因此解在模 (M) 下唯一。

你可以把它看成:

把每个“余数条件”看作一个投票,每个投票权重是“其他模数的乘积 × 逆元”,然后把所有票加权求和,再在大模 (M) 下归一,得到最终答案。


六、秦九韶的贡献到底在哪里?

  1. 系统化: 在他之前,中国已经有“剩余问题”的萌芽(如《孙子算经》的“物不知数,三三数之…”),但只是零散技巧。 秦九韶把它抽象成一道标准算法,可以对任意多模数、任意余数组合使用。

  2. 程式化 + 可操作性: 他为“大衍求一术”配套了详细的步骤、口诀、算例,普通工匠、官吏按表操作即可,数学思想从“高玄理论”变成“实际计算工具”。

  3. 与“大衍”宇宙观结合: 秦九韶把算法命名为“大衍求一”,说明他有很强的象数意识:

    • 多模、多余数 = 众多分殊
    • 合并后唯一解 = 万殊归一,符合“大衍之数五十”这种“由多归一”的哲学结构
  4. 在世界数学史上的位置: 西方形式化的“中国剩余定理”要晚到 19 世纪才被完全抽象出来,而秦九韶在 13 世纪就已经有完整的构造算法,属于极早的构造性数论思想


七、如果你想继续深入,可以怎么学?

我可以帮你往下做几件事:

  1. 用 Python 或纸算,带你亲手跑几组“大衍求一术”

    • 从两模、三模到很多模
    • 感受计算量和模式
  2. 把“大衍求一术”转成现代伪代码 / 程序

    • 让你看到它和现代 CRT 算法的 1:1 对应关系
  3. 从“大衍求一术”过渡到更大的数论世界

    • 模逆元、扩展欧几里得算法
    • 同余线性方程组的一般解
    • 中国剩余定理在密码学、区块链中的应用(RSA、模幂运算加速)

如果你愿意,下一步我可以专门帮你写一份“从大衍求一术到现代中国剩余定理”的学习笔记,把“古文算法 ⇄ 现代数学”完全对照起来。