From 5a56b26e3e78badfea35cfcc1769e66c8c25e127 Mon Sep 17 00:00:00 2001 From: tyxben <20570617+tyxben@users.noreply.github.com> Date: Tue, 30 Jul 2024 11:55:42 +0800 Subject: [PATCH 1/2] Update readme.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 优化中国剩余定理求解函数,确保模逆元非负 --- 08_Remainder/readme.md | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/08_Remainder/readme.md b/08_Remainder/readme.md index 113bd1b..d84e8d5 100644 --- a/08_Remainder/readme.md +++ b/08_Remainder/readme.md @@ -283,6 +283,12 @@ $a_3 = 2, b_3 = 15, b_3' \equiv 15^{-1} = 1\pmod{7}$ ```python def extended_gcd(a, b): + """ + 扩展欧几里得算法,用于求解 ax + by = gcd(a, b) 的整数解 + :param a: 整数 + :param b: 整数 + :return: (gcd(a, b), x, y) + """ if b == 0: return a, 1, 0 else: @@ -292,7 +298,6 @@ def extended_gcd(a, b): def chinese_remainder_theorem(congruences): """ 中国剩余定理求解函数 - :param congruences: 模线性同余方程组,格式为 [(a1, m1), (a2, m2), ..., (an, mn)],表示方程组为 x ≡ ai (mod mi) :return: 方程组的解 x """ @@ -303,18 +308,22 @@ def chinese_remainder_theorem(congruences): # 计算 Mi 和 Mi 的模逆元素 M_values = [M // mi for _, mi in congruences] - Mi_values = [extended_gcd(Mi, mi)[1] for Mi, (_, mi) in zip(M_values, congruences)] + inverse_values = [extended_gcd(Mi, mi)[1] % mi for Mi, (_, mi) in zip(M_values, congruences)] # 计算解 x - x = sum(ai * Mi * mi for (ai, _), Mi, mi in zip(congruences, Mi_values, M_values)) % M + x = sum(ai * Mi * inverse for (ai, mi), Mi, inverse in zip(congruences, M_values, inverse_values)) % M return x # 示例:解 x ≡ 2 (mod 3), x ≡ 3 (mod 5), x ≡ 2 (mod 7) congruences = [(2, 3), (3, 5), (2, 7)] solution = chinese_remainder_theorem(congruences) -print(f"同余方程组的解为 x ≡ {solution} (mod {congruences[0][1] * congruences[1][1] * congruences[2][1]})") -# 同余方程组的解为 x ≡ 23 (mod 105) +M_product = 1 +for _, mi in congruences: + M_product *= mi + +print(f"同余方程组的解为 x ≡ {solution} (mod {M_product})") +# 输出: 同余方程组的解为 x ≡ 23 (mod 105) ``` ### 4.5 逆向使用 @@ -337,4 +346,4 @@ $$ ## 5. 总结 -这一讲,我们学习了剩余类,同余方程组,和中国剩余定理。其中中国剩余定理不仅可以解同余方程组,还可以逆向使用,将大问题分解为小问题,在零知识证明中非常重要。 \ No newline at end of file +这一讲,我们学习了剩余类,同余方程组,和中国剩余定理。其中中国剩余定理不仅可以解同余方程组,还可以逆向使用,将大问题分解为小问题,在零知识证明中非常重要。 From 05135b0444a3bd0271a2dc2a389cc5fda1e62bd6 Mon Sep 17 00:00:00 2001 From: weitianyuan <15245012960@163.com> Date: Wed, 31 Jul 2024 11:50:19 +0800 Subject: [PATCH 2/2] update jupyter code --- 08_Remainder/Remainder.ipynb | 46 +++++++++++++++++++++++------------- 1 file changed, 30 insertions(+), 16 deletions(-) diff --git a/08_Remainder/Remainder.ipynb b/08_Remainder/Remainder.ipynb index 5dfa37d..e9dcbc0 100644 --- a/08_Remainder/Remainder.ipynb +++ b/08_Remainder/Remainder.ipynb @@ -2,20 +2,21 @@ "cells": [ { "cell_type": "code", - "execution_count": 2, "id": "40f73521", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "同余方程组的解为 x ≡ 23 (mod 105)\n" - ] + "metadata": { + "ExecuteTime": { + "end_time": "2024-07-31T03:46:04.473502Z", + "start_time": "2024-07-31T03:46:04.468611Z" } - ], + }, "source": [ "def extended_gcd(a, b):\n", + " \"\"\"\n", + " 扩展欧几里得算法,用于求解 ax + by = gcd(a, b) 的整数解\n", + " :param a: 整数\n", + " :param b: 整数\n", + " :return: (gcd(a, b), x, y)\n", + " \"\"\"\n", " if b == 0:\n", " return a, 1, 0\n", " else:\n", @@ -25,7 +26,6 @@ "def chinese_remainder_theorem(congruences):\n", " \"\"\"\n", " 中国剩余定理求解函数\n", - "\n", " :param congruences: 模线性同余方程组,格式为 [(a1, m1), (a2, m2), ..., (an, mn)],表示方程组为 x ≡ ai (mod mi)\n", " :return: 方程组的解 x\n", " \"\"\"\n", @@ -36,19 +36,33 @@ "\n", " # 计算 Mi 和 Mi 的模逆元素\n", " M_values = [M // mi for _, mi in congruences]\n", - " Mi_values = [extended_gcd(Mi, mi)[1] for Mi, (_, mi) in zip(M_values, congruences)]\n", + " inverse_values = [extended_gcd(Mi, mi)[1] % mi for Mi, (_, mi) in zip(M_values, congruences)]\n", "\n", " # 计算解 x\n", - " x = sum(ai * Mi * mi for (ai, _), Mi, mi in zip(congruences, Mi_values, M_values)) % M\n", + " x = sum(ai * Mi * inverse for (ai, mi), Mi, inverse in zip(congruences, M_values, inverse_values)) % M\n", "\n", " return x\n", "\n", "# 示例:解 x ≡ 2 (mod 3), x ≡ 3 (mod 5), x ≡ 2 (mod 7)\n", "congruences = [(2, 3), (3, 5), (2, 7)]\n", "solution = chinese_remainder_theorem(congruences)\n", - "print(f\"同余方程组的解为 x ≡ {solution} (mod {congruences[0][1] * congruences[1][1] * congruences[2][1]})\")\n", - "# 同余方程组的解为 x ≡ 23 (mod 105)" - ] + "M_product = 1\n", + "for _, mi in congruences:\n", + " M_product *= mi\n", + "\n", + "print(f\"同余方程组的解为 x ≡ {solution} (mod {M_product})\")\n", + "# 输出: 同余方程组的解为 x ≡ 23 (mod 105)" + ], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "同余方程组的解为 x ≡ 23 (mod 105)\n" + ] + } + ], + "execution_count": 1 }, { "cell_type": "code",