GIMPS梅森素数搜寻及相关算法综述

本文介绍了梅森素数的定义、梅森素数搜寻项目GIMPS的历史与贡献,重点阐述了卢卡斯-莱默测验在素性检验中的关键作用。讨论了GIMPS发现新素数的艰难过程,以及如何利用该算法提高效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

GIMPS梅森素数搜寻及相关算法综述

1. 梅森素数简介

梅森数是指形如 2 n − 1 {\displaystyle 2^{n}-1} 2n1 的数,记为 M n {\displaystyle M_{n}} Mn,如果一个梅森数是素数那么它被称为梅森素数(Mersenne prime)。

梅森数是根据17世纪法国数学家马林·梅森(Marin Mersenne)的名字命名的,他列出了 n ≤ 257 n \leq 257 n257 的梅森素数,不过他错误地包括了不是梅森素数的 M 67 M_{67} M67 M 257 M_{257} M257,而遗漏了 M 61 M_{61} M61 M 89 M_{89} M89 M 107 M_{107} M107

现在我们更关注的是,梅森素数具有哪些重要性质。

n n n 为合数时, M n {\displaystyle M_{n}} Mn 一定为合数(因为当 a 整除 b 时, M a {\displaystyle M_{a}} Ma 一定整除 M b {\displaystyle M_{b}} Mb,反之亦然)。但当 n n n 为素数时, M n {\displaystyle M_{n}} Mn不一定皆为素数,比如 M 2 = 2 2 − 1 = 3 {\displaystyle M_{2}=2^{2}-1=3} M2=221=3 M 3 = 2 3 − 1 = 7 {\displaystyle M_{3}=2^{3}-1=7} M3=231=7 是素数,但 M 11 = 2 11 − 1 = 2047 = 23 × 89 {\displaystyle M_{11}=2^{11}-1=2047=23\times 89} M11=2111=2047=23×89 却不是素数。

另一方面,当 M n M_n Mn 为素数时,则 n n n 一定为素数。基于此,为搜寻梅森素数,我们可以将目标限定在 n n n 取素数的场合。

截至2022年8月,已知的梅森素数共有51个。其中最大的梅森素数是 2 82589933 − 1 {\displaystyle 2^{82589933}-1} 2825899331 该数足有 24,862,048 位十进制数,也是已知最大的素数。从1997年至今,所有新的梅森素数都是由 互联网梅森素数大搜索(GIMPS) 分布式计算项目发现的。然而下面的结论也是十分有趣的:

q ≡ 3 m o d 4 q ≡ 3 mod 4 q3mod4 为素数。则 2 q + 1 2q+1 2q+1 是素数的充分必要条件是 2 q + 1 ∣ M q 2q+1 | M_q 2q+1∣Mq ,因此对于这些素数 q q q(除3以外), M q M_q Mq 不可能是素数。

前几个这样的素数 q q q 为 11, 23, 83, 131, 179, 191, 239, 251, 359, 419, 431, 443, 491, 659, 683, 719, 743, 911, 1019, 1031, 1103, 1223, 1439, 1451, 1499, 1511, 1559, 1583, 1811, 1931, 2003, 2039, 2063, 2339, 2351, 2399, 2459, 2543, 2699, 2819, 2903, 2939, 2963, 3023, 3299, …

以上正是搜寻梅森素数时需要进一步排除的情形,同时也节省了很多计算时间,但这个长长的素数序列需要提前创建出来。关于梅森数的素性检验,目前最好的方法当属卢卡斯-莱默检验(Lucas–Lehmer primality test)。

该方法由爱德华·卢卡斯于1878年发现,并由德里克·亨利·莱默于1930年代作了改进,因此得名。该方法基于循环数列的计算,其原理是:

M n M_n Mn 为素数当且仅当 M n ∣ S n − 2 M_n | S_{n-2} MnSn2 , 其中 S 0 = 4 , S k = S k − 1 2 − 2 , k > 0 S_0=4,S_k = S^2_{k − 1} − 2,k > 0 S0=4Sk=Sk122k>0,此数列具体为 4, 14, 194, 37634, 1416317954, 2005956546822746114, …

例如, M 3 = 7 M_3=7 M3=7 S 1 = 14 S_1=14 S1=14,由于 M 3 ∣ S 1 M_3 | S_1 M3S1,因此 M 3 M_3 M3 为素数。看似简单的问题,随著素数 p p p 值的增大,每一个梅森素数 M p M_p Mp 的产生都无比艰辛。然而,人们对于梅森素数搜寻仍乐此不疲。

2. GIMPS 项目

目前梅森素数搜寻最重要的途径当属 GIMPS 了,即因特网梅森素数大搜索。自1996年11月到现在,所有梅森素数皆由 GIMPS 发现。GIMPS 官网成立于1996年:

GIMPS
通过点击 Instructions 首先创建自己的账户:

在这里插入图片描述
账户创建好后,点击上图中的 Downloads 下载对应操作系统的 Prime95 软件,笔者使用的是2022年8月9日发布的 Prime95 version 30.8b16 版本。本软件无需安装,直接解压即可使用。

开启程序后如果没有自动分配计算任务,则点击 Advanced → Round off checking 即可开启第一个计算任务。

在这里插入图片描述
图中是当前作者的计算任务,正在通过 LL 算法完成梅森数 M 66384743 M_{66384743} M66384743 的 Double-Check。至于Prime95 其它功能,可以查看 Help 帮助。

我们也可以加入一个计算团队,比如笔者加入了 GIMPSChina 计算团队。

在这里插入图片描述
如果搜寻到了新的梅森素数,那么你也可以领取奖励,有关奖励的最新说明如下:

在这里插入图片描述
当然,对于绝大多数爱好者,参与 GIMPS 搜寻梅森素数也绝不是为了领取奖金,因为发现一个新的梅森素数实在是太难了。截止2022年7月18日,所有低于 61427809 的测试都得到了验证,即 M n M_n Mn 中, n ≤ 61 , 427 , 809 n \leq 61,427,809 n61,427,809 的梅森数都已经通过了再次验证,并于2021年10月6日确定出了第48个梅森素数 M 57885161 M_{57885161} M57885161。而后续三个数,目前还未确定是不是第49、50、51个梅森素数,因此在序号后面加上了红色星号,有关序号的确认,目前还在 GIMPS 的大量计算中。

在这里插入图片描述
从2018年至今将近四年过去了,仍没有发现 M 82589933 M_{82589933} M82589933 之后的下一个梅森素数或者发现 M 82589933 M_{82589933} M82589933 之前可能漏掉的梅森素数。截止2022年3月30日,所有低于1.09亿的测试至少进行了一次,即 M n M_n Mn 中, n ≤ 109 , 460 , 867 n \leq 109,460,867 n109,460,867 的梅森数都已经测试了至少一次,仍未发现新的梅森素数。可见计算之艰巨,要发现一个新的梅森素数,当以年记。如果加入 GIMPS 搜寻项目的人越多,也越能加快新梅森素数的发现。

3. 卢卡斯-莱默测验

卢卡斯-莱默测验基于如下定理:

定理 p p p 是一个奇素数,则梅森数 M p M_p Mp 是素数当且仅当 M p ∣ S p − 2 M_p | S_{p-2} MpSp2,其中 S 0 = 4 , S k = S k − 1 2 − 2 , k > 0 S_0=4,S_k = S^2_{k − 1} − 2,k > 0 S0=4Sk=Sk122k>0

该定理的好处在于,将复杂的素性判断归结为简单的整除、迭代问题,因此非常高效地提升了素性检验的效率。如此好的方法,只对梅森素数有效,至于一般的大整数,其素性判断只能通过其他方法。比如概率方向的Miller-Rabin算法,2021年5月8日已测试出一个 8,177,207 位可能的素数 R 8177207 R_{8177207 } R8177207。另一方面,椭圆曲线方向的ECPP算法,能证明一个大整数是素数,也是目前无条件证明大整数是素数的最有效的方法。2022年6月1日,一个 50001 位的素数 1 0 50000 + 65859 10^{50000 }+ 65859 1050000+65859 已经得到了证明,也是目前通过 ECPP 证明的最大的素数。

以下是一段卢卡斯-莱默测验的伪代码

Lucas_Lehmer_Test(p):
  s := 4;
  for i from 3 to p do s := s^2-2 mod 2^p-1;
  if s == 0 then
    2^p-1 is prime
  else
    2^p-1 is composite;

这个测试的理论是 Lucas 在19世纪70年代末提出的,然后在1930年左右由 Lehmer 提出了这个简单的测试。通过序列 S p − 2 S_{p-2} Sp2 M p M_p Mp 取模,以节省大量运算时间。这个测试对于二进制计算机还非常理想,因为对 M p M_p Mp 的二进制除法可以只使用旋转和加法来完成。

下面我们给出卢卡斯-莱默测验的完整 Python 代码:

# 最后输出的 lucas 值等于 0 当且仅当 Mp 为素数
def lucas_lehmer(p):
    my_list=[4]
    value=2**p-1
    lucas=4
    for val in range(1, p - 1):
        lucas = ((lucas*lucas)-2) % value
        my_list.append(lucas)
    if lucas == 0:
        print("prime")
    else:
        print("composite")
    # print(my_list)
    # 仅打印最后的 lucas 值
    print(lucas) 

经测试,计算 lucas_lehmer(19937) 所花费的时间仅为 23.4672 秒,而这已是第24个梅森素数,该数首次发现于1971年3月4日,仅有 6,002 位十进制数。

为了进一步加快更大梅森素数的判定,我们将取模运算替换成位运算,完整代码如下:

# 更快速判定梅森素数
def lucas_lehmer_fast(n):
    m = 2**n - 1
    s = 4
    for i in range(2, n):
        sqr = s*s
        s = (sqr & m) + (sqr >> n)
        if s >= m:
            s -= m
        s -= 2
    return s == 0

经测试,同样计算 lucas_lehmer_fast(19937) 所花费的时间仅为 5.3317 秒,比之前的算法有了明显的改善。而计算 lucas_lehmer_fast(86243) 所花费的时间仅为 4分01.4661 秒,而这已是第28个梅森素数,该数首次发现于1982年9月25日,该素数足有 25,962 位!

以上,我们了解了梅森素数和 GIMPS 的基本知识,感受了自己编程验证梅森素数的过程,体会了随着 M p M_p Mp p p p 值的增大,相应的计算会越来越困难,个人的能力越来越有限,因此通过 GIMPS 加入梅森素数的搜寻工作将是一件十分不错的事情。


参考文献
[1]: List of Known Mersenne Prime Numbers
[2]: Mersenne Primes: History, Theorems and Lists

评论 13
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Tengfei Wang

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值