【问题标题】:Prime number generation using Fibonacci possible?可以使用斐波那契生成素数吗?
【发布时间】:2014-09-09 01:39:17
【问题描述】:

我从斐波那契生成素数如下(使用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 设置与正在计算的数字相关联来考虑精度。 真的是斐波那契数和素数看起来如此相关,但是当它变得详细时,它们不是吗? :)

【问题讨论】:

标签: python primes fibonacci


【解决方案1】:

对于此类问题,您可能需要查看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。

更新

正如其他人评论的那样,您正在检查斐波那契伪素数。实际测试与您的代码略有不同。让我们拨打正在测试的号码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。不需要计算n-th 斐波那契数的所有数字。测试只关心其余部分。您可以在每一步计算余数,而不是完全精确地计算斐波那契数。以下代码仅计算斐波那契数的余数。它基于@pts在Python mpmath not arbitrary precision?中给出的代码

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)

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

通常称为斐波那契数列的数字序列只是一般卢卡斯序列L(n) = p*L(n-1) - q*L(n-2) 的一个特例。通常的斐波那契数由(p,q) = (1,-1) 生成。 gmpy2.is_fibonacci_prp() 接受 p,q 的任意值。 gmpy2.is_fibonacci(1,-1,n) 应该与上面给出的is_fib_pr(n) 的结果相匹配。

免责声明:我维护 gmpy2。

【讨论】:

  • 我真的很想使用它,但是由于构建错误(找不到 vcvarsall.bat),我在安装时遇到了问题。我知道这与我的 VS90COMNTOOLS 变量有关,但修复似乎没有帮助。无论如何,我真的很想知道它有多快!
  • 由于您使用的是Windows,您应该只使用预编译版本:pypi.python.org/pypi/gmpy2/2.0.3 如果您使用pip 安装,它将尝试编译所有C 代码,这并不容易。
  • 我已经下载了。但是安装预编译版本,它是如何工作的?我似乎找不到 setup.py 命令的简单标志。或者我应该只是将文件复制粘贴到我的 Python 安装目录中?
  • 它是一个可执行文件。只需像任何应用程序安装程序一样运行它,它就应该安装。如果您使用的 Python 版本不是来自 python.org 的版本,则安装可能会失败。如果是这样,请参阅stackoverflow.com/questions/16171658/…
  • 我下载了 zip 文件。我要试试这个exe。
【解决方案2】:

这不是真正的 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

【讨论】:

  • 我只使用 log10 计算来计算斐波那契计算所需的精度!
  • 为什么纯整数算法需要任何浮点精度? (您没有详细描述算法,但我假设您在谈论计算标准斐波那契数列?)
  • 因为我需要计算斐波那契的Nth位置。这包括sqrt
  • 很公平。我确实被指出了我不知道的伪素数概念。我要看看casevh的图书馆,看看我能从哪里得到:)。
  • gmpy2 确实包含一个 is_fibonacci_prp() 函数,但使用它可能是作弊。 ;-)
猜你喜欢
  • 2011-12-18
  • 2015-04-25
  • 2017-11-13
  • 2013-02-24
  • 1970-01-01
  • 2011-04-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多