埃拉托色尼素数筛选法的证明及原理

一、什么是素数?

  素数又称为质数。素数定义为在大于1的自然数中,除了1和它本身以外不再有其他因数。素数在日常中最多的应用就是加密算法,例如RSA加密算法就是基于来实现的。RSA算法会随机生成两个1024位的质数相乘,要破解密码必须对乘积做质因数分解,而1024位的质因数分解是非常困难的。

二、如何快速的算出小于某个数的所有素数?

  从素数的概念上似乎可以很快得出一个算素数的公式,即将一个数循环做除法,从1一直除到它本身,如果中途只有被1和自己整除了这个数便是素数了,这样的计算效率是非常差的,因为他会不停的遍历整个数据范围。我们来试着跑一下它的效率:

#求10万以内的素数
import datetime
start = datetime.datetime.now()
for i in range(2,100000):
    for j in range(2,i):
        if i%j == 0:
            break
    #else:
        #print(i)
stop = datetime.datetime.now()
print(stop-start)

  运行结果: 0:01:04.326679 ,在没有print的情况下竟然用了1分多钟,并且数字越大计算越慢。这样的效率肯定是不被允许的。下面介绍一种最常见的质数算法的原理:

三、埃拉托色尼素数筛选法

  埃拉托色尼是一名古希腊的地理学家,他是世界上第一个计算出地球周长的人。埃拉托色尼素数筛选法可以很快速的计算出1到N之间的所有素数。将n开根号,即N^0.5,去掉2到N^0.5中所有素数的倍数,剩下的数便都是素数了。例如求1到25中的素数有哪些,第一步是将25开根号,得到5;第二步将2到5的素数取出来,分别是2、3、5;再将2到25中且是2、3、5的倍数的数去掉,即去掉4、6、8、9、10、12、14、15、16、18、20、21、22、24、25,剩下2、3、5、7、11、13、17、19便是1到25中的所有素数了。

  这里还用到了一个数学知识,即只要小于或等于根号N的数(1除外)不能整除N,则N一定是素数;反过来说就是只要小于或等于根号N的数(1除外)能整除N,则N一定是合数。下面给出证明过程:

假设一个数N是合适,那一定存在一个因数b和一个非1且非自身的因数a,即a*b=N

等式两边同时开根号得出:(a*b)^0.5=a^0.5*b^0.5=N^0.5

可以推出:若N为合数,则a和b中一定有一个大于或等于N^0.5,另一个小于或等于N^0.5

  按照这个结论,就只需计算小于等于N^0.5的数了,这样就大大提高了效率(要注意等于N^0.5的这个边界):

#求10万以内的素数
import datetime
start = datetime.datetime.now()
for i in range(2,100000):
    for j in range(2,int(i**0.5+1)): #边界需要加1
        if i%j == 0:
            break
    #else:
        #print(i)
stop = datetime.datetime.now()
print(stop-start)

  运行结果: 0:00:00.428024 。可以说是质的飞跃。

小的优化

  我们也可以将偶数事先就排除在外,然后在进行素数筛选:

#求10万以内的素数
import datetime
start = datetime.datetime.now()
print(2)
for i in range(3,100000,2): #从3开始,跳过偶数
    for j in range(2,int(i**0.5+1)):
        if i%j == 0:
            break
    #else:
        #print(i)
stop = datetime.datetime.now()
print(stop-start)

  运行结果: 0:00:00.406024 ,又快了不少。

猜你喜欢

转载自www.cnblogs.com/readygood/p/10202004.html
今日推荐