数论基础-最大公约数-(扩展)欧几里得算法-同余

2023-12-13 20:56:50

最大公约数

定义

最大公约数即为 Greatest Common Divisor,常缩写为 gcd。

一组整数的公约数,是指同时是这组数中每一个数的约数的数。+1和-1是任意一组整数的公约数。

一组整数的最大公约数,是指所有公约数里面最大的一个。

在python中,可以使用gmpy2库中的gcd函数计算最大公约数:

from gmpy2 import *
print(gcd(10,15))
# 5

欧几里得算法

辗转相除法是求两个自然数的最大公约数的一种方法,也叫欧几里得算法。

原理:两个整数的最大公约数等于其中较小的数和两数相除余数的最大公约数。

公式 gcd(a, b) = gcd(b, a % b)

证明过程:

假设 a = bk + c,就会有 c = a % b;设 d 是 可以被 a 和 b 整除的数(d是a和b的一个公约数),根据 c = a - bk

就会有 c/d = a/d - bk/d

根据式子的右边,可以知道 c 也是一个整数。到这里我们就证明了如果 d 是 a 和 b 的公约数,那么d也会是 b 和 a % b 的公约数。

同样的,从左边开始反证下,假设 d 是 b 和 a % b 的一个公约数,那么也有 c + bk = a,即 a % b + bk = a;

都除以d, (a % b)/d + bk/d = a/d

由右边可以知道 a 是一个整数,那么就可以证明,d 也是 a 的一个公约数。

所以式子俩边的公约数相同,最大公约数也相同。

因此 gcd(a, b) = gcd(b, a % b)

python代码实现:

def gcd(a, b):
    if b == 0:
        return a
    return gcd(b, a % b)

欧几里得算法的python实现是一种递归计算,一直计算到较小的数为 0 为止。

一个实例(源自https://zh.khanacademy.org/computing/computer-science/cryptography/modarithmetic/a/the-euclidean-algorithm):

计算 270 与 192 的最大公约数

  • A=270, B=192
  • A ≠0
  • B ≠0
  • 用长除法算出 270/192 = 1, 余数是 78。我们可以把这个写为: 270 = 192 * 1 +78
  • 计算 GCD(192,78), 因为 GCD(270,192)=GCD(192,78)

A=192, B=78

  • A ≠0
  • B ≠0
  • 用长除法算出 192/78 = 2,余数是 36。我们可以把这个写为:
  • 192 = 78 * 2 + 36
  • 计算 GCD(78,36),因为 GCD(192,78)=GCD(78,36)

A=78, B=36

  • A ≠0
  • B ≠0
  • 用长除法算出 78/36 = 2 ,余数是 6我们可以把这个写为:
  • 78 = 36 * 2 + 6
  • 计算 GCD(36,6),因为 GCD(78,36)=GCD(36,6)

A=36, B=6

  • A ≠0
  • B ≠0
  • 用长除法算出 36/6 = 6,余数是 0我们可以把这个写为:
  • 36 = 6 * 6 + 0
  • 计算 GCD(6,0),因为 GCD(36,6)=GCD(6,0)

A=6, B=0

  • A ≠0
  • B =0, GCD(6,0)=6

因此我们已经证明:

GCD(270,192) = GCD(192,78) = GCD(78,36) = GCD(36,6) = GCD(6,0) = 6

GCD(270,192) = 6

更相减损法

更相减损法最早起源于我国的《九章算术》,用于求两个数的最小公倍数。大意是给定两个数a,b,如果存在偶数,就将偶数以2;否则,就比较两数大小,用大数减小数,得到一个差;对差和剩下的那个小数重复该过程,直到两数相等,下一次相减结果为0,这时的数就是a和b的最大公约数。

例如:求119和85的最大公约数,17就是最大公约数

119-85=34 85-34=51 51-34=17 34-17=17

其实就是证明 gcd(a, b) = gcd(a - b, b)

证明过程:

设d为(p,q)的公约数,设p=ad, q=bd 其中a, b是正整数

于是p-q=(a-b)d,所以d也是p-q的约数,所以d是(p-q,q)的公约数

另一方面,设d为(p-q,q)的公约数,设p-q=ad, q=bd 其中a, b是正整数

于是p=(p-q)+q=(a+b)d,所以d也是p的约数,所以d是(p,q)的公约数

更相减损法和欧几里得算法的区别

  • 两者都是求最大公因数的方法,计算上辗转相除法以除法为主,更相减损术以减法为主,计算次数上辗转相除法计算次数相对较少,特别当两个数字大小区别较大时计算次数的区别较明显。
  • 从结果体现形式来看,辗转相除法体现结果是以相除余数为0则得到,而更相减损术则以减数与差相等而得到。

扩展欧几里得算法

扩展欧几里得算法(Extended Euclidean algorithm, EXGCD),常用于求 ax + by = gcd(a, b) 的一组可行解。

这里提一下贝祖等式。

贝祖等式

在数论中,裴蜀等式(英语:Bézout’s identity)或裴蜀定理(Bézout’s lemma)是一个关于最大公约数的定理。

贝祖等式 说明了任何整数a ,b和 m ,关于未知数 x 和 y 的 线性不定方程(未知数是整数的多项式)。

ax + by = m

有整数解时,当且仅当 m 是 a 及 b 的最大公约数 d 的倍数。贝祖等式有解时必然有无穷多个整数解,每组 x ,y都可以被称为贝祖系数,可以用扩展欧几里得算法求解。

特别来说,方程 ax + by = 1 有整数解当且仅当整数 a 和 b 互素。

好嘟,这样就又回来了,扩展欧几里得算法。

证明

假设 a = bx + c , a > b 则

ax1 + by1 = gcd(a, b)

bx2 + cy2 = gcd(b, c)

由欧几里得定理可知, gcd(a, b) = gcd(b, c)

所以ax1 + by1 = bx2 + cy2

可以得到 x1 = y2 ,y1 = x2 - ky2

这样就可以 将x1,y1用x2,y2表示下去,以此递归下去,知道 b = 0;

python实现代码

def Exgcd(a, b):
    if b == 0:
        return a, 1, 0
    d, x, y = Exgcd(b, a % b)
    return d, y, x - (a // b) * y

最小公倍数

定义

两个或多个整数公有的倍数叫做它们的公倍数,其中除0以外最小的一个公倍数就叫做这几个整数的最小公倍数(Least Common Multiple, LCM)。

最小公倍数和最大公约数的关系
image-20231213155848367

素数

定义

质数(Prime number),又称素数,指在大于 1 的自然数中,除了1和该数自身外,无法被其他自然数整数的数(也可定义为只有 1 与该数本身两个正因数的数)。大于 1 的自然数若不是素数,则称之为合数(也称为合成数)

算术基本定理

对于 p 是一个素数,如果 p 是 a1 * a2 的公约数,则 p 是 a1 的公约数或 p 是 a2 的公约数,这俩个条件中的其中一个必定成立。

互素

俩个整数互素,则 gcd(x,y) = 1

多个整数互素,则 gcd(x,y,z) = 1

同余

定义

同余在数论中是一种等价关系,当俩个整数除以同一个正整数,若余数相同,则称俩个整数同余。同余也是抽象代数中的同余关系的原型。

记作 a ≡ b (mod m)

乘法逆元

定义

如果一个线性同余方程 ax ≡ 1 (mod b),则称 x 为 a mod b 的逆元,记作 a-1

存在性

ax ≡ 1 (mod b) ,若a 与b 互质, 则一定存在一个正整数解x, 满足x < b,若a 与b 不互质, 则一定不存在正整数解x.

所以乘法逆元要求 a 和 b 互质

扩展欧几里得算法求逆元

因为扩展欧几里得算法就是 求ax + by = gcd(a, b) 的一组可行解 ,而 ax ≡ 1 (mod b) 实际上可以写成 ax-by = 1,再将y变成负的话,就是ax+by = 1;这样就直接套用扩展欧几里得算法就好了。

除了可以用扩展欧几里得算法求逆元,还可以用线性求逆元以及欧拉定理求逆元,下次学。

文章来源:https://blog.csdn.net/Sciurdae/article/details/134980278
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。