📜  用中国余数定理组合模方程

📅  最后修改于: 2021-05-04 12:27:34             🧑  作者: Mango

给定N个模块化方程式:
A≅x 1 mod(m 1 )


A≅x n mod(m n )
在方程A≅xmod(m 1 * m 2 * m 3 .. * m n )中找到x
其中m i是素数或素数的幂,并且i取从1到n的值。

输入被提供为两个数组,第一个是包含每个x i值的数组,第二个数组包含每个素数的值集。
输出最终方程式中x的整数。
例子 :

Consider the two equations
A ≅ 2mod(3)
A ≅ 3mod(5)
Input : 
2 3
3 5
Output : 
8

Consider the four equations,
A ≅ 3mod(4)
A ≅ 4mod(7)
A ≅ 1mod(9) (32)
A ≅ 0mod(11)
Input :
3 4 1 0
4 7 9 11
Output :
1243

解释 :

我们旨在一次求解两个方程。我们采用前两个方程式,将其组合起来,然后使用该结果与第三个方程式组合,依此类推。下面以示例2为参考,说明结合两个方程的过程:

  1. A we 3mod(4)和A≅4mod(7)是我们首先提供的两个方程。让所得到的方程是一些A 0≅X 0 MOD(M 1 * M 2)。
    • A 0由m 1 ‘* m 1 * x 0 + m 0 ‘* m 0 * x 1给出
      其中,m 1 ‘= M 1模m 0和m 0的逆模块化’=模块化逆米0模m 1
    • 我们可以使用扩展的欧几里得算法来计算模逆。
    • 我们发现x 0为A 0 mod(m 1 * m 2 )
    • 我们得到的新方程为A≅11mod(28),其中A为95
  2. 现在,我们尝试将其与方程式3组合,并通过类似的方法,得出A≅235mod(252),其中A = 2503
  3. 最后,将其与方程式4结合在一起,我们得到A≅1243mod(2772)其中A = 59455和x = 1243

我们观察到2772正好等于4 * 7 * 9 * 11。
因此,我们找到了最终方程的x值。

您可以参考扩展欧几里得算法和模乘逆,以获取有关这些主题的更多信息。

# Python 2.x program to combine modular equations
# using Chinese Remainder Theorem
  
# function that implements Extended euclidean
# algorithm
def extended_euclidean(a, b):
    if a == 0:
        return (b, 0, 1)
    else:
        g, y, x = extended_euclidean(b % a, a)
        return (g, x - (b // a) * y, y)
  
# modular inverse driver function
def modinv(a, m):
    g, x, y = extended_euclidean(a, m)
    return x % m
  
# function implementing Chinese remainder theorem
# list m contains all the modulii
# list x contains the remainders of the equations
def crt(m, x):
  
    # We run this loop while the list of
    # remainders has length greater than 1
    while True:
          
        # temp1 will contain the new value 
        # of A. which is calculated according 
        # to the equation m1' * m1 * x0 + m0'
        # * m0 * x1
        temp1 = modinv(m[1],m[0]) * x[0] * m[1] + \
                modinv(m[0],m[1]) * x[1] * m[0]
  
        # temp2 contains the value of the modulus
        # in the new equation, which will be the 
        # product of the modulii of the two
        # equations that we are combining
        temp2 = m[0] * m[1]
  
        # we then remove the first two elements
        # from the list of remainders, and replace
        # it with the remainder value, which will
        # be temp1 % temp2
        x.remove(x[0])
        x.remove(x[0])
        x = [temp1 % temp2] + x 
  
        # we then remove the first two values from
        # the list of modulii as we no longer require
        # them and simply replace them with the new 
        # modulii that  we calculated
        m.remove(m[0])
        m.remove(m[0])
        m = [temp2] + m
  
        # once the list has only one element left,
        # we can break as it will only  contain 
        # the value of our final remainder
        if len(x) == 1:
            break
  
    # returns the remainder of the final equation
    return x[0]
  
# driver segment
m = [4, 7, 9, 11]
x = [3, 4, 1, 0]
print crt(m, x)
Output
1243

该定理和算法具有很好的应用价值。一个非常有用的应用是计算n C r %m,其中m不是素数,而卢卡斯定理不能直接应用。在这种情况下,我们可以计算出m的素因数,然后将我们的n C r %m方程中的素因数一一用作模数(可以使用卢卡斯定理进行计算),然后使用上面显示了中国剩余定理。