为什么我的阿特金筛法实施忽略了接近指定限制的数字?
我的阿特金筛法的实现要么忽略了极限附近的素数,要么忽略了极限附近的合成。有些限制有效,有些则无效。我完全不知道出了什么问题。
def AtkinSieve (limit):
results = [2,3,5]
sieve = [False]*limit
factor = int(math.sqrt(lim))
for i in range(1,factor):
for j in range(1, factor):
n = 4*i**2+j**2
if (n <= lim) and (n % 12 == 1 or n % 12 == 5):
sieve[n] = not sieve[n]
n = 3*i**2+j**2
if (n <= lim) and (n % 12 == 7):
sieve[n] = not sieve[n]
if i>j:
n = 3*i**2-j**2
if (n <= lim) and (n % 12 == 11):
sieve[n] = not sieve[n]
for index in range(5,factor):
if sieve[index]:
for jndex in range(index**2, limit, index**2):
sieve[jndex] = False
for index in range(7,limit):
if sieve[index]:
results.append(index)
return results
例如,当我生成极限为 1000 的素数时,阿特金筛会错过素数 997,但包含合数 965。但是,如果我生成极限为 5000 的素数,则它返回的列表是完全正确的。
My implementation of Sieve of Atkin either overlooks primes near the limit or composites near the limit. while some limits work and others don't. I'm am completely confused as to what is wrong.
def AtkinSieve (limit):
results = [2,3,5]
sieve = [False]*limit
factor = int(math.sqrt(lim))
for i in range(1,factor):
for j in range(1, factor):
n = 4*i**2+j**2
if (n <= lim) and (n % 12 == 1 or n % 12 == 5):
sieve[n] = not sieve[n]
n = 3*i**2+j**2
if (n <= lim) and (n % 12 == 7):
sieve[n] = not sieve[n]
if i>j:
n = 3*i**2-j**2
if (n <= lim) and (n % 12 == 11):
sieve[n] = not sieve[n]
for index in range(5,factor):
if sieve[index]:
for jndex in range(index**2, limit, index**2):
sieve[jndex] = False
for index in range(7,limit):
if sieve[index]:
results.append(index)
return results
For example, when I generate a primes to the limit of 1000, the Atkin sieve misses the prime 997, but includes the composite 965. But if I generate up the limit of 5000, the list it returns is completely correct.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
lim
更改为limit
。当然你一定知道这一点。sieve = [False]*limit
,允许的最大索引为
limit-1
。但是,在这一行
您正在检查是否
n<=limit
。如果n==limit
则sieve[n]
引发 IndexError。使用较小的
limit
值(例如 n=50)尝试您的算法。你会看到这个错误出现。一个简单的解决方法是使用
这个简单的修复有点浪费,因为 sieve[0] 从未被使用过。因此,您可能认为更好的修复方法是保留 sieve = [False]*limit,但通过将 sieve 上的索引递减 1 来修复所有其他代码。 (例如,将
sieve[n]
更改为sieve[n-1]
等)但是,这将迫使您进行一些额外的减法,而这不会有利于速度。因此,简单/浪费的解决方案实际上可能是更好的选择。x 应该是 [1,sqrt(limit)] 中的整数,包括端点。
在你的代码中
和
int
取math.sqrt(limit)
的下限。此外,range(1,factor)
从 1 到 Factor-1。所以你落后了 1。所以你需要将其更改为
lim
tolimit
. Of course you must have known that.Since
sieve = [False]*limit
,the largest index allowed is
limit-1
.However, on this line
you are checking if
n<=limit
. Ifn==limit
thensieve[n]
raises an IndexError.Try your algorithm with a small value of
limit
(e.g. n=50). You'll see this error come up.An easy fix is to use
The easy fix is a bit wasteful since sieve[0] is never used. So you might think a better fix is to keep
sieve = [False]*limit
, but fix all your other code by stepping the index onsieve
down by one. (E.g., changesieve[n]
tosieve[n-1]
everywhere, etc.) However, this will force you to do a number of extra subtractions which will not be good for speed. So the easy/wasteful solution is actually probably the better option.x should be an integer in [1,sqrt(limit)], inclusive of the endpoints.
In your code
and
int
takes the floor ofmath.sqrt(limit)
. Furthermore,range(1,factor)
goes from 1 to factor-1. So you are off by 1.So you need to change this to