前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >一次找出范围内的所有素数,埃式筛法是什么神仙算法?

一次找出范围内的所有素数,埃式筛法是什么神仙算法?

作者头像
TechFlow-承志
发布于 2020-06-09 05:09:40
发布于 2020-06-09 05:09:40
1.1K00
代码可运行
举报
文章被收录于专栏:TechFlowTechFlow
运行总次数:0
代码可运行

今天这篇是算法与数据结构专题的第23篇文章,我们继续数论相关的算法,来看看大名鼎鼎的埃式筛法。

我们都知道在数学领域,素数非常重要,有海量的公式和研究关于素数,比如那个非常著名至今没有人解出来的哥德巴赫猜想。和数学领域一样,素数在信息领域也非常重要,有着大量的应用。举个简单的例子,很多安全加密算法也是利用的质数。我们想要利用素数去进行各种计算之前,总是要先找到素数。所以这就有了一个最简单也最不简单的问题,我们怎么样来寻找素数呢?

判断素数

寻找素数最朴素的方法当然是一个一个遍历,我们依次遍历每一个数,然后分别判断是否是素数。所以问题的核心又回到了判断素数上,那么怎么判断一个数是不是素数呢?

素数的性质只有一个,就是只有1和它本身这两个因数,我们要判断素数也只能利用这个性质。所以可以想到,假如我们要判断n是否是素数,可以从2开始遍历到n-1,如果这n-1个数都不能整除n,那么说明n就是素数。这个我没记错在C语言的练习题当中出现过,总之非常简单,可以说是最简单的算法了。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
def is_prime(n):
    for i in range(2, n):
        if n % i == 0:
            return False
    return n != 1

显然,这个算法是可以优化的,比如当n是偶数的时候,我们根本不需要循环,除了2以外的偶数一定是合数。再比如,我们循环的上界其实也没有必要到n-1,到就可以了。因为因数如果存在一定是成对出现的,如果存在小于根号n的因数,那么n除以它一定大于根号n。

这个改进也很简单,稍作改动即可:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
def is_prime(n):
    if n % 2 == 0 and n != 2:
        return False
    for i in range(3, int(math.sqrt(n) + 1)):
        if n % i == 0:
            return False
    return n != 1

这样我们把O(n)的算法优化到了O()也算是有了很大的改进了,但是还没有结束,我们还可以继续优化。数学上有一个定理,只有形如6n-1和6n+1的自然数可能是素数,这里的n是大于等于1的整数。

这个定理乍一看好像很高级,但其实很简单,因为所有自然数都可以写成6n,6n+1,6n+2,6n+3,6n+4,6n+5这6种,其中6n,6n+2,6n+4是偶数,一定不是素数。6n+3可以写成3(2n+1),显然也不是素数,所以只有可能6n+1和6n+5可能是素数。6n+5等价于6n-1,所以我们一般写成6n-1和6n+1。

利用这个定理,我们的代码可以进一步优化:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
def is_prime(n):
    if n % 6 not in (1, 5) and n not in (2, 3):
        return False
    for i in range(3, int(math.sqrt(n) + 1)):
        if n % i == 0:
            return False
    return n != 1

虽然这样已经很快了,但仍然不是最优的,尤其是当我们需要寻找大量素数的时候,仍会消耗大量的时间。那么有没有什么办法可以批量查找素数呢?

有,这个方法叫做埃拉托斯特尼算法。这个名字念起来非常拗口,这是一个古希腊的名字。此人是个古希腊的大牛,是大名鼎鼎的阿基米德的好友。他虽然没有阿基米德那么出名,但是也非常非常厉害,在数学、天文学、地理学、文学、历史学等多个领域都有建树。并且还自创方法测量了地球直径、地月距离、地日距离以及黄赤交角等诸多数值。要知道他生活的年代是两千五百多年前,那时候中国还是春秋战国时期,可以想见此人有多厉害。

埃式筛法

我们今天要介绍的埃拉托斯特尼算法就是他发明的用来筛选素数的方法,为了方便我们一般简称为埃式筛法或者筛法。埃式筛法的思路非常简单,就是用已经筛选出来的素数去过滤所有能够被它整除的数。这些素数就像是筛子一样去过滤自然数,最后被筛剩下的数自然就是不能被前面素数整除的数,根据素数的定义,这些剩下的数也是素数。

举个例子,比如我们要筛选出100以内的所有素数,我们知道2是最小的素数,我们先用2可以筛掉所有的偶数。然后往后遍历到3,3是被2筛剩下的第一个数,也是素数,我们再用3去筛除所有能被3整除的数。筛完之后我们继续往后遍历,第一个遇到的数是7,所以7也是素数,我们再重复以上的过程,直到遍历结束为止。结束的时候,我们就获得了100以内的所有素数。

如果还不太明白,可以看下下面这张动图,非常清楚地还原了这整个过程。

这个思想非常简单,理解了之后写出代码来真的很容易:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
def eratosthenes(n):
    primes = []
    is_prime = [True] * (n + 1)
    for i in range(2, n+1):
        if is_prime[i]:
            primes.append(i)
            # 用当前素数i去筛掉所有能被它整除的数
            for j in range(i * 2, n+1, i):
                is_prime[j] = False
    return primes

我们运行一次代码看看:

和我们的预期一样,获得了小于100的所有素数。我们来分析一下筛法的复杂度,从代码当中我们可以看到,我们一共有了两层循环,最外面一层循环固定是遍历n次。而里面的这一层循环遍历的次数一直在变化,并且它的运算次数和素数的大小相关,看起来似乎不太方便计算。实际上是可以的,根据素数分布定理以及一系列复杂的运算(相信我,你们不会感兴趣的),我们是可以得出筛法的复杂度是。

极致优化

筛法的复杂度已经非常近似了,因为即使在n很大的时候,经过两次ln的计算,也非常近似常数了,实际上在绝大多数使用场景当中,上面的算法已经足够应用了。

但是仍然有大牛不知满足,继续对算法做出了优化,将其优化到了的复杂度。虽然从效率上来看并没有数量级的提升,但是应用到的思想非常巧妙,值得我们学习。在我们理解这个优化之前,先来看看之前的筛法还有什么可以优化的地方。比较明显地可以看出来,对于一个合数而言,它可能会被多个素数筛去。比如38,它有2和19这两个素因数,那么它就会被置为两次False,这就带来了额外的开销,如果对于每一个合数我们只更新一次,那么是不是就能优化到了呢?

怎么样保证每个合数只被更新一次呢?这里要用到一个定理,就是每个合数分解质因数只有的结果是唯一的。既然是唯一的,那么一定可以找到最小的质因数,如果我们能够保证一个合数只会被它最小的质因数更新为False,那么整个优化就完成了。

那我们具体怎么做呢?其实也不难,我们假设整数n的最小质因数是m,那么我们用小于m的素数i乘上n可以得到一个合数。我们将这个合数消除,对于这个合数而言,i一定是它最小的质因数。因为它等于i * n,n最小的质因数是m,i 又小于m,所以i是它最小的质因数,我们用这样的方法来生成消除的合数,这样来保证每个合数只会被它最小的质因数消除。

根据这一点,我们可以写出新的代码:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
def ertosthenes(n):
    primes = []
    is_prime = [True] * (n+1)
    for i in range(2, n+1):
        if is_prime[i]:
            primes.append(i)
        for j, p in enumerate(primes):
            # 防止越界
            if p > n // i:
                break
            # 过滤
   is_prime[i * p] = False
            # 当i % p等于0的时候说明p就是i最小的质因数
            if i % p == 0:
                break
                
    return primes

总结

到这里,我们关于埃式筛法的介绍就告一段落了。埃式筛法的优化版本相对来说要难以记忆一些,如果记不住的话,可以就只使用优化之前的版本,两者的效率相差并不大,完全在可以接受的范围之内。

筛法看着代码非常简单,但是非常重要,有了它,我们就可以在短时间内获得大量的素数,快速地获得一个素数表。有了素数表之后,很多问题就简单许多了,比如因数分解的问题,比如信息加密的问题等等。我每次回顾筛法算法的时候都会忍不住感慨,这个两千多年前被发明出来的算法至今看来非但不过时,仍然还是那么巧妙。希望大家都能怀着崇敬的心情,理解算法当中的精髓。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-06-03,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Coder梁 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
CMU贺斌教授团队提出:冥想可以增强对脑机接口的控制
脑机接口(BCI)是一种允许个人直接通过大脑控制机器或计算机的设备。与使用大脑植入的高风险侵入性方法相比,通过颅骨获取的非侵入性控制手段,如脑电图(EEG),既安全又方便,但它们需要更长的学习时间,使用者的的熟练程度最终会有所不同。
脑机接口社区
2020/09/30
8640
解密脑机接口:专访CMU生物医学工程系主任贺斌
脑机接口能做什么?带上电极帽,你可以在实验室中用意念控制无人机飞行;在大脑皮层中植入电极,瘫痪病人能够用意念打字或者驱动轮椅。无论是无创还是有创的脑机接口,都试图在人类大脑与外部机器之间建立连接。过去几十年中,脑机接口技术稳步发展,一步步从科幻走向现实,也开始从实验室走向生活。2019年7月,埃隆·马斯克旗下 Neuralink 公司发布了一款缝纫机式的外科机器人,它可以在头骨上打洞,并将3072个微电极置入大脑皮层。
脑机接口社区
2020/06/30
8580
解密脑机接口:专访CMU生物医学工程系主任贺斌
CMU重大突破:无需植入芯片,大脑意念即可控制机械臂
能够仅使用思想无创地控制机器人装置将具有广泛的应用,特别是有益于瘫痪患者和运动障碍患者的生活。
新智元
2019/07/05
5910
CMU重大突破:无需植入芯片,大脑意念即可控制机械臂
深度解析脑机接口技术的现状与未来!
通过在脑后插入一根线缆,我们就能够畅游计算机世界;只需一个意念我们就能改变“现实”;学习知识不再需要通过书本、视频等媒介,也不需要在花费大量的时间,只需直接将知识传输到大脑当中即可。这是1999年上映的经典科幻片《黑客帝国》当中,为我们描绘的画面。这并非是天马行空的幻想,而是基于早已有之的“脑机接口”技术的的合理设想。
数据猿
2020/06/28
2K0
深度解析脑机接口技术的现状与未来!
脑机接口与深度学习
脑机接口(BCI)是一种系统,可将受试者(人类或动物)的大脑活动模式提取并转换为用于交互式应用程序的消息或命令。脑活动模式是通过脑电图(EEG)获得的信号。
脑机接口社区
2020/06/30
1.4K0
挑战马斯克Neuralink!斯坦福全新脑机接口,直连大脑和硅基芯片
斯坦福大学材料科学与工程专业的研究生 Abdulmalik Obaid 说,“以前没有人把这些 2D 硅电子器件与大脑的三维结构相匹配,我们必须抛弃我们已经知道的传统芯片制造方法,设计新的工艺,将硅电子技术带入三维空间,我们必须以一种容易大规模应用的方式来实现这一目标。”
新智元
2020/04/01
6060
决策脑机接口:利用脑机接口改善你的决策性能
有些决定是瞬间做出的,有些则需要反复权衡。有时候反复权衡虽然能一定程度保障决定的全面性,但未必很高效。
脑机接口社区
2023/02/14
4240
决策脑机接口:利用脑机接口改善你的决策性能
脑机接口新进展!意念控制机器人离实现更近了一步!
多年来,研究人员一直在努力制造一种设备,让人们可以用他们的思想控制并独立地进行某些活动。
脑机接口社区
2022/08/25
6180
脑机接口新进展!意念控制机器人离实现更近了一步!
2021年过了大半了,脑机接口取得哪些进展?
NextMind's neural controller allows gameplay via a brain-computer interface.
脑机接口社区
2022/08/17
5060
2021年过了大半了,脑机接口取得哪些进展?
瘫痪患者借助脑机接口可进行数字绘画
一幅由瘫痪参与者创作的数字绘画。(来源:B M Dekleva et al J. Neural Eng. 10.1088/1741-2552/ac16b2)
脑机接口社区
2022/08/18
4230
瘫痪患者借助脑机接口可进行数字绘画
​基于脑机接口的闭环运动想象脑电图仿真
脑机接口(BCI),尤其是能够解码运动意图的脑机接口,由于其作为神经修复系统的潜力,能够改善患有各种运动功能损害病症(如脊髓损伤、肌萎缩侧索硬化症和中风)的患者的生活质量,已经成为积极研究的热门主题。一种成熟的方法是基于感觉运动节律(SMR)的运动想象BCI,它允许用户通过检测和解码与真实和想象的运动相关的SMR模式来控制物理或虚拟世界中仿真的运动。通常在BCI系统中,解码算法的测试、任务及其参数对于优化性能至关重要,然而,当研究广泛的参数集,进行人体实验既昂贵又耗时,而尝试利用以前收集到的数据线下分析却又缺乏系统和用户之间自适应反馈循环,极大限制了其适用性。因此,已有许多研究已经试图通过实时神经活动模拟器解决这一问题。
脑机接口社区
2023/02/14
7370
​基于脑机接口的闭环运动想象脑电图仿真
Nature子刊 | 清华大学研究团队联合提出一种基于视觉和听觉的耳内脑机接口
近日,清华大学柔性电子技术实验室冯雪教授课题组与医学院高小榕教授课题组合作,在《Nature Communications》期刊上在线发表了题为“用于视觉和听觉脑机接口的入耳式共形生物电子器件”(Conformal in-ear bioelectronics for visual and auditory brain-computer interfaces)的研究成果。在该研究中,研究人员提出了一种耳内的柔性三维附壁攀爬神经电子器件,开展了基于稳态视觉诱发电位和鸡尾酒会效应的视觉及听觉脑机接口(BCI)研究,并提出了基于耳内生物电子学的耳内视觉和听觉脑机接口,命名为Spiral E,这是一种耳内式脑电图监测设备。耳内式脑电图监测以其独特的可穿戴性和离散性等优点而备受关注。
脑机接口社区
2023/09/19
6340
Nature子刊 | 清华大学研究团队联合提出一种基于视觉和听觉的耳内脑机接口
北理工何际平团队:皮质内脑机接口的神经解码
自2014年巴西世界杯开幕式上,一名截瘫青年借助一副“机械战甲”外骨骼装置,用脑电波控制自己的“脚”踢出了第一球以来,脑机接口技术开始走入大众的视野。
脑机接口社区
2023/11/13
9190
北理工何际平团队:皮质内脑机接口的神经解码
挑战马斯克脑机接口!俄罗斯最强读心术,通过脑电波知道你在看什么
长久以来,“读心术”这种特异功能只在文学作品或影视作品中出现,比如说《X战警》中的X教授就具有这种超感知能力。
新智元
2019/11/27
7160
挑战马斯克脑机接口!俄罗斯最强读心术,通过脑电波知道你在看什么
Meta全新脑机接口模型,挑战Neuralink!无需植入芯片实现「心灵感应」
脑机接口一直是全球关注的新技术。尤其是有着马斯克光环加持下的Neuralink,更是备受瞩目。
新智元
2025/02/15
1200
Meta全新脑机接口模型,挑战Neuralink!无需植入芯片实现「心灵感应」
成功!马斯克官宣首个Neuralink脑机接口人类,意念操控鼠标,全民机器人时代来了?
就在刚刚,马斯克宣布,第一个植入Neuralink的人类患者,已经可以通过思考移动计算机鼠标了!
新智元
2024/02/26
1590
成功!马斯克官宣首个Neuralink脑机接口人类,意念操控鼠标,全民机器人时代来了?
Nature:研究人员设计稳定器来改善脑机接口
神经记录的不稳定性可导致临床脑机接口(BCI)失控。在这里,研究人员展示了低维神经流形(描述神经元之间特定关联模式的低维空间)的对齐可以用来稳定神经活动,从而在记录不稳定的情况下保持脑机接口的性能。研究人员在存在严重和突然的记录不稳定的情况下,通过皮层内BCIs在线控制光标时,以非人类灵长类对稳定剂进行了评估。稳定的BCIs在不同的不稳定条件下,经过多日恢复了有效的控制。稳定器不需要了解用户意图,并且可以超越监督的重新校准。即使在神经活动中几乎没有关于光标移动方向的信息,它也可以稳定BCI。该稳定器可应用于其他神经接口。
脑机接口社区
2020/06/30
5920
Nature:研究人员设计稳定器来改善脑机接口
元宇宙的终极脑机接口离我们还有多远
最近元宇宙的概念很火。行行业业的人要是不聊元宇宙,出门都不好意思跟人打招呼。有支持的也有骂的,反正很热闹。说来说去,元宇宙可以说是VR等各种“R”技术的最新马甲。这里R是英文Reality的缩写,意思是“真实”。但是现有技术提供的各种“真实”体验,总觉得差那么点意思。
脑机接口社区
2022/08/24
3210
元宇宙的终极脑机接口离我们还有多远
重要突破!西湖大学团队和浙二医院共同实现脑机接口中文解码
先进神经芯片中心默罕默德·萨万教授团队,自然语言处理实验室张岳教授团队和朱君明教授团队联合发布了他们最新的研究结果:“A high-performance brain-sentence communication designed for logosyllabic language”.该研究实现脑机接口全谱汉语解码,一定程度弥补了国际上汉语解码脑机接口技术的空白。
脑机接口社区
2023/11/18
6740
重要突破!西湖大学团队和浙二医院共同实现脑机接口中文解码
一种灵活,坚固且无凝胶的脑电图电极,可用于无创脑机接口
脑机接口(BCI)能够在大脑和电子设备之间实现直接和近乎即时的通信。目前最大的挑战之一是开发一种有效的无创BCI,它能使记录电极避免人类皮肤上的毛发,同时又不带来使用导电凝胶的不便和隐患。在这项研究中,清华大学研究人员开发了一种低成本、易于制造、柔韧、坚固且不含凝胶的脑电图(EEG)电极【银纳米线/聚乙烯醇缩丁醛(PVB)/三聚氰胺海绵(AgPMS)】,可以解决头发问题。由于银纳米线(AgNWs)表面金属化,海绵在重量不变的情况下导电率高达917 S/m。柔软的海绵框架和自锁式AgNW结合在一起,为新电极提供了非常好的机械稳定性(电导率在10%的压缩下循环10000次后保持不变)。基于稳态视觉诱发电位(SSVEP)在无毛皮肤上的BCI应用表明,新电极的BCI精度(86%)与导电凝胶支撑的传统电极(88%)大致相同。最重要的是,AgPMS在多毛皮肤上的性能并没有明显降低,这表明新电极可以替代传统电极用于无毛和多毛皮肤BCI及其他EEG应用。
脑机接口社区
2022/08/18
5860
一种灵活,坚固且无凝胶的脑电图电极,可用于无创脑机接口
推荐阅读
相关推荐
CMU贺斌教授团队提出:冥想可以增强对脑机接口的控制
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验