如何解决python中的同余系统?

时间:2018-01-14 17:27:44

标签: python algorithm math discrete-mathematics

问题Ax≡B(MOD C)我这样做了,没关系:

{{1}}

现在我必须解决一个方程组,其中A =(5x + 7y)和A =(6x + 2y), B = 4且B = 12,C为26。

换句话说:   (5x + 7y)≡4(mod 26)   (6x + 2y)≡12(mod 26)

我该怎么做?

感谢。

4 个答案:

答案 0 :(得分:0)

解决了,这是代码:

    def congru(a0,a1,a2,b0,b1,b2,c):
        for i in range(0,c):  
            for j in range(0,c): 
                if ((a0*i + a1*j) - a2)%c ==0 and ((b0*i +b1*j)-b2)%c==0:
                    print('x: %d  y: %d' %( i, j))

答案 1 :(得分:0)

对于aX ≡ b (mod m)线性同余,这是一个基于欧拉定理的功能更强大的Python解决方案,即使对于非常大的数,它也能很好地发挥作用:

def linear_congruence(a, b, m):
    if b == 0:
        return 0

    if a < 0:
        a = -a
        b = -b

    b %= m
    while a > m:
        a -= m

    return (m * linear_congruence(m, -b, a) + b) // a

>>> linear_congruence(80484954784936, 69992716484293, 119315717514047)
>>> 45347150615590

对于X, Y系统:将第一个方程乘以2,将第二个方程乘以-7,将它们相加并求解X。然后替换X并求解Y

答案 2 :(得分:0)

要解决线性同余系统,应使用中文提醒定理。 我使用python和AppJar(AppJar用于grafics)编写了完整的代码。 而且您可以从我的github个人资料中下载它:github profile, full code there

在那里您可以找到我使用的所有功能。 这很简单,我相信您会理解该代码,尽管它是用塞尔维亚语编写的。

答案 3 :(得分:0)

这是一个非常快速的线性同余求解器,可以在一秒钟内解决4096个字节数。递归版本在此长度上达到其最大深度:

#included if you use withstats=True, not needed otherwise
def ltrailing(N):
    return len(str(bin(N))) - len(str(bin(N)).rstrip('0'))

#included if you use withstats=True, not needed otherwise
def _testx(n, b, withstats=False):
    s = ltrailing(n - 1)
    t = n >> s
    if b == 1 or b == n - 1:
        return True
    else:
        for j in range(0, s):
            b = pow_mod(b, 2, n, withstats)
            if b == n - 1:
                return True
            if b == 1:
                return False
            if withstats == True:
               print(f"{n}, {b}, {s}, {t}, {j}")
    if withstats == True:
        print(f"{n}, {b}, {s}, {t}")
    return False

def fastlinearcongruence(powx, divmodx, N, withstats=False):  
 x, y, z = egcditer(powx, N, withstats)  
 answer = (y*divmodx)%N  
 if withstats == True:  
    print(f"answer = {answer}, mrbt = {a}, mrst = {b},  mranswer = {_testx(N, answer)}")  
 if x > 1:  
    powx//=x  
    divmodx//=x  
    N//=x  
    if withstats == True:  
      print(f"powx = {powx}, divmodx = {divmodx}, N = {N}")  
    x, y, z = egcditer(powx, N, withstats)  
    if withstats == True:  
      print(f"x = {x}, y = {y}, z = {z}")  
    answer = (y*divmodx)%N  
    if withstats == True:  
       print(f"answer = {answer}, mrbt = {a}, mrst = {b},  mranswer = {_testx(N, answer)}")  
 answer = (y*divmodx)%N  
 if withstats == True:  
    print(f"answer = {answer}, mrbt = {a}, mrst = {b},  mranswer = {_testx(N, answer)}")  
 return answer 
 
def egcditer(a, b, withstats=False):  
  s = 0  
  r = b  
  old_s = 1  
  old_r = a  
  quotient = 0 
  if withstats == True:  
      print(f"quotient = {quotient}, old_r = {old_r}, r = {r}, old_s = {old_s}, s = {s}")  
  while r!= 0:  
    quotient = old_r // r  
    old_r, r = r, old_r - quotient * r  
    old_s, s = s, old_s - quotient * s  
    if withstats == True:  
      print(f"quotient = {quotient}, old_r = {old_r}, r = {r}, old_s = {old_s}, s = {s}")  
  if b != 0:  
    bezout_t = quotient = (old_r - old_s * a) // b  
    if withstats == True:  
      print(f"bezout_t = {bezout_t}")  
  else:  
    bezout_t = 0  
  if withstats == True:  
    print("Bézout coefficients:", (old_s, bezout_t))  
    print("greatest common divisor:", old_r)  
  return old_r, old_s, bezout_t

要使用:


In [2703]: fastlinearcongruence(63,1,1009)                                                                                                                                                   
Out[2703]: 993


In [2705]: fastlinearcongruence(993,1,1009)                                                                                                                                                  
Out[2705]: 63


Also this is 100x faster than pow when performing this pow: 

pow(1009, 2**bit_length()-1, 2**bit_length())

where the answer is 273.

This is equivalent to the much faster:


In [2713]: fastlinearcongruence(1009,1,1024)                                                                                                                                              
Out[2713]: 273