孫子問題
最早,在《孫子算經》中有這樣一個問題:“今有物不知其數,三三數之剩二,五五數之剩三,七七數之剩二,問物幾何?用白話描述就是,現在有一個數不知道是多少,只知道這個數除以3餘2,除以5餘3,除以7餘2, 問這個數是多少?
上面的問題可以轉換爲以下這樣一個方程組:
⎩⎪⎨⎪⎧xmod3=2xmod5=3xmod7=2
其中這個x就是我們要求的數。而中國剩餘定理就是用來解決上述形式的方程組的x解的。
解答講解
在開始解答這個問題之前,我們先來了解一下幾個數論基本知識。
基本等式
(1)amodb=(a+k∗b)modb
(2)(a∗k)modb=k∗(amodb)
需要注意:a≡b(modc)的意思是amodc=bmodc
在瞭解兩個基本等式之後我們就可以對上述方程組做一些變換了:
⎩⎪⎨⎪⎧x=k1∗3+2x=k2∗5+3x=k3∗7+2
直接看上面的方程組,好像直接求解出k1、k2、k3不太現實,所以我們需要另尋出路。在這裏我們先假設三個數,分別是n1、n2、n3,滿足一下條件:
⎩⎪⎨⎪⎧n1mod3=2n2mod5=3n3mod7=2
假如n2、n3均能整除3的話,那麼按照等式(1)就有:
{n2=k2′∗3n3=k3′∗3
(n1+k2′∗3+k3′∗3)mod3=n1mod3=2(n1+n2+n3)mod3=2
那麼我們繼續假如n1、n3能被5整除,n1、n2能被7整除,那麼就有:
⎩⎪⎨⎪⎧(n1+n2+n3)mod3=2(n1+n2+n3)mod5=3(n1+n2+n3)mod7=2
對比題目中的方程組,可以看出只要滿足以下條件就能使我們需要求解的x=(n1+n2+n3):
- n1除以3餘2,且是5和7的公倍數。
- n2除以5餘3,且是3和7的公倍數。
- n3除以7餘2,且是3和5的公倍數。
我們只需要將n1、n2、n3求出來後相加即可得我們想求的x值。不過,這只是其中一個解,並不是最小解。要求最小解我們還需要除以n1、n2、n3的最大公約數。
這裏呢,我們以n1求解爲例,n2、n3求解過程類似。
求解n1過程
首先我們先羅列一下基本約束條件:
⎩⎪⎨⎪⎧n1mod3=2n1=5∗k2′n1=7∗k3′
根據等式(2),可以得到:
n1mod3=2∗(2n1mod3)=2
2n1mod3=1
如果2n1是5、7的整數倍,那麼n1自然也是5、7的整數倍。不過在這裏呢,我們並沒有從5和7的公倍數中直接找一個除以3餘2的數,而是先找一個除以3餘1的數,再乘以2。也就是先求出5和7的公倍數模3下的逆元,再用逆元去乘餘數。具體過程如下:參考來源
推算過程如下:
首先我們令K=2n1,
因爲Kmod3=1(K是5和7的整數倍),所以gcd(5∗7,3)=1,即35與3互質,由拓展歐幾裏得算有:K≡1(mod3)⇒K=a∗x=(5∗7)∗x≡1(mod3)35∗x+3∗y=1⇒整數解爲:{x=2,y=−23,可求得a的逆元x=2,則K=70⇒n1=2∗K=140
類似,可求出n2=63,n3=30⇒x=(n1+n2+n3)=233
不過此時並不是最小數,我們還需要將233÷(3、5、7)最大公約數105=23,這才是符合條件的最小數
最大公倍數=各個數的乘積÷最大公約數,最大公約數可使用輾轉相除法獲取(歐幾里得算法)
中國剩餘定理公式
設正整數m1,m2,...,mk,兩兩互素,則同餘方程組:
⎩⎪⎪⎪⎨⎪⎪⎪⎧x≡a1(modm1)x≡a2(modm2)......x≡ak(modmk)
有整數解。並且在模M=m1∗m2∗...∗mk下的解是唯一的,解爲
x≡(a1M1M1−1+a2M2M2−1+...+akMkMk−1)modM
其中Mi=miM,而Mi模mi的逆元。
關於擴展歐幾里得算法
參考文章:歐幾里德算法與擴展歐幾里德算法
用途
用來求解形如ax+by=c(a,b,c∈Z)的方程的一組整數解.。
使用條件
cmodgcd(a,b)=0,gcd(a,b)表示a/b的最大公約數
求解過程
求解方程:ax+by=gcd(a,b)
(1)當b=0時,原方程可化爲ax=gcd(a,0)⇒解得:{x=1y=0
(2)設a′=b,b′=amodb,有如下方程:
{a′x′+b′y′=gcd(a′,b′)=gcd(b,amodb)ax+by=gcd(a,b)
另有恆等式:gcd(a,b)=gcd(b,amodb),則:
ax+by=a′x′+b′y′=bx′+(amodb)y′=bx′+(a−⌊ba⌋b)y′
整理得:
ax+by==bx′+(a−⌊ba⌋b)y′⇓{x=y′y=x′−⌊ba⌋y′
通過上述這個解可知道,如果反覆迭代遞歸,最終一定會到達臨界條件b=0,即情況(1),從而計算出最終值。