美文网首页
扩展欧几里得算法

扩展欧几里得算法

作者: ticks | 来源:发表于2018-11-02 17:14 被阅读0次

    欧几里得算法

    文中用 \% 表示求模运算, /表示整除, 比如 215\%15=5, 215/15=14
    欧几里德算法(称辗转相除法),用于计算两个整数a, b的最大公约数gcd(a, b).
    基本原理

    1. gcd(a, b) = gcd(a, b-a) 与第3条结合, 可以写更相减损术
    2. gcd(a,b) = gcd(b,a\%b) 与第3条结合, 欧几里得算法(辗转相除法)
    3. gcd(a, 0) = a
    4. gcd(a, b) 是点集 \{ax+by| x,y \in Z\} 中最小的正整数.
      c/c++ 实现的欧几里得算法
    int gcd(a, b)
    {
        int temp;
        while(b)
        {
              temp = b;
              b = a % b;
              a = temp;
        }
      return a;
    }
    

    扩展欧几里得算法

    ax+by=gcd(a,b)的整数解
    因为我不是学数学的, 严谨的证明就不写了. 只写一点简单的推导

    递推公式


    ax_1+by_1=gcd(a,b)
    bx_2+(a\%b)y_2=gcd(b,a\%b)=gcd(a,b)
    \therefore ax_1+by_1=bx_2+(a\%b)y_2=bx_2+(a-a/b*b)y_2
    \therefore ax_1+by_1=ay_2+b(x_2-a/by_2)
    \begin{cases} x_1=y_2\\ y_1=x_2-(a/b)y_2 \end{cases}
    根据上式的 c++ 实现

    void exgcd(int a, int b, int& g, int& x, int& y)
    {  // 纯c好像不支持引用, 可以用指针代替.
        if(!b)
        {
            g = a;
            x = 1;
            y = 0;
        }
        else exgcd(b, a % b, g, x, y);
        int t;
        t = x;
        x = y;
        y = t -(a / b) * y;
    }
    

    非递归算法

    这个稍有些难, 仍然是a,b,g,x,y
    step1 . x'=y=1, x=y'=0, c=a, d=b
    step2. r=c\%d, q=c/d
    step3. if(r==0) 结束, else继续
    step4. c=d, d=r,\begin{cases}t=x'\\x'=x\\x=t-qx\end{cases},\begin{cases}t=y'\\y'=y\\y=t-qy\end{cases} 去step2

    初始时由上step1的定义有 \begin{cases}ax+by=d &(1)\\ax'+by'=c&(2)\end{cases}\Rightarrow a(x'-qx)+b(y'-qy)=r\quad (3)
    第一次到step3, 如果r=0,x,y就是ax+by=gcd(a,b)的解
    step4
    (1)式变为 ax'+by'=c, (3)式变为ax+by=d

    void exgcd(int a, int b, int& g, int& x, int& y)
    { // 可以用来求逆元
        if(!b)
        {
            x = 0;
            y = 1;
            g = a;
        }
        else
        {
              int x1, y1, q, r, t;
              x1 = y = 1; y1 = x = 0; 
              r = a % b; q = a / b;
              while(r) 
              {
                  a = b;
                  b = r;
                  t = x1;
                  x1 = x;
                  x = t - q * x;
                  t = y1;
                  y1 = y;
                  y = t - q * y;
                  r = a % b;
                  q = a / b;
              } 
              g = b;
        }
    }
    

    相关文章

      网友评论

          本文标题:扩展欧几里得算法

          本文链接:https://www.haomeiwen.com/subject/icgxxqtx.html