为什么我的阿特金筛法实施忽略了接近指定限制的数字?

发布于 2024-08-24 04:54:46 字数 1011 浏览 7 评论 0原文

我的阿特金筛法的实现要么忽略了极限附近的素数,要么忽略了极限附近的合成。有些限制有效,有些则无效。我完全不知道出了什么问题。

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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

新人笑 2024-08-31 04:54:46
  • lim 更改为 limit。当然你一定知道这一点。
  • 由于sieve = [False]*limit
    允许的最大索引为 limit-1

    但是,在这一行

    if (n <= limit) and (n % 12 == 1 or n % 12 == 5):
    

    您正在检查是否n<=limit。如果 n==limitsieve[n] 引发 IndexError。
    使用较小的 limit 值(例如 n=50)尝试您的算法。你会看到这个错误出现。
    一个简单的解决方法是使用

    筛子 = [False]*(limit+1)
    

    这个简单的修复有点浪费,因为 sieve[0] 从未被使用过。因此,您可能认为更好的修复方法是保留 sieve = [False]*limit,但通过将 sieve 上的索引递减 1 来修复所有其他代码。 (例如,将 sieve[n] 更改为 sieve[n-1] 等)但是,这将迫使您进行一些额外的减法,而这不会有利于速度。因此,简单/浪费的解决方案实际上可能是更好的选择。

  • 根据http://en.wikipedia.org/wiki/Sieve_of_Atkin
    x 应该是 [1,sqrt(limit)] 中的整数,包括端点。

    在你的代码中

    factor = int(math.sqrt(limit))
    

    intmath.sqrt(limit)下限。此外,

    range(1,factor) 从 1 到 Factor-1。所以你落后了 1。

    所以你需要将其更改为

    factor = int(math.sqrt(limit))+1
    

  • 请参阅列出下面所有素数的最快方法N 用于阿特金筛法的替代(且更快)实现,由 Steve Krenzel 提出。
def AtkinSieve (limit):
    results = [2,3,5]
    sieve = [False]*(limit+1)
    factor = int(math.sqrt(limit))+1
    for i in range(1,factor):
        for j in range(1, factor):
            n = 4*i**2+j**2
            if (n <= limit) and (n % 12 == 1 or n % 12 == 5):
                sieve[n] = not sieve[n]
            n = 3*i**2+j**2
            if (n <= limit) and (n % 12 == 7):
                sieve[n] = not sieve[n]
            if i>j:
                n = 3*i**2-j**2
                if (n <= limit) 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


  • Change lim to limit. Of course you must have known that.

  • Since sieve = [False]*limit,
    the largest index allowed is limit-1.

    However, on this line

    if (n <= limit) and (n % 12 == 1 or n % 12 == 5):
    

    you are checking if n<=limit. If n==limit then sieve[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

    sieve = [False]*(limit+1)
    

    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 on sieve down by one. (E.g., change sieve[n] to sieve[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.

  • According to http://en.wikipedia.org/wiki/Sieve_of_Atkin,
    x should be an integer in [1,sqrt(limit)], inclusive of the endpoints.

    In your code

    factor = int(math.sqrt(limit))
    

    and int takes the floor of math.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

    factor = int(math.sqrt(limit))+1
    

  • See Fastest way to list all primes below N for an alternative (and faster) implementation of the Sieve of Atkin, due to Steve Krenzel.

def AtkinSieve (limit):
    results = [2,3,5]
    sieve = [False]*(limit+1)
    factor = int(math.sqrt(limit))+1
    for i in range(1,factor):
        for j in range(1, factor):
            n = 4*i**2+j**2
            if (n <= limit) and (n % 12 == 1 or n % 12 == 5):
                sieve[n] = not sieve[n]
            n = 3*i**2+j**2
            if (n <= limit) and (n % 12 == 7):
                sieve[n] = not sieve[n]
            if i>j:
                n = 3*i**2-j**2
                if (n <= limit) 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
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文