码龄0.5年的python成长之路(11):找素数的模块 & 观察素数

素数定义:只能被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)
  • 结果:
110万的整数中:有1224对满足孪生素数猜想的数字。
  • 我们还可以看看p的分布(代码就不写了,直接上图)
    在这里插入图片描述
  • 这“对儿数”,还真像是对数(log)分布了。

暂时到这儿吧,下次见

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

小熊@RoyalzoneTCM

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

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

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

打赏作者

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

抵扣说明:

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

余额充值