中国剩余定理

中国剩余定理

一、实验目的

实验环境:python环境
实验目标:实现中国剩余定理,计算同余方程组的解

二、方案设计

(一)背景

中国剩余定理(即孙子定理)是中国古代求解一次同余式组的方法。是数论中一个重要定理。一元线性同余方程组问题最早可见于中国南北朝时期(公元5世纪)的数学著作《孙子算经》卷下第二十六题,叫做“物不知数”问题,原文如下:
有物不知其数,三三数之剩二,五五数之剩三,七七数之剩二。问物几何?即,一个整数除以三余二,除以五余三,除以七余二,求这个整数。
《孙子算经》中首次提到了同余方程组问题,以及以上具体问题的解法,因此在中文数学文献中也会将中国剩余定理称为孙子定理。

(二)实验原理

在这里插入图片描述

(三)算法步骤

在这里插入图片描述

三、方案实现

在这里插入图片描述

(二)算法主要代码

# 扩展欧几里得算法,返回值列表中,x是a的逆元(mod b),q是gcd(a,b),若x是0,则表示没有逆元
def Ex_Euclid(a, b):
    if 0 == b:
        x = 1;
        y = 0;
        q = a
        return x, y, q
    xyq = Ex_Euclid(b, a % b)
    x = xyq[0];
    y = xyq[1];
    q = xyq[2]
    temp = x;
    x = y;
    y = temp - a // b * y
    return x, y, q


# 获取a的逆元(mod b)的函数,目的是为了封装获取逆元的功能
def Get_Inverse(a, b):
    return Ex_Euclid(a, b)[0]


# 获取a和b的最大公约数函数
def gcd(a, b):
    return Ex_Euclid(a, b)[2]


# 判断所有的mi是否两两互质
def Is_Coprime(m_list):
    for i in range(len(m_list)):
        for j in range(i + 1, len(m_list)):
            if 1 != gcd(m_list[i], m_list[j]):
                return 0  # 返回0表示不是两两互质的
    return 1  # 返回1表示是两两互质的


# 获取所有的Mi
def Get_Mi(m_list, M):
    Mi_list = []
    for mi in m_list:
        Mi_list.append(M // mi)
    return Mi_list


# 获取所有的Mi的逆元
def Get_Mi_inverse(Mi_list, m_list):
    Mi_inverse = []
    for i in range(len(Mi_list)):
        Mi_inverse.append(Get_Inverse(Mi_list[i], m_list[i]))
    return Mi_inverse


# 中国剩余定理,返回值为最终的x
def C_R_T(path):
    # 两个空列表,分别用来保存mi和bi
    m = {}
    b = {}

    file_object = open(path, 'r')

    i = 1

    for i in [1, 2, 3]:
        b[i] = file_object.readline()

    for i in [1, 2, 3]:
        m[i] = file_object.readline()

    m_list = []
    b_list = []

    for i in [1, 2, 3]:
        temp = int(b[i])
        b_list.append(temp)

    for i in [1, 2, 3]:
        temp = int(m[i])
        m_list.append(temp)

    if  0 == Is_Coprime(m_list):
        print("错误!输入的mi并不是两两互素的,不能直接使用中国剩余定理\n")
        return 0

    M = 1  # M是所有mi的乘积
    for m in m_list:
        M *= m

    Mi_list = Get_Mi(m_list, M)

    Mi_inverse = Get_Mi_inverse(Mi_list, m_list)
    x = 0
    for i in range(len(b_list)):  # 开始计算x
        x += Mi_list[i] * Mi_inverse[i] * b_list[i]
        x %= M
    return x


if __name__ == '__main__':
    print('结果:  1.txt:')
    path1 = '1.txt'
    t = C_R_T(path1)
    if t != 0:
        print("同余式组的解为:x=", t)

    print('结果:  3.txt')
    path2 = '3.txt'
    t = C_R_T(path2)
    if t != 0:
        print("同余式组的解为:x=", t)

四、思考与总结

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值