擴(kuò)展歐幾里得算法

資料

  • 歐幾里得算法
  • 擴(kuò)展歐幾里得算法
  • 擴(kuò)展歐幾里得算法應(yīng)用

歐幾里得算法

歐幾里得算法用于求兩個數(shù)的最大公約數(shù)

證明
設(shè) a > b, a = kb + r;
只需證明gcd( a, b ) = gcd( b, r );
設(shè) gcd( a, b ) = c;
a = m * c, b = n * c;
r = a - kb
  = ( m - nk ) * c;
要證gcd( b, r ) = c;只需證明 ( m - nk ) 與 n 互素,即gcd( m - nk, n ) = 1;
假設(shè)gcd( m - nk , n ) = d ( d > 1 );
那么 ( m - n k ) = xd, n = yd;
a = m * c
  = ( xd + nk )c 
  = ( x + ny )cd 
b = ycd;
如果d > 1 那么 gcd( a, b ) >= cd > c; 矛盾
所以 d = 1;
gcd( b, r ) = gcd( a, b );即證
算法
遞歸版:
int gcd(int a, int b)
{
 return (b == 0 ? a : gcd(b, a % b));
}

非遞歸版
int gcd( int a, int b )
{
    int t;
    while( b != 0 )
    {
        t = a % b;
        a = b;
        b = t;
    }
    return a;
}

擴(kuò)展歐幾里得算法

在求得a,b 的最大公約數(shù)的同時,還能求出一組解x,y,使其滿足貝祖等式
ax + by = gcd( a, b )

證明
設(shè) a > b, a = kb + r;
1. b = 0 時,
    gcd( a, b ) = a,x = 1,y = 0;
2. b != 0 時,
   設(shè) ax1 + by1 = gcd( a, b );
       bx2  + ( a % b )y2 = gcd( b, a % b );
   由歐幾里得算法得
   ax1 + by1 = bx2 + ( a % b )y2;
   化簡得
   x1 = y2;
   y1 = x2 -( a / b )y2;
   上述表明x1, y1 可由 x2, y2表示,以此遞歸下去,直到b = 0;可知必有解,
   即證.
算法
遞歸版
int exgcd(int a,int b,int & x,int & y){
    if(b == 0){
        //根據(jù)上面的推理1,基本情況
        x = 1;
        y = 0;
        return a;
    }
    //根據(jù)推理2
    int r = exgcd(b, a%b, x, y);
    int t = y;
    y = x - (a/b)*y;
    x = t;
    return r;
}

非遞歸版
int exgcd(int a,int b,int &x,int &y)
{
    int r = a % b;
    int x0, y0, x1, y1;
    x0 = 1; y0 = 0;
    x1 = 0; y1 = 1;
    x  = x1; y  = y1;
    while( r )
    {
        x = x0 -  a/b * x1;
        y = y0 -  a/b * y1;
        x0 = x1;
        y0 = y1;
        x1 = x;
        y1 = y;
        a = b;
        b = r;
        r = a % b;
    }
    return b;
}
非遞歸算法證明
根據(jù)歐幾里得算法
a = bq1 + r1; (1)
b = r1q2 + r2;(2)
r1 = r2q3 + r3;
....
ri-2 = ri-1*qi + r i;
....
rn-2 = rn-1*qn + rn; 
rn-1 = rn*qn+1 + 0;
因為對于ri>0,ri均是gcd(a, b)的倍數(shù)
所以每一步均存在 xi, yi, 使得 a xi + b yi = ri成立
ri = ri-2 - ri-1*qi
   = ( a*xi-2 + b*yi-2 ) - ( a*xi-1 + b*yi-1 )*qi
   = a*( xi-2 - qi*xi-1 ) + b( yi-2 - qi*yi-1 )
因為 ri = a xi + b yi;
xi = xi-2 - qi*xi-1;
yi = yi-2 - qi*yi-1;
直到求xn, yn;
因為 (1)和(2)式,
初始化 x0 = 1,y0 =0,x1=0,y1=1;

擴(kuò)展歐幾里得算法應(yīng)用

  • 求解不定方程
  • 求解模線性方程
  • 求解模的逆元
求解不定方程

不定方程指ax + by = c,
a,b,c是整數(shù),證明ax+by=c在整數(shù)范圍內(nèi)有解的充要條件是 gcd( a, b )整除c.

證明:
設(shè)gcd( a,b )= d,則 d|c ,c = kd;
充分性:
ax0 + by0 = d,左右乘k,即可證明
必要性:
ax0 + by0 = c; d|a, b|a,那么 d|ax0 + by0,則 d|c即證  
算法
bool linear_equation(int a,int b,int c,int &x,int &y)
{
    int d=exgcd(a,b,x,y);
    if(c%d)
        return false;
    int k=c/d;
    x*=k; y*=k;    //求得的只是其中一組解
    return true;
}
求解模線性方程

模線性方程是指 ax≡b (mod n)

求解:
ax≡b(mod n)  等價于 ax = b + nk;
等價于 ax + ny = b;
當(dāng)b|gcd( a, n )時,有解
設(shè) gcd( a,n ) = d, ax0 + ny0 = d,
那么存在解 x = x0 * ( b/d ); 對模n有特解 x = x0*(b/d)( mod n );
易知,x, y有多解  
由x = ( b/a ) + ( n / a ) * y知,x的相鄰解的間隔時相同的
設(shè)間隔為dx
ax≡b(mod n) 
a(x+ dx) ≡b(mod n) 
相減  adx ≡ 0 ( mod n )  即 n | adx,且 a | adx.
那么最小的dx滿足 
adx = lcm( a, n )
       = a n / gcd( a, n )  
 dx = n / d;
可知,該方程對模n恰有d個不同的解(這個很顯然,但不會理論證明)
算法
bool modular_linear_equation(int a,int b,int n)
{
    int x,y,x0,i;
    int d=exgcd(a,n,x,y);
    if(b%d)
        return false;
    x0=x*(b/d)%n;   //特解
    for(i=1;i<d;i++)
        printf("%d\n",(x0+i*(n/d))%n);
    return true;
}
求解模的逆元

ax≡ 1 (mod n), gcd( a, n ) = 1, 只有唯一解,該解稱為 x 為 a 的對模 n 乘法的逆元。

byene.jpg
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容