Eratosthenes的筛子遗漏了一些复合材料

时间:2017-05-11 11:18:20

标签: python python-3.x sieve-of-eratosthenes

编辑:好的,所以代码现在正在运行......任何人都可以解释为什么将Floor(1000/index)更改为floor(999/index) + 1有帮助吗?

我对Eratosthenes筛选的实施将一些复合材料列为列表末尾的素数。也就是说,如果我找到1000个素数,那么980和1000之间的一些素数也包括在内

from math import floor

prime_list = []
list_primes2 = [True for x in range(1000)]
list_primes2[0], list_primes2[1] = False, False

for index, value in enumerate(list_primes2):
    if value:
        for x in range(floor(999/index)+1):
            list_primes2[index*x] = False

        prime_list.append(index)

print(prime_list)

以上代码导致所有素数高达1000加989和999

989的Prime因子是23和43,它们都列在prime_list

999的Prime因子是3和37,它们都列在prime_list

2 个答案:

答案 0 :(得分:2)

考虑何时index = 3。此处,floor(1000/index) = 333range(333)生成0到332之间的值。因此,list_primes2[999]不会设置为False

另一方面,floor(999/index) + 1 = 334range(334)生成0到333之间的值。

通常,此语句的结构应为floor(max/index) + 1。请注意,语句ceil(max/index)不等同。通过上面的示例可以很容易地看到这一点,其中ceil(max/index)将仅再次生成0到332之间的值。

答案 1 :(得分:1)

我尝试弄乱1000数字以查看它是否会表现出相同的行为,因为您只看到接近限制的错误输出,并且看起来错误的非素数保留在附近的列表中限制(无论你在哪里设置它,我都试过2000年)。

简答:问题似乎在于,由于range(float(1000/index))元素的运作方式,您正在削减接近上限的某些值。它没有迭代它们,也没有从你的素数列表中取出它们。

如果你在该范围内加1,那就是它会迭代所需的所有数字,但你必须减少1000到999才能使产品不会上升到1000以上(即x in range(floor(1000/index)+1) )。否则该产品> 999并且指的是超出您设置的原始范围的列表索引:list_primes2 = [True for x in range(1000)]

更长的答案/我如何到达那里: 你的第一个range(1000)是0,1000。 你的第二个是range(floor(1000/index)),即0,1 我认为必须因此,正如我所理解的那样,floor()会给你小于或等于x的最大整数值。对于range(floor(1000/index)),范围将是永远不会超过一个,因为它会浮动(1000/999)给出范围0,1。 现在,如果您使用`range(floor((999 / index)+1),则以范围0,2结束。

现在进行试验,看来如果你做range(n)range(floor((n-1/index)+1)就行了。

我为每次迭代打印出x,index,product x * index范围:对于你使用的第一组参数,它只循环到x = 23,index = 42,所以它永远不会返回989,同样的999,它永远不会循环通过任何等于999的索引和x的组合。当你将范围增加1时,它会达到所有这些迭代。您必须减少1000到999才能使产品不会上升到1000以上(即x in range(floor(1000/index)+1))并引用超出您设置的原始范围的列表索引:list_primes2 = [True for x in range(1000)]

from math import floor
prime_list = []
list_primes2 = [True for x in range(1000)]
list_primes2[0], list_primes2[1] = False, False
for index, value in enumerate(list_primes2):
    if value:
        for x in range(floor(1000/index)):
            print (x)
            print (index)
            print (x*index)
            print (range(floor(1000/index)))
for index, value in enumerate(list_primes2):
    if value:
        for x in range(floor(1000/index)):
            list_primes2[index*x] = False
        prime_list.append(index)
print(prime_list)


prime_list = []
list_primes2 = [True for x in range(1000)]
list_primes2[0], list_primes2[1] = False, False
for index, value in enumerate(list_primes2):
    if value:
        for x in range(floor(999/index)+1):
            print (x)
            print (index)
            print (x*index)
            print(range(floor(999/index)+1))

for index, value in enumerate(list_primes2):
    if value:
        for x in range(floor(999/index)+1):
            list_primes2[index*x] = False
        prime_list.append(index)
print(prime_list)

此外: 我想你可能会误解Sieve的工作方式,或者范围是如何工作的。使用筛子,你可以更少次地迭代一次,尤其是当你向上移动时,它的一部分就是它的用处:你标记每个素数的倍数,所以你需要既不对每个数字进行详尽的测试,也不能找到它的复合性或最优性。你只需消除每个连续素数的倍数2 *(1 ... n),3 *(1 ... n),[4已经是elim],5 *(1 ... n)直到你到达n

我们会去20,所以它更清楚。只有倍数在"

上重复
So  
x-[Eliminating]               [All Eliminated]                
2-[4,6,8,10,12,14,16,18,20]   [4,6,8,10,12,14,16,18,20]
3-[6,9,15]                    [4,6,8,9,10,12,14,15,16,18,20]
5-No more multiples <20       [4,5,6,8,9,10,12,14,15,16,18,20]          
7-No more multiples <20       [4,5,6,8,9,10,12,14,15,16,18,20]
11-No more multiples <20      [4,5,6,8,9,10,12,14,15,16,18,20]
13-No more multiples <20      [4,5,6,8,9,10,12,14,15,16,18,20]
17-No more multiples <20      [4,5,6,8,9,10,12,14,15,16,18,20]
19-No more multiples <20      [4,5,6,8,9,10,12,14,15,16,18,20]

所以我们可以看到0-10是4步,远远低于你的功能运行。

我们可以像我之前的答案一样进行测试,即使我们将限制设置为低至10,也有13次迭代 - 超过数字。

from math import floor
prime_list = []
iterations=0
list_primes2 = [True for x in range(10)]
list_primes2[0], list_primes2[1] = False, False
for index, value in enumerate(list_primes2):
    if value:
        for x in range(floor(9/index)+1):
            iterations+=1
            print ("Iterations:",iterations)
            list_primes2[index*x] = False
            print ("X:         ",x)
            print ("index:     ",index)
            print ("x*index:   ",x*index)
            print(range(floor(9/index)+1))
            print("Numbers now in list of primes: ",prime_list)
            print()
        prime_list.append(index)

print("List of primes: ",prime_list)