同余方程组
先把结论说在前面:
“同余方程组”就是:在模 (m_1,m_2,\dots) 下,一个未知数 (x) 同时满足好几个“余数条件”的方程组。 秦九韶在《数书九章》里提出的“大衍求一术”,就是一套系统求解这类方程组的算法,本质上就是中国版的“中国剩余定理 + 线性同余迭代算法”。
下面我分几层给你讲清楚:
- 什么是同余、同余方程、同余方程组
- 同余方程组什么时候有唯一解
- 秦九韶“大衍求一术”究竟在干嘛(从例子到一般原理)
- 和现代数论里的“中国剩余定理”是怎样一一对应的
一、从零讲:什么是“同余方程组”?
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 秦九韶怎么做?——“大衍求一术”的结构
他当然不会写成现代“解一次同余方程”这种形式,而是用一整套口诀 + 表格算法。
核心思想其实就是:
- 把所有模数乘起来得到 (M);
- 对每个模数 (m_i),算出一个“局部权重” (M_i = M / m_i);
- 找到一个数 (e_i),使得 (M_i e_i \equiv 1 \pmod{m_i})(也就是 (M_i) 在模 (m_i) 下的逆元);
- 把各个“余数 × 局部权重 × 逆元”加起来,再对 (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)
-
在模 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)。
-
在模 5 下: (21 e_2 ≡ 1 \pmod 5) 21 ≡ 1 (mod 5),所以 (e_2=1)。
-
在模 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} ]
这就是与刚才迭代法同样的结果。
这就是“大衍求一术”的数学内核。
古文中虽然用的是“乘除”、“倍数”、“等分”等词,但算法逻辑就是这样:
给每个同余条件一个“加权份额”,把它们合并成一个统一的解。
五、把秦九韶的思想翻译成现代“原理”表述
我们可以把大衍求一术的原理归纳成几个句子:
- 同余方程组的解可以写成一个线性组合:
[ x = \sum_{i=1}^{k} a_i M_i e_i ] 在模 (M) 意义下成立。
- 每个 (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。
- 总模 (M = \prod m_i) 的唯一性: 因为模数两两互质,任何两个不同的组合会在模 (M) 下给出不同余数,因此解在模 (M) 下唯一。
你可以把它看成:
把每个“余数条件”看作一个投票,每个投票权重是“其他模数的乘积 × 逆元”,然后把所有票加权求和,再在大模 (M) 下归一,得到最终答案。
六、秦九韶的贡献到底在哪里?
-
系统化: 在他之前,中国已经有“剩余问题”的萌芽(如《孙子算经》的“物不知数,三三数之…”),但只是零散技巧。 秦九韶把它抽象成一道标准算法,可以对任意多模数、任意余数组合使用。
-
程式化 + 可操作性: 他为“大衍求一术”配套了详细的步骤、口诀、算例,普通工匠、官吏按表操作即可,数学思想从“高玄理论”变成“实际计算工具”。
-
与“大衍”宇宙观结合: 秦九韶把算法命名为“大衍求一”,说明他有很强的象数意识:
- 多模、多余数 = 众多分殊
- 合并后唯一解 = 万殊归一,符合“大衍之数五十”这种“由多归一”的哲学结构
-
在世界数学史上的位置: 西方形式化的“中国剩余定理”要晚到 19 世纪才被完全抽象出来,而秦九韶在 13 世纪就已经有完整的构造算法,属于极早的构造性数论思想。
七、如果你想继续深入,可以怎么学?
我可以帮你往下做几件事:
-
用 Python 或纸算,带你亲手跑几组“大衍求一术”:
- 从两模、三模到很多模
- 感受计算量和模式
-
把“大衍求一术”转成现代伪代码 / 程序:
- 让你看到它和现代 CRT 算法的 1:1 对应关系
-
从“大衍求一术”过渡到更大的数论世界:
- 模逆元、扩展欧几里得算法
- 同余线性方程组的一般解
- 中国剩余定理在密码学、区块链中的应用(RSA、模幂运算加速)
如果你愿意,下一步我可以专门帮你写一份“从大衍求一术到现代中国剩余定理”的学习笔记,把“古文算法 ⇄ 现代数学”完全对照起来。