中国剩余定理中间涉及一个重要观念:互质

首先来看《孙子算经》卷下第二十六问:今有物,不知其数。三、三数之,剩二;五、五数之,剩三;七、七数之,剩二。问物几何?

转换为数学语言即是(理解其中的文言,三、三数之,不表示 /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