素数定义:只能被1和自己整除的数。
关于素数,有以下有趣的事实:
- 素数的数量有无限多。
- 素数的分布。随着X的增大,素数的分布越来越稀疏;第n个素数渐进于logn;随机整数 X是素数的概率是1/logX。(下面证明这是错的) - 对于任意正整数n,存在至少n个连续的正合数。
有大量关于素数的猜想,著名的有:
- 波特兰猜想。对任意给定的正整数n > 1,存在一个素数p,使得n < p < 2n。已经证明。
- 孪生素数猜想。存在无穷多的形如p和p+2的素数对。
- 素数等差数列猜想。对任意正整数n >2,有一个由素数组成的长度为n的等差数列。
- 哥德巴赫猜想。每个大于2的正偶数可以写成两个素数的和。这是最有名的素数猜想,也是最令人头疼的猜想,已经困扰数学家3世纪。至今为止,最好的结果仍然是陈景润1966年做出的。
1. 尝试重新写寻找素数的模块
- 生成1到100的数列表:
import numpy as np
nums = np.arange(1, 101)
- 得到:
array([ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26,
27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39,
40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52,
53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65,
66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78,
79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91,
92, 93, 94, 95, 96, 97, 98, 99, 100])
- 写个识别nums列表中素数的列表的封装函数:
oddlist = []
for i in nums: # 开始判断每个数是不是素数
if i == 1:
continue # 1不被定义为素数
if i == 2 or i == 3 or i == 5:
oddlist.append(i) # 2,3,5 直接添加进去
else:
for j in oddlist:
if i % j == 0: # 遇到可以被苏素数整除,则停止循环
break
else: # 否则一直迭代
while j is oddlist[-1]: # 直到循环到最后一个j,
if i % j != 0:
# 并且i被最后一个j也不能整除,证明是素数
oddlist.append(i) # 添加进素数列表
continue # 继续循环
- 我们来print一下 oddlist 看看函数是否正确
[2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97]
# len(oddlist) = 25
- 封装成一个函数
def find_odd(nums):
oddlist = []
for i in nums: # 开始判断每个数是不是素数
if i == 1:
continue # 1不被定义为素数
if i == 2 or i == 3 or i == 5:
oddlist.append(i) # 2,3,5 直接添加进去
else:
for j in oddlist:
if i % j == 0: # 遇到可以被苏素数整除,则停止循环
break
else: # 否则一直迭代
while j is oddlist[-1]: # 直到循环到最后一个j,
if i % j != 0: # 并且i被最后一个j也不能整除,证明是素数
oddlist.append(i) # 添加进素数列表
continue # 继续循环
return oddlist
2. 来观察一下10万整数内的素数数量的分布
- 10万个数用上诉模块算可以十几秒出结果;
- 我们用matplotlib库来做hist图,可以观察到素数量。
- 图片如上,代码如下:
import matplotlib.pyplot as plt
plt.figure(figsize=(16, 4))
plt.subplot(121)
plt.hist(oddlist, bins=100, log=True)
plt.title('oddlist hist with log', fontsize=14)
plt.subplot(122)
plt.hist(oddlist, bins=100, color='purple', alpha=0.5, log=False)
plt.title('oddlist hist actual amount', fontsize=14)
plt.show()
- 可以观察到,就算是用log来拉大数的差别,我们看到越往大的数走,同一个数值区间内可以发现的素数量虽有浮动、大体在稳定的范围内。
3. 孪生素数猜想
- 孪生素数猜想:存在无穷多的形如p和p+2的素数对。
- 我们至少可以在这10万个数据当中看看有多少,用程序试试看。
- 遇到数字对,我们只记录左值,也就是p,那么数组的长度就是“有多少对”满足孪生素数猜想的数字。
- 代码如下:
twinleft = []
for i in oddlist:
if i == oddlist[-1]:
break
elif int(i) + 2 == oddlist[oddlist.index(i) + 1]:
twinleft.append(i)
continue
len(twinleft)
- 结果:
从1到10万的整数中:有1224对满足孪生素数猜想的数字。
- 我们还可以看看p的分布(代码就不写了,直接上图)
- 这“对儿数”,还真像是对数(log)分布了。