#Python中的这段非常简短的代码试图模拟前N个自然数的“Eratosthennes筛”,并限制(0)脚本长度;(1) 最小化“if语句”和“for/while循环”;(2) CPU时间方面的效率。
import numpy as np
N = 10**5
a = np.array(range(3,N,2))
for j in range(0, int(round(np.sqrt(N),0))):
a[(a!=a[j]) & (a%a[j] == 0)] = 0
a = a[a!=0]
a = [2]+list(a)
在Intel Core I5上,它返回第一个数字中的质数:
有人想在上述限制内分享更高效的CPU时间代码吗?
10.000.000为1.94秒
def sieve_eratosthene(limit):
primes = [True] * (limit+1)
iter = 0
while iter < limit**0.5 :
if iter < 2:
primes[iter]= False
elif primes[iter]:
for i in range(iter*2, limit+1, iter):
primes[i] = False
iter+=1
return(x for x in range(limit+1) if primes[x])
我决定玩这个,并创建了一个进一步优化的NumPy版本,由@user2357112发布,支持Monica,它使用Numba JIT来加快速度。
import numba
import numpy
import timeit
import datetime
@numba.jit(nopython = True, parallel = True, fastmath = True, forceobj = False)
def sieve (n: int) -> numpy.ndarray:
primes = numpy.full(n, True)
primes[0], primes[1] = False, False
for i in numba.prange(2, int(numpy.sqrt(n) + 1)):
if primes[i]:
primes[i*i::i] = False
return numpy.flatnonzero(primes)
if __name__ == "__main__":
timestart = timeit.default_timer()
print(sieve(1000000000))
timestop = timeit.default_timer()
timedelta = (timestop - timestart)
print(f"Time Elapsed: {datetime.timedelta(seconds = timedelta)}")
else:
pass
在我的笔记本电脑上,我筛选出0:00:10.378686秒内第一个10亿(1e9)自然数中的素数。JIT在这里提供了至少一个数量级的性能;在撰写本文时,下一个最快的答案需要0:01:27.059963分钟。遗憾的是,我在这个系统(苹果)上没有英伟达图形处理器和库达,否则我会用它。
一个实际的厄拉多塞数字筛看起来像这样:
def sieve(n):
flags = numpy.ones(n, dtype=bool)
flags[0] = flags[1] = False
for i in range(2, n):
# We could use a lower upper bound for this loop, but I don't want to bother with
# getting the rounding right on the sqrt handling.
if flags[i]:
flags[i*i::i] = False
return numpy.flatnonzero(flags)
它维护一个“可能素数”标志的数组,并直接取消设置对应于素数倍数的标志,而无需测试可除性,特别是对于当前正在处理的素数不可整除的数字。
我们所做的是试除法,在这里,我们只需要通过并测试数字是否可以被候选除数整除。即使是一个好的试除法实现也需要做更多的操作和更昂贵的操作,而不是筛子。你的实现做的工作甚至更多,因为它考虑了非质数候选除数,并且因为它一直在对它应该知道是质数的数字进行可整除性测试。
我正在尝试在Java中创建一个快速的素数生成器。人们(或多或少)认为,最快的方法是埃拉托斯特尼的分段筛:https://en.wikipedia.org/wiki/Sieve_of_Eratosthenes。可以进一步实施许多优化以使其更快。截至目前,我的实现在大约秒内生成低于的素数,但我希望让它更快,至少打破秒的障碍。为了增加获得良好回复的机会,我将包括算法和代码的演练。 尽管如此,作为 ,我希
null null 谢谢你的帮助!
问题内容: 我已经可以存储所有32位质数,并且 我想用它们来生成一些64位质数 。即使对逻辑和编译进行了优化,使用试验划分也太慢了。 我正在尝试修改Eratosthenes的筛网以使用预定义列表,如下所示: 在数组A中从2到4294967291 在数组B中从2 ^ 32到X inc减1 找到C,它是当前素数的第一个倍数。 从C标记开始并以当前素数跳至X。 转到1。 问题是使用模数查找素数的第3步,
问题内容: 我想为正在构建的数学应用程序找到质数,并遇到了Eratosthenes方法的Sieve。 我已经用Python编写了一个实现。但这太慢了。可以说,如果我想找到所有小于200万的素数。这需要> 20分钟。(我此时已停止)。我怎样才能加快速度? 更新: 我最终对这段代码进行了分析,发现花了很多时间从列表中删除一个元素。考虑到它必须遍历整个列表(最坏的情况)以找到元素,然后删除它,然后重新调
为了澄清,这与Eratosthenes的问题Sieve-Finding Primes Python不同,因为我不想在两个数字之间生成素数,但我想检查一个数字是否是素数。 我做了下面的代码来确定一个数字是否是素数。然后我听说了埃拉托色尼算法的筛子,它显然更快,但我不知道如何在下面的代码中编写它? 你们能帮帮我吗?
问题内容: 当我们必须处理10k量纲的向量时,python的外部乘积似乎很慢。有人可以告诉我如何在python中加快此操作的速度吗? 代码如下: 由于我必须多次执行此操作,因此我的代码越来越慢。 问题答案: 确实没有比这更快的速度,这些是您的选择: numpy.outer numpy.einsum 麻巴 Parakeet 赛顿 茶野 py 结论: