模块化逆计算卡住了

时间:2014-01-17 08:10:25

标签: python algorithm python-3.x theory

到目前为止,这是我的代码:

def mod_div(a, b, n): 

if gcd(b,n) != 1:
    return 'Undefined'    

for x in range(1, n):
        if b*x%n == a%n:      
            return x   

这段代码接受我制作的函数gcd()并返回gcd,然后我用它来计算逆。我搜索了这些问题,但似乎没有人给我正确答案。

我的问题是:当我执行div_mod(3,2,7)时,代码返回5,应该如此。但是,当我为大数字时,例如n> 10000,计算解决方案需要很长时间,因为通过n的迭代来找到正确的数字。

我试着查看其他问题,并且在他们的答案中,他们都有类似的事情,但是如果gcd!= 1,他们都会返回x%n而不是i中的i。 这对我没有帮助,也没有给出正确答案。

例如。如果我使用a = 12,b = 3和n = 11它应该返回4,但除了我的所有函数都返回1。

我想知道是否有更有效的方法来使用eulids扩展定理,而不是测试每个n,并希望有效。

1 个答案:

答案 0 :(得分:5)

扩展欧几里德算法解决了这个问题,你说得对。但是,您无需将其称为n次 - 您只需要一次。查看http://en.wikipedia.org/wiki/Extended_Euclidean_algorithm

这是来自http://en.wikibooks.org/wiki/Algorithm_Implementation/Mathematics/Extended_Euclidean_algorithm

的命令式python算法
def egcd(a, b):
    x,y, u,v = 0,1, 1,0
    while a != 0:
        q, r = b//a, b%a
        m, n = x-u*q, y-v*q
        b,a, x,y, u,v = a,r, u,v, m,n
    return b, x, y

def modinv(a, m):
    g, x, y = egcd(a, m)
    if g != 1:
        return None  # modular inverse does not exist
    else:
        return x % m

O(1)空间和最坏情况下的O(log n)时间。

现在,除了模n之外,我们按照定义

def moddiv(a, b, n):
    binv = modinv(b, n)
    if not binv:
        return None
    return a * binv % n