中国剩余定理中间涉及一个重要观念:互质;
首先来看《孙子算经》卷下第二十六问:今有物,不知其数。三、三数之,剩二;五、五数之,剩三;七、七数之,剩二。问物几何?
转换为数学语言即是(理解其中的文言,三、三数之,不表示 /32,而是三个三个地,应当是 /3):
x≡2(mod3)x≡3(mod5)x≡2(mod7)⇓x?
《孙子算经》给出的答案是23。当然这个问题还有其他解,由于
105=3×5×7,所以
23+105n 也能满足要求。除此之外,还有别的解吗?没有了。
事实上(中国剩余定理的内容),不管物体总数除以3的余数,除以5的余数以及除以7(3、5、7互质)的余数分别为多少?在0到104(3×5×7−1)当中总存在唯一解,在此解(特解)的基础上再加上105的整数倍之后,可以得到其他所有的正整数解。这正是中国剩余定理:给出 m 个两两互质(3,5,7,m=3)的整数,它们的乘积为 P(P=3×5×7=105),假设有一个未知数 M(M=23),如果我们已知 M分别除以这 M个数所得的余数,那么在0到 P−1 的范围内,我们可以唯一地确定这个M。这可以看做是 M的一个特解,其他所有满足要求的 M,则正好是那些除以 P 之后余数等于这个特解的数(x≡M(modP)⇒x=nP+M)
我们回到《孙子算经》,来求解“今有物,不知其数”。根据中国剩余定理,由于除数3,5,7两两互质,因而解在0-104之间,且解唯一。我们求解的基本思路就是,依次找出满足每个条件,但是又不会破坏掉其他条件的数。
- 我们首先要寻找一个数,它既是5的倍数又是7的倍数,但同时除以3正好余2,也即 35⋅xmod3=2,根据 扩展欧几里得算法及其应用 一文的算法,我们可轻易对之求解,解得 x=1,也即该数为 35⋅x=35,
- 再来看第二个条件,寻找这么一个数,它既是3的倍数,又是7的倍数,同时除以5余3,也即 21⋅xmod5=3,此时解得,x=3,也即 21⋅x=63
- 同理对于第三个条件,15⋅xmod7=2,解得 x=2,15⋅x=30
现在如果我们把 35,63,30 这三个数加在一起(得128)会怎样?它将同时满足题目中的三个条件。为了得一个0-104之间的解,我们在128的基础上减去 3×5×7=105,正好得到《孙子算经》当中的答案,23.
这是我们给出求解的 python 代码(因为涉及 a⋅xmodn=b
from operator import mul
from functools import reduce
def ext_euclid(a, b):
# ax + by = gcd(a, b)
if b == 0:
return (a, 1, 0)
d, x, y = ext_euclid(b, a%b)
return (d, y, x-a//b*y)
def mod_linear_equation(a, b, c):
d, x, y = ext_euclid(a, b)
if c%d:
raise 'no solution'
return x*(c//d)%b
def chinese_remainer(l1, l2):
# l1, l2 均为数组
# 分别表示除数,和余数
s = 0
P = reduce(mul, l1)
for i in range(len(l1)):
t = P//l1[i]
s += mod_linear_equation(t, l1[i], l2[i])*t
return s%P
if __name__ == '__main__':
print(chinese_remainer([3, 5, 7], [2, 3, 3]))
# 23