【问题标题】:Trial Division faster than Sieve for Primality Test?初等性检验比筛法快?
【发布时间】:2015-08-20 17:16:15
【问题描述】:

我用 python 写了两个素数测试。第一个是基于试验划分,第二个是埃拉托色尼筛。我的理解是 sieve 的时间复杂度应该比 Trial 小,所以 sieve 应该渐近更快。

但是当我运行它时,试用分区要快得多。例如,当n = 6*(10**11)is_prime(n) 用时不到一秒,但is_prime_sieve(n) 实际上永远不会结束!我是不是把筛子写错了?

我的代码是:

# determines if prime using trial division
def is_prime(n):
    d = {}
    u = math.floor(math.sqrt(n))
    i = 2
    # trial division: works pretty well for determining 600 billion
    while (i <= u):
        if (n % i == 0):
            return False
        i += 1
    return True

# primality test with sieve
def is_prime_sieve(n):
    # first find all prime numbers from 2 to u
    # then test them
    u = math.floor(math.sqrt(n))
    prime = {}
    lst = range(2, int(u)+1)
    for i in lst:
        j = 2
        prime[i] = True
        while (i*j <= u):
            prime[i*j] = False
            j += 1
    while (u >= 2):
        if (u not in prime) or (prime[u]):
            if (n % u == 0):
                return False
        u -= 1
    return True

【问题讨论】:

  • FWIW:return all(n % i for i in range(2, int(n**0.5)+1)).

标签: python primality-test


【解决方案1】:

对于 Erastothenes 筛子,您每次都在重新计算筛子。筛子应该被缓存,以便您只生成一次。当您构建一次筛子然后执行 许多 素性检查时,它会很好地工作;如果只检查一个数字,效率非常低。

顺便说一句,这意味着您需要预测最高质数并生成直到该数的筛表。

如果操作正确,is_prime_sieve 会变得简单:

def is_prime_sieve(n):
    return prime[n]

您不需要while 循环。

【讨论】:

  • 我认为这是有道理的。所以试用分割毕竟更快,没有缓存。筛子..
  • 他们做了两件不同的事情:筛子生成一个范围内的所有个素数,试除法确定单个数字是否为素数。考虑 filter(is_prime, range(N))sieve(N) 生成从 1 到 N 的所有素数的运行时间。
  • “试除法”在筛子使用得当的情况下并不比筛子快。但是,对于非常大的奇异素性测试,您提出的试验部门的变体确实存在。此变体仅涉及除以已被证明与特定范围相关的数字。
【解决方案2】:

筛子找到从 1 到 n 的 所有 个素数。计算 一个 筛子比对每个数字进行试除法要快得多。显然,如果你确定 所有 个从 1 到 n 的素数,然后丢弃前 n-1 个数字的所有信息,这是非常低效的。

这就像比较公共汽车和两座跑车的速度。如果你需要从 A 到 B 带 50 个人,公共汽车要快得多。如果你只带一个乘客,猜猜看,跑车更快。

【讨论】:

    【解决方案3】:

    但即使使用传统的筛子构建方法,仍会发生太多事务。 我开发了一种无需除法即可提取素数的方法(除了数据管理目的),它适用于 Eratosthenes 的基本筛法。我不必设置任何上限或下限,算法是完全开放式的。我开发了一个数据字符串,我可以从中找到计算范围内的任何位置,并提取子集范围内的所有素数。我不浪费除法计算。

    【讨论】:

    • 这没有回答问题。你只是在谈论你的代码而不显示它。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-30
    • 1970-01-01
    • 2018-12-30
    相关资源
    最近更新 更多