程序员的数学思维修炼(趣味解读)神奇的素数

素数在自然数中占有非常重要的地位,素数是一类既简单又神秘的数字。说其简单, 是因为小学生也知道什么是素数;说其神秘,是因为从古至今,多少数学家都想弄明白素 数的规则,却一直没有找到其分布规律。

数学家都没研究出来的规律,程序员当然也不可能会找到。但是,任何事物都有正反 两面,正是由于素数的无规律特点,在密码学中就可以大量采用。另外,在一些齿轮啮合 设计中,也通常将齿轮的齿数设计成素数,以增加两齿轮中两个相同的齿相遇啮合次数的 最小公倍数,这样可增强齿轮的耐用度,减少故障。

2.1    怎么判断素数

怎么判断素数呢?首先需要对素数进行定义,然后根据其定义判断指定的数是不是素 数。对程序员来说,可以按素数的定义编写相应程序对素数进行判断。

2.1.1    什么是素数

数学中的定义是这样的:素数,又称为质数,是指在一个大于1的自然数中,除了1和 此整数自身外,无法被其他自然数整除的数。或者说素数是只有1和本身两个因数的数。

比1大但不是素数的数称为合数。1和0既非素数也非合数。

根据素数的定义,可用如图2-1所示方式列出10以内各数的因数,从而得出2 、3 、5、 7为素数,而4 、6 、8 、9不是素数。

 

图2-1

从上面的因数分解可看出,10以内共有4个素数。随着数据的增大,素数的分布频率 将变得更稀少,10000以内的素数共有1229个,由于篇幅所限不逐一列出,下面列出1000 以内的168个素数,如图2-2所示。

 

图2-2

对图2-2所列出的1000以内的素数进行总结,可看出在以100为间隔的区间中素数的个 数是没有规律的,其中:

100以内的素数有25个;

100~200之间的素数有21个;

200~300之间的素数有16个;

300~400之间的素数有16个;

400~500之间的素数有17个;

500~600之间的素数有14个;

600~700之间的素数有16个;

700~800之间的素数有14个;

800~900之间的素数有15个;

900~1000之间的素数有14个。

目前最大的已知素数是257885161-1  (此数字位长度是17425170) ,它是在2013年1月 25日由GIMPS发现的。该组织还在2008年8月23日发现了目前所知第二大的已知素数    243112609-1  (此数字位长度是12978189) 。

在图2-2中列出了1000以内的素数,究竟这些数据是不是素数呢?需要进行验证。

验证一个自然数是否为素数,这个问题在中世纪就引起了人们的注意,当时人们试图 寻找一个公式一劳永逸地解决问题,到了高斯时代,基本上确认了简单的素数公式是不存 在的,因此,高斯认为对素性判定是一个相当困难的问题。从此以后,这个问题吸引了大 批数学家。验证素数的算法可分为两大类,即确定性算法及随机算法,如图2-3所示。

 

图2-3

确定性算法可得出确定的结果,但通常算法较慢,而随机算法正好相反。通过计算机 进行运算,可解决算法较慢的问题,其算法的实现也很简单。

确定性算法中最常用的就是试除法。试除法是根据素数的定义得出的一种方法,用需 要验证的数N逐个除以从2开始至N-1中的所有数,若能被某一个数整除,表示有一个因 数,说明数N不是素数;若直到N-1都不能被整除,则说明该数是素数。

根据以上思路,可编写以下的试除法函数:

 

其实,可以对素数的定义进行进一步的分析。要判断数N是否为素数,不需要用N一 直除到N-1才能确认,而只需要除到

就可以了。例如,N=15 ,则能被15整除的除数 有1 、3 、5 ,对于除数5就不用判断,因为N被3整除时其商就是5 ,也就表示N能被5整除 了。

因此,为了减少循环判断的次数,提高程序的执行效率,可将函数is_prime()进行修

改,以提高程序的效率。

 

从上面的程序可看到,在for循环中以i2与n值进行比较,就可以显著地减少循环的次

数,从而提高验证的效率。

通过验证方法可以验证某个整数是否为素数,而寻找素数的方法,就是寻找在给定限 度内的所有素数排列。例如,要求出1000以内的所有素数,就是一个寻找素数排列的问  题。由于已经有上面定义的is_prime()函数,求出1000以内所有素数的方法就很简单了,

可以用以下程序来完成。

 

执行以上程序,可得到1000以内的所有素数列表,如图2-4所示。

 

图2-4

在上面的代码中,通过is_prime()函数来验证指定区间 (2~1000) 中的每一个数是否 为素数,而is_prime()函数中又通过循环进行验证。这种双循环会导致程序执行效率不   高。

这时可考虑采用另一种寻找素数的算法:著名的Eratosthenes求素数方法。下面演示 如何用这种方法求100以内的素数。

Eratosthenes算法假设有一个筛子,用来存放2~100之间的所有数,如图2-5  (a) 所 示。

 

图2-5

由于偶数都能被2整数,因此偶数都不是素数 (2除外) ,则将这些数筛去,得到如图

2-5  (b) 所示的数据 (设置了背景色的数字将被筛去) 。

接着再将3的倍数筛去,得到如图2-5  (c) 所示结果。

接下来继续将5的倍数筛去,得到图2-5  (d) 所示结果。

最后再将7的倍数筛去,得到如图2-5  (e) 所示结果,即可得到100以内的所有素数。

从图2-5中可看到,在使用Eratosthenes算法进行筛选时,只需要执行4次筛选就完成了 100以内的素数的筛选,效率非常高。如果要筛选的数据范围更大,由于只需要选择已经 筛选过的素数对后面的数进行筛选,因此可快速筛选出后面的素数。

从图2-5中的算法过程可以看出,Eratosthenes算法比试除法的效率要高得多。

根据图2-5中所示的过程编写相应的程序,具体代码如下:

 

2.1.4    已被证明的素数定理

自古以来就有很多数学家研究素数,因此,得出了许多与素数有关的定理。下面简单 介绍一些已被证明的素数定理。

1 .在(a,2a]之间必有一个素数

在一个大于1的数a和它的2倍之间 (即区间(a,2a]中) 必存在一个素数。如图2-6所

示,可看到在(a,2a]区间中都至少包含一个素数。

 

图2-6

2 .存在任意长度的素数等差数列

什么是等差数列呢?这是一个古老的数学课题。一个数列从第二项起,从后项减去前

项所得的差是一个相同的常数,则这个数列就被称为等差数列。

 

用素数构成的等差数列被称为素数等差数列。例如从5开始,以12为间隔常数,就可 以得到这样的序列:

 

对这个数列来说,只有前5个数是素数,第6个数65能被5整除,不是素数,因此,在

这里得到的是由5个素数构成的素数等差数列:

 

还有更长的素数等差数列吗?当然有,如下面的10个素数就构成间隔为210的素数等 差数列:

 

2004年4月18日,格林和陶哲轩两人宣布:他们证明了“存在任意长度的素数等差数  列” ,也就是说,对于任意值K ,存在K个成等差级数的素数。例如K=3 ,有素数序列3 、 5 、7  (两数之间差2) … …K=10 ,有素数序列199 、409 、619 、829 、1039 、1249 、     1459 、1669 、1879 、2089  (两数之间差210) 。他们将长达50页的论文——《素数含有任 意长度的等差数列》张贴在当日的预印本网站上,并向《美国数学年鉴》  (Annals         of Mathematics) 投稿。

这是一项惊人的成就,他们的发现揭示了素数中存在的某种规律。他们的证明立即在 国际学术界引起轰动。

3 .其他已证明的素数定理

已证明的素数定理还包括以下几项:

一个偶数可以写成两个数字之和,其中每一个数字最多只有9个质因数。 一个偶数必定可以写成一个质数加上一个合数,其中的因子个数有上界。

一个偶数必定可以写成一个质数加上一个最多由5个因子所组成的合数。后来,有人 简称这个结果为 (1+5) 。

一个充分大偶数必定可以写成一个素数加上一个最多由2个质因子所组成的合数,简 称为 (1+2) 。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

生活家小毛

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

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

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

打赏作者

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

抵扣说明:

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

余额充值