【问题标题】:Modular inverse calculation stuck模块化逆计算卡住了
【发布时间】:2014-01-17 08:10:25
【问题描述】:

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

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,而不是 for i in n。 这对我没有帮助,也没有给出正确的答案。

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

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

【问题讨论】:

    标签: python algorithm python-3.x theory


    【解决方案1】:

    你说得对,扩展欧几里得算法解决了这个任务。但是,您不需要调用它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
    

    【讨论】:

    • 谢谢。但是,对于我的测试用例,a,b,c = 14,67,88 应该输出 58,但是在这种情况下,当我将 a 和 m 放入 modinv 函数时,它返回 None 而不是 58。我很难时间理解为什么。另外,我注意到您在我使用 b 的 modinv 的答案中使用了 a。我不明白为什么。
    • a 的逆元素 b 是 a * inv = 1 mod m 所以你只需要两个参数。我猜您正在寻找a * inv = b,但将结果乘以b 并取mod m 就足够了。
    • 附言。感谢您接受答案。但是要知道,如果您在事情变得清楚时接受,那就没有错;)
    • 感谢您的澄清。我接受了您的回答,因为该算法有意义,只是必须缺少某些东西。我仍然无法让 a,b,c = 14,67,88 输出 58。您介意解释一下这部分吗?
    • 我在上一条评论中混淆了符号,抱歉。所以你有a=14,b=67,n=88。您首先需要将b 取模n 取反。原来modinv(67,88) = 67。现在你只需将a 乘以倒数的b 就可以得到14*67 mod 88 = 58。我将在答案中添加mod_div 函数。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多