Eratosthenes理解筛网

时间:2018-11-12 13:30:32

标签: python primes sieve

我有一段不太了解的代码,因为我一周前才开始学习Python。

import numpy as np
import time

start_time=time.clock()

def Sieb(n):                           #Sieve
    Eins = np.ones(n, dtype=bool)      #Eins is just german for One
    Eins[0] = Eins[1] = False          #->I don't quite understand what
    for i in range(2, n):              #this one does.
        if Eins[i]:
            Eins[i*i::i] = False       #Does this make the ones = zero?
    return np.flatnonzero(Eins)


print Sieb(1000000)
print start_time

所以,我了解筛子的概念(我想),但是我不确定在这里如何实现。 自身的倍数在哪里0np.flatnonzero如何得出质数,因为在此之前它们分别是10

希望您能理解并帮助我。 :)

1 个答案:

答案 0 :(得分:2)

让我们逐步进行。

Eins = np.ones(n, dtype=bool)

这将创建一个大小为 n 的新数组,类型为bool,并且全为1。由于类型的原因,“一个”表示True。该数组表示我们要测试其素数的所有数字,其中True表示该数字是质数,False表示不是。因此,我们从标记为(潜在)素数的所有数字开始。

Eins[0] = Eins[1] = False

现在我们将第0和第1个元素设置为False:0和1都不是素数。

for i in range(2, n):

接下来,我们将迭代所有剩余的数字(从2开始)。我们只需要上到 n 的平方根就可以逃脱,但是为了简单起见,我们遍历了所有数字。

    if Eins[i]:

如果数组的第i个值为True,则意味着i是质数。第一次输入此条件是使用i=2。接下来,我们要从主要候选人中删除所有数字的倍数:

        Eins[i*i::i] = False

Eins[2*i::i] = False开始,我们可以将这行读为i*i,这只是一个优化¹。如果2是质数,则表示2 * 2、3 * 2、4 * 2 ...不是,因此我们将倍数设置为False。索引符号表示“从i*i到结尾”(由冒号之间的空白表示)“,以i的步长”。该语句产生数字i*ii*(i+1)i*(i+2),...,因此i的所有倍数尚未标记为“不是质数”。

return np.flatnonzero(Eins)

这只是返回所有值为True的索引,即找到的所有素数。


1:关于i*i的一句话:我们可以从i的平方开始,因为任何数字j*i(对于j < i)已经被标记为非质数当我们在j时。


这是一个对n=15有效的演示:

我们从填充.ones的数组开始:

 0  1  2  3  4  5  6  7  8  9 10 11 12 13 14
[T, T, T, T, T, T, T, T, T, T, T, T, T, T, T]

然后我们清空Eins[0]Eins[1]

 0  1  2  3  4  5  6  7  8  9 10 11 12 13 14
[F, F, T, T, T, T, T, T, T, T, T, T, T, T, T]

现在我们从i=2开始遍历整个范围,并从2*2=4开始删除2的每一个倍数:

 0  1  2  3  4  5  6  7  8  9 10 11 12 13 14
[F, F, T, T, F, T, F, T, F, T, F, T, F, T, F]

i=3,从3*3=9开始删除3的倍数:

 0  1  2  3  4  5  6  7  8  9 10 11 12 13 14
[F, F, T, T, F, T, F, T, F, F, F, T, F, T, F]

请注意,我们不必删除6,因为i=2已经删除了它。

i=4时,由于Eins[i]False,因此我们跳过了删除操作。从i=5开始,什么都没有发生,因为正方形(25,36,...)比数组大。最后,我们使用flatnonzero并获取所有值为True的索引:

 0  1  2  3  4  5  6  7  8  9 10 11 12 13 14
[F, F, T, T, F, T, F, T, F, F, F, T, F, T, F]
       2  3     5     7          11    13