扩展欧几里得算法

扩展欧几里得算法


扩展欧几里得算法
(英语:Extended Euclidean algorithm)是欧几里得算法(又叫辗转相除法)的扩展。已知整数a、b,扩展欧几里得算法可以在求得a、b的最大公约数的同时,能找到整数x、y(其中一个很可能是负数),使它们满足贝祖等式
{\displaystyle ax+by=\gcd(a,b).}ax + by = \gcd(a, b).

如果a是负数,可以把问题转化成

{\displaystyle \left|a\right|(-x)+by=\gcd(|a|,b)}\left|a\right|(-x)+by=\gcd(|a|,b){\displaystyle \left|a\right|}\left|a\right|为a的绝对值),然后令{\displaystyle x'=(-x)}x'=(-x)

通常谈到最大公约数时,我们都会提到一个非常基本的事实(由裴蜀定理给出):给定二个整数a、b,必存在整数x、y使得ax + by = gcd(a,b)[1]

众所周知,已知两个数{\displaystyle a}a{\displaystyle b}b,对它们进行辗转相除(欧几里得算法),可得它们的最大公约数。不过,在欧几里得算法中,我们仅仅利用了每步带余除法所得的余数。扩展欧几里得算法还利用了带余除法所得的商,在辗转相除的同时也能得到裴蜀等式[2]裴蜀定理中描述的等式,裴蜀定理也翻译成贝祖定理)中的x、y两个系数。以扩展欧几里得算法求得的系数是满足裴蜀等式的最简系数。

另外,扩展欧几里得算法是一种自验证算法,最后一步得到的{\displaystyle s_{i+1}}{\displaystyle s_{i+1}}{\displaystyle t_{i+1}}{\displaystyle t_{i+1}}{\displaystyle s_{i+1}}{\displaystyle s_{i+1}}{\displaystyle t_{i+1}}{\displaystyle t_{i+1}}的含义见下文)乘以{\displaystyle \gcd(a,b)}{\displaystyle \gcd(a,b)}后恰为{\displaystyle a}a{\displaystyle b}b,可以用来验证计算结果是否正确。

扩展欧几里得算法可以用来计算模反元素(也叫模逆元),求出模反元素是RSA加密算法中获得所需公钥、私钥的必要步骤。

算法和举例

在标准的欧几里得算法中,我们记欲求最大公约数的两个数为{\displaystyle a,b}a,b,第{\displaystyle i}i步带余除法得到的商为{\displaystyle q_{i}}q_i,余数为{\displaystyle r_{i+1}}{\displaystyle r_{i+1}},则欧几里得算法可以写成如下形式:

{\displaystyle {\begin{aligned}r_{0}&=a\\r_{1}&=b\\&\,\,\,\vdots \\r_{i+1}&=r_{i-1}-q_{i}r_{i}\quad {\text{and}}\quad 0\leq r_{i+1}<|r_{i}|\\&\,\,\,\vdots \end{aligned}}}{\displaystyle {\begin{aligned}r_{0}&=a\\r_{1}&=b\\&\,\,\,\vdots \\r_{i+1}&=r_{i-1}-q_{i}r_{i}\quad {\text{and}}\quad 0\leq r_{i+1}<|r_{i}|\\&\,\,\,\vdots \end{aligned}}}

当某步得到的{\displaystyle r_{i+1}=0}{\displaystyle r_{i+1}=0}时,计算结束。上一步得到的{\displaystyle r_{i}}r_{i}即为{\displaystyle a,b}a,b的最大公约数。

扩展欧几里得算法在{\displaystyle q_{i}}q_i{\displaystyle r_{i}}r_{i}的基础上增加了两组序列,记作{\displaystyle s_{i}}s_{i}{\displaystyle t_{i}}t_{i},并令{\displaystyle s_{0}=1}{\displaystyle s_{0}=1}{\displaystyle s_{1}=0}{\displaystyle s_{1}=0}{\displaystyle t_{0}=0}t_{0}=0{\displaystyle t_{1}=1}{\displaystyle t_{1}=1},在欧几里得算法每步计算{\displaystyle r_{i+1}=r_{i-1}-q_{i}r_{i}}{\displaystyle r_{i+1}=r_{i-1}-q_{i}r_{i}}之外额外计算{\displaystyle s_{i+1}=s_{i-1}-q_{i}s_{i}}{\displaystyle s_{i+1}=s_{i-1}-q_{i}s_{i}}{\displaystyle t_{i+1}=t_{i-1}-q_{i}t_{i}}{\displaystyle t_{i+1}=t_{i-1}-q_{i}t_{i}},亦即:

{\displaystyle {\begin{aligned}r_{0}&=a&r_{1}&=b\\s_{0}&=1&s_{1}&=0\\t_{0}&=0&t_{1}&=1\\&\,\,\,\vdots &&\,\,\,\vdots \\r_{i+1}&=r_{i-1}-q_{i}r_{i}&{\text{and }}0&\leq r_{i+1}<|r_{i}|\\s_{i+1}&=s_{i-1}-q_{i}s_{i}\\t_{i+1}&=t_{i-1}-q_{i}t_{i}\\&\,\,\,\vdots \end{aligned}}}

算法结束条件与欧几里得算法一致,也是{\displaystyle r_{i+1}=0}{\displaystyle r_{i+1}=0},此时所得的{\displaystyle s_{i}}s_{i}{\displaystyle t_{i}}t_{i}即满足等式{\displaystyle \gcd(a,b)=r_{i}=as_{i}+bt_{i}}{\displaystyle \gcd(a,b)=r_{i}=as_{i}+bt_{i}}

下表以{\displaystyle a=240}{\displaystyle a=240}{\displaystyle b=46}{\displaystyle b=46}为例演示了扩展欧几里得算法。所得的最大公因数是{\displaystyle 2}2,所得贝祖等式{\displaystyle \gcd(240,46)=2=-9*240+47*46}{\displaystyle \gcd(240,46)=2=-9*240+47*46}。同时还有自验证等式{\displaystyle |23|*2=46}{\displaystyle |23|*2=46}{\displaystyle |-120|*2=240}{\displaystyle |-120|*2=240}

序号 i商 qi−1余数 risiti
0   240 1 0
1   46 0 1
2 240 ÷ 46 = 5 240 − 5 × 46 = 10 1 − 5 × 0 = 1 0 − 5 × 1 = −5
3 46 ÷ 10 = 4 46 − 4 × 10 = 6 0 − 4 × 1 = −4 1 − 4 × −5 = 21
4 10 ÷ 6 = 1 10 − 1 × 6 = 4 1 − 1 × −4 = 5 −5 − 1 × 21 = −26
5 6 ÷ 4 = 1 6 − 1 × 4 = 2 −4 − 1 × 5 = −9 21 − 1 × −26 = 47
6 4 ÷ 2 = 2 4 − 2 × 2 = 0 5 − 2 × −9 = 23 −26 − 2 × 47 = −120

证明

由于{\displaystyle 0\leq r_{i+1}<|r_{i}|}{\displaystyle 0\leq r_{i+1}<|r_{i}|}{\displaystyle r_{i}}{\displaystyle r_{i}}序列是一个递减序列,所以本算法可以在有限步内终止。又因为{\displaystyle r_{i+1}=r_{i-1}-r_{i}q_{i}}{\displaystyle r_{i+1}=r_{i-1}-r_{i}q_{i}}, {\displaystyle (r_{i-1},r_{i})}{\displaystyle (r_{i-1},r_{i})}{\displaystyle (r_{i},r_{i+1})}{\displaystyle (r_{i},r_{i+1})}的最大公约数是一样的,所以最终得到的{\displaystyle r_{k}}{\displaystyle r_{k}}{\displaystyle a}a{\displaystyle b}b的最大公约数。

在欧几里得算法正确性的基础上,又对于{\displaystyle a=r_{0}}{\displaystyle a=r_{0}}{\displaystyle b=r_{1}}{\displaystyle b=r_{1}}有等式{\displaystyle as_{i}+bt_{i}=r_{i}}{\displaystyle as_{i}+bt_{i}=r_{i}}成立(i = 0 或 1)。这一关系由下列递推式对所有{\displaystyle i>1}i>1成立:

{\displaystyle r_{i+1}=r_{i-1}-r_{i}q_{i}=(as_{i-1}+bt_{i-1})-(as_{i}+bt_{i})q_{i}=(as_{i-1}-as_{i}q_{i})+(bt_{i-1}-bt_{i}q_{i})=as_{i+1}+bt_{i+1}}{\displaystyle r_{i+1}=r_{i-1}-r_{i}q_{i}=(as_{i-1}+bt_{i-1})-(as_{i}+bt_{i})q_{i}=(as_{i-1}-as_{i}q_{i})+(bt_{i-1}-bt_{i}q_{i})=as_{i+1}+bt_{i+1}}

因此{\displaystyle s_{i}}s_{i}{\displaystyle t_{i}}t_{i}满足裴蜀等式,这就证明了扩展欧几里得算法的正确性。

实现

以下是扩展欧几里德算法的Python实现:

def ext_euclid(a, b):
    old_s,s=1,0
    old_t,t=0,1
    old_r,r=a,b
    if b == 0:
        return 1, 0, a
    else:
        while(r!=0):
            q=old_r//r
            old_r,r=r,old_r-q*r
            old_s,s=s,old_s-q*s
            old_t,t=t,old_t-q*t
    return old_s, old_t, old_r

 

扩展欧几里得算法C语言实现:

#include <stdio.h>

//这里用了int类型,所支持的整数范围较小且本程序仅支持非负整数,可能缺乏实际用途,仅供演示。
struct EX_GCD { //s,t是裴蜀等式中的系数,gcd是a,b的最大公约数
    int s;
    int t;
    int gcd;
};

struct EX_GCD extended_euclidean(int a, int b) {
    struct EX_GCD ex_gcd;
    if (b == 0) { //b等于0时直接结束求解
        ex_gcd.s = 1;
        ex_gcd.t = 0;
        ex_gcd.gcd = 0;
        return ex_gcd;
    }
    int old_r = a, r = b;
    int old_s = 1, s = 0;
    int old_t = 0, t = 1;
    while (r != 0) { //按扩展欧几里得算法进行循环
        int q = old_r / r;
        int temp = old_r;
        old_r = r;
        r = temp - q * r;
        temp = old_s;
        old_s = s;
        s = temp - q * s;
        temp = old_t;
        old_t = t;
        t = temp - q * t;
    }
    ex_gcd.s = old_s;
    ex_gcd.t = old_t;
    ex_gcd.gcd = old_r;
    return ex_gcd;
    }

int main(void) {
    int a, b;
    printf("Please input two integers divided by a space.\n");
    scanf("%d%d", &a, &b);
    if (a < b) { //如果a小于b,则交换a和b以便后续求解
        int temp = a;
        a = b;
        b = temp;
    }
    struct EX_GCD solution = extended_euclidean(a, b);
    printf("%d*%d+%d*%d=%d\n", solution.s, a, solution.t, b, solution.gcd);
    printf("Press any key to exit.\n");
    getchar();
    getchar();
    return 0;
}

 



posted @ 2020-01-23 21:50  DirWangK  阅读(1135)  评论(0编辑  收藏  举报