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

  • 1. 梅森素数简介
  • 2. GIMPS 项目
  • 3. 卢卡斯-莱默测验

1. 梅森素数简介

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

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

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

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

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

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

设 q≡3mod4q ≡ 3 mod 4q≡3mod4 为素数。则 2q+12q+12q+1 是素数的充分必要条件是 2q+1∣Mq2q+1 | M_q2q+1∣Mq​ ,因此对于这些素数 qqq(除3以外),MqM_qMq​ 不可能是素数。

前几个这样的素数 qqq 为 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年代作了改进,因此得名。该方法基于循环数列的计算,其原理是:

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

例如,M3=7M_3=7M3​=7,S1=14S_1=14S1​=14,由于 M3∣S1M_3 | S_1M3​∣S1​,因此 M3M_3M3​ 为素数。看似简单的问题,随著素数 ppp 值的增大,每一个梅森素数 MpM_pMp​ 的产生都无比艰辛。然而,人们对于梅森素数搜寻仍乐此不疲。

2. GIMPS 项目

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


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


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

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


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

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


如果搜寻到了新的梅森素数,那么你也可以领取奖励,有关奖励的最新说明如下:


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


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

3. 卢卡斯-莱默测验

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

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

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

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

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

# 最后输出的 lucas 值等于 0 当且仅当 Mp 为素数
def lucas_lehmer(p):my_list=[4]value=2**p-1lucas=4for val in range(1, p - 1):lucas = ((lucas*lucas)-2) % valuemy_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 - 1s = 4for i in range(2, n):sqr = s*ss = (sqr & m) + (sqr >> n)if s >= m:s -= ms -= 2return s == 0

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

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


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

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

  1. 目标检测相关算法综述

    目标检测相关算法综述 1. R-CNN[1] 2. SPP-Net[2] 3.Fast Rcnn[3] 4.Faster Rcnn[4] 5.Cascade Rcnn[5] 6.FPN[6] 7.YO ...

  2. 100个python算法超详细讲解:梅森素数

    [100个python算法超详细讲解@谷哥技术] 1.问题描述 梅森数(Mersenne Prime)指的是形如2 n -1的正整数,其中指数n 是素数,记为Mn.如果一个梅森数是素数,则称其为梅森素 ...

  3. JAVA算法练习(3):梅森素数

    ------文章底部代码分享 一.题目 如果一个数字的所有真因子之和等于自身,则称它为"完全数"或"完美数"例如: 6 = 1 + 2 + 328 = 1 + ...

  4. 梅森素数为什么这么重要?

    "它反映了一个国家的科技水平,是人类智力发展在数学上的一种标志,更是整个科技发展的里程碑之一.梅森素数究竟是个怎样的数,为何如此重要呢?" 众所周知,素数也叫质数,是只能被自己和1 ...

  5. 梅森素数:千年不休的探寻之旅

    还记得年少时的梦吗? 还记得你小学时背诵的素数表吗?那时候它还叫做质数表"2.3.5.7......"如今你是否已经真正理解了老师说过的话:这些只能被1和本身整除的数,具有着无穷的 ...

  6. python程序判断梅森素数_梅森素数的探索之旅

    2009年5月22日,对于很多人来说并不是什么特别的日志,不过数学界这边又传来了一个"喜讯":我们已经找到了第47个梅森素数,即$2^{42643801}-1$是一个素数!新的素数 ...

  7. 多视图点云配准算法综述

    作者:杨佳琪,张世坤,范世超等 转载自:华中科技大学学报(自然科学版) 编辑:东岸因为@一点人工一点智能 原文:​​多视图点云配准算法综述​​ 摘要:以多视图点云配准为研究对象,对近二十余年的多视图点 ...

  8. 梅森素数--美丽的贝壳

    一.价值五万美元的素数 2000年4月6日,住在美国密歇根州普利茅茨的那扬·哈吉拉特瓦 拉(Nayan Hajratwala)先生得到了一笔五万美元的数学奖金,因为他 找到了迄今为止已知的最大素数,这 ...

  9. 十万美元的悬赏——互联网梅森素数大搜索

    一.价值五万美元的素数 2000年4月6日,住在美国密歇根州普利茅茨的那扬·哈吉拉特瓦拉(Nayan Hajratwala)先生得到了一笔五万美元的数学奖金,因为他找到了迄今为止已知的最大素数,这是一 ...

最新文章

  1. Fragment导入包的问题
  2. CSDN 文章标题含非法字符
  3. ubuntu14.04不能安全卸载移动硬盘
  4. HTML/CSS基础知识(四)
  5. matlab aviobj,MATLAB AVI 视频读取处理
  6. python数据挖掘学习笔记】十.Pandas、Matplotlib、PCA绘图实用代码补充
  7. 用markdown + html写一封简历
  8. 函数中结构体指针作为形参修改指针地址
  9. 学习C++项目—— 计算机网络编程基础 和 学习多线程,多进程基础
  10. linux脚本写的计算器,Linux bc命令实现数学计算器
  11. 分蛋糕、思路视频(动态规划)
  12. 从头到尾理解假设检验
  13. java 实现金额大小写转换
  14. TFN TT70网络综合分析仪性能如何
  15. PR/PO一锅粥,关键信息一图兜
  16. Docker 4.2:Docker 公有镜像仓库 - 阿里云容器镜像服务
  17. 表格标签案例---个人简历
  18. OpenStack实例创建失败
  19. 什么人不在生死簿_高人亲眼所见的“地狱、生死簿、三世因果”(转)阴间一直是世...
  20. (原创)添加QQ好友日期爬虫01——总体思路

热门文章

  1. Python40个自动化办公实战案例,终于实现下班自由啦~
  2. 150. 逆波兰表达式求值。
  3. 用UDP实现HTTP Streaming协议从指定的URL拉流
  4. iOS中模拟器常用操作
  5. U盘提示需要格式化?优盘损坏修复
  6. ExtJs 备忘录(9)—— Ext常用属性、方法小结 [系列完]
  7. Tensorflow Embedding
  8. 【模电】0012 功率放大电路
  9. 【Java设计模式 规范与重构】 一 重构的目的、内容、时机、方法
  10. java考勤程序,请为一个公司编写程序记录公司员工出勤情况