模块化逆的算法

时间:2011-09-30 16:45:44

标签: c++ algorithm numbers

我已经阅读了关于扩展欧几里德算法的部分&模块化反转,表明它不仅计算GCD(n,m)而且还计算a和b,a*n+b*b=1; 通过这种方式描述算法:

  
      
  1. 记下n,m和两个向量(1,0)和(0,1)
  2.   
  3. 将两个数字中较大的一个除以较小的数字 - 调用此方法   商q
  4.   
  5. 从较大的减去q倍(即减小较大的值)   模数较小的)
  6.   

(我有问题,如果我们用qn / m表示,那么n-q*m is不等于0?因为q = n / m;(假设n> m),那么为什么有必要这样的操作? 然后4步

  

4.从对应于较小的向量中减去q倍   矢量对应的较大   5.重复步骤2到4,直到结果为零   6.将前面的结果发布为gcd(n,m)

所以我对这个问题的问题也是我如何在代码中实现这个步骤?请帮助我,我不知道如何开始,从哪个点开始我可以解决这个问题,为了澄清结果,它应该看起来像这样 该算法的一个示例是以下计算30 ^( - 1)(mod 53);

53           30           (1,0)                        (0,1)
53-1*30=23   30           (1,0)-1*(0,1)=(1,-1)         (0,1)
23           30-1*23=7    (1,-1)                       (0,1)-1*(1,-1)=(-1,2)
23-3*7=2      7           (1,-1)-3*(-1,2)=(4,-7)       (-1,2)
2             7-3*2=1     (4,-7)                      (-1,2)-3*(4,7)=(-13,23)
2-2*1=0       1           (4,-7)-2*(-13,23)=(30,-53)   (-13,23)

由此我们看到gcd(30,53)= 1,重新排列术语,我们看到1 = -13 * 53 + 23 * 30, 所以我们得出结论,30 ^( - 1)= 23(mod 53)。

1 个答案:

答案 0 :(得分:3)

除法应该是截断的整数除法。 gcd(a, b)a <= b的标准EA如下所示:

 b =  a * q0 + r0
 a = r0 * q1 + r1
r0 = r1 * q2 + r2
  ...
r[N+1] = 0

现在rN是所需的GCD。然后你回来替代:

r[N-1] = r[N] * q[N+1]

r[N-2] = r[N-1] * q[N] + r[N]
       = (r[N] * q[N+1]) * q[N] + r[N]
       = r[N] * (q[N+1] * q[N] + 1)

r[N-3] = r[N-2] * q[N-1] + r[N-1]
       = ... <substitute> ...

直到你最终到达rN = m * a + n * b。您描述的算法会立即跟踪回溯数据,因此效率会更高。

如果rN == gcd(a, b) == 1,那么您确实找到ab的乘法逆,即m(a * m) % b == 1