可能使用斐波纳契生成素数?

时间:2014-09-09 01:39:17

标签: python primes fibonacci

我从Fibonacci生成素数如下(使用Pythonmpmathsympy获得任意精度:

from mpmath import *

def GCD(a,b):
    while a:
        a, b = fmod(b, a), a
    return b

def generate(x):
    mp.dps = round(x, int(log10(x))*-1)
    if x == GCD(x, fibonacci(x-1)):
        return True
    if x == GCD(x, fibonacci(x+1)):
        return True

    return False

for x in range(1000, 2000)
    if generate(x)
        print(x)

它是一个相当小的算法,但似乎生成所有素数(除了5以某种方式,但这是另一个问题)。我说似乎是因为很少的百分比(1000%以下0.5%和10K以下0.16%,越来越少)并不是素数。例如,在1000:323下,还生成377和442。这些数字不是素数。

我的脚本中是否有其他内容?我尝试通过将.dps设置与正在计算的数字相关联来说明精确度。 斐波那契和素数似乎真的是如此相关,但是当它得到详细时它们就不是吗? :)

2 个答案:

答案 0 :(得分:2)

对于此类问题,您可能需要查看gmpy2库。 gmpy2提供对GMP多精度库的访问,该库包括gcd()和fib()函数,它们可以快速计算最大公约数和第n个斐波纳契数,并且只使用整数运算。

以下是您重新编写的程序以使用gmpy2

import gmpy2

def generate(x):
    if x == gmpy2.gcd(x, gmpy2.fib(x-1)):
        return True
    if x == gmpy2.gcd(x, gmpy2.fib(x+1)):
        return True
    return False

for x in range(7, 2000):
    if generate(x):
        print(x)

您不应该使用任何浮点运算。您只需使用内置%(模数)运算符即可计算GCD。

<强>更新

正如其他人评论的那样,您正在检查Fibonacci pseudoprimes。实际测试与您的代码略有不同。让我们调用正在测试的号码n。如果n可被5整除,那么如果n均分fib(n),则测试通过。如果n除以5会留下1或4的余数,那么如果n均分fib(n-1),则测试通过。如果n除以5会留下2或3的余数,那么如果n均分fib(n+1),则测试通过。您的代码没有正确区分这三种情况。

如果n均分另一个数字,比如x,则会留下0的余数。这相当于x % n为0.计算{{1}的所有数字斐波纳契数不是必需的。测试只关心其余部分。您可以计算每一步的余数,而不是将斐波纳契数计算为全精度。以下代码仅计算Fibonacci数的余数。它基于Python mpmath not arbitrary precision?

中@pts给出的代码
n-th

它是用纯Python编写的,非常快。

通常称为斐波那契数的数字序列只是一般卢卡斯序列def gcd(a,b): while b: a, b = b, a % b return a def fib_mod(n, m): if n < 0: raise ValueError def fib_rec(n): if n == 0: return 0, 1 else: a, b = fib_rec(n >> 1) c = a * ((b << 1) - a) d = b * b + a * a if n & 1: return d % m, (c + d) % m else: return c % m, d % m return fib_rec(n)[0] def is_fib_prp(n): if n % 5 == 0: return not fib_mod(n, n) elif n % 5 == 1 or n % 5 == 4: return not fib_mod(n-1, n) else: return not fib_mod(n+1, n) 的特例。通常的斐波那契数字由L(n) = p*L(n-1) - q*L(n-2)生成。 (p,q) = (1,-1)接受p,q的任意值。 gmpy2.is_fibonacci_prp()应与上面给出的gmpy2.is_fibonacci(1,-1,n)的结果相符。

免责声明:我维持gmpy2。

答案 1 :(得分:1)

这不是一个Python问题;这是一个数学/算法问题。您可能希望在Math StackExchange上询问它。

此外,无需任何非整数算术:您可以使用纯整数数学轻松完成计算floor(log10(x))。使用任意精度数学将大大减慢此算法的速度,并可能引入一些奇怪的数字错误。

这是一个简单的floor_log10(x)实施:

from __future__ import division # if using Python 2.x

def floor_log10(x):
  res = 0
  if x < 1:
    raise ValueError
  while x >= 1:
    x //= 10
    res += 1
  return res