歐幾里德算法(最大公約數算法)


歐幾里德算法

  歐幾里德算法又稱為輾轉相除法,用於計算兩個非負整數的最大公因數。其偽代碼如下: 

gcd(a, b) //要求a>=b
    if(b == 0)
        return a
    return gcd(b, a % b)

  結果的正確性源於a與b的最大公約數c也是a%b的公共約數。原因很簡單,a%b=a-kb=ic-kjc=(i-kj)c,故a%b能整除c。設p為b和a%b的最大公約數,由於a=kb+a%b=xkp+yp=(xk+y)p,因此p能被a整除,因此p也是a與b的最大公約數,因此可以保證c>=p>=c,故p=c。

  再不考慮遞歸的情況下,gcd的時間復雜度為O(1),而每次遞歸調用都會使得兩個傳入參數a與b中較大者減少一半以上(a%b<=min{a-b,b}),因此遞歸最多發生O(log2(a)+log2(b))=O(log2(ab))次,總的時間復雜度為O(log2(ab)),空間復雜度主要集中在遞歸,同樣也是O(log2(ab))。

應用

場景1

  對於自然數a與b,有時候我們需要求解能使得x*(a/b)為整數的最小自然數x。我們可以將式子改寫為x*((a/c)/(b/c)),其中c是a與b的最大公約數,由於a/c與b/c沒有公約數,即二者互質,因此由算術基本定理知x能整除b/c,即x可以取值b/c,2b/c,...。當我們選取b/c作為x值時,式子的值為x*(a/b)=a/c,為整數,因此b/c即為我們要求的值。  

 

場景2  

  設z是x與y的最大公約數,要求讓ax+by=z成立的某組可能的a與b的取值,也可以通過歐幾里德算法實現。

  若x與y中有至少一者為0時,我們只需要取非0元素的系數為1,就可以得到一組解。而當x=y時只需要令a,b中任意一個為1另外一個為0即可得到所求值。之后均認為x>y>0。若我們已知ny+m(x%c)=c成立,則進行如下推導:$$ ny+m\left(x\%y\right)=z $$ $$ \Rightarrow ny+m\left(x-y\cdot\lfloor\frac{x}{y}\rfloor\right)=z $$ $$ \Rightarrow m\cdot x+\left(n-m\cdot\lfloor\frac{x}{y}\rfloor\right)\cdot y=z $$因此我們就得到了一組可行的a與b的值。

  到此我們可以使用遞歸的思路求解a與b:

coe(x, y) //認為x>y
    if(y == 0)
        return (1, 0)
    n, m = coe(y, x % y)
    return (m, n - m * floor(x / y))

  對於已知的一組式子ax+by=z,其中a,x,b,y,z均已知且z是x與y的公約數,希望找到另外一對n,m使得nx+my=c成立且n是所有符合值中最小自然數,即我們希望銳化a的取值。首先我們分別令等式左右兩邊除以z,此時式子形如np+mq=1,其中p與q互質。而我們的目標是通過修改n和m的值使得等式成立且n為最小自然數,因此我們將n與m的變更值記作u與v(這里認為n尚未達到目標結果,即u與v均非0),則可得up+vq=0。由於p與q互質,因此u能整除q且v能整除p,u的值最小允許取-q和q,表示對n最小幅度的波動。我們可以按照n現有符號對n不斷加上q或-q,直到n成為最小的可行自然數。這里可以直接寫作n%q。因此我們知道了n%(y/z)是使得式子ax+by=z滿足的最小自然數。

  要求ax+by=cz滿足的一組a與b的取值,且c是給定整數,可以先使用上面的方法取一對可行解n,m使得nx+my=z成立,之后兩端均乘上c得到cnx+cmy=cz,就得到一組可行系數。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM