繁体   English   中英

斐波那契特定数字生成器python

[英]fibonacci specific number generator python

有没有办法显示第 N斐波那契数? 例如,我想要第 15斐波那契数,但这仅给出了一个列表。

a = int(input('Enter N Number: '))

def fib(n):
    a = b = 1
    for i in range(n):
        yield a
        a, b = b, a + b

print(fib(a))

一种天真的方法是生成所有n Fibonacci 数并返回花费O(n)时间的最后一个元素。 可以在计算N Fibonacci数O(1)假设math.pow花费O(1)使用的时间) 比奈的公式。

比奈公式:

Fib(n) =(Phin − (−Phi)−n)/√5

在哪里

import math
def fib(n):
    phi=1.61803398874989484820
    return round(((math.pow(phi,n))-(math.pow(-(1-phi),n)))/math.sqrt(5))

fib(15)
# 610
fib(10)
# 55

数学证明和计算器在这里。

fib()的结果转换为列表并将其索引为-1

print(list(fib(a))[-1])

>> Enter N Number: 15
>> [610]

您可以使用带记忆的递归计算第 N 个斐波那契数

为什么?

例如:假设您要计算fibonacci(5)因此您需要计算fibonacci(4)fibonacci(3) 但是现在,对于fibonacci(4)您需要计算fibonacci(3)fibonacci(2) ,依此类推。 但是等等,当您完成计算fibonacci(4)分支时,您已经计算了 3 和 2 的所有 fibonacci,所以当您从第一次递归调用返回另一个分支 ( fibonacci(3) ) 时,您已经计算了它。 那么,如果有一种方法可以存储这些计算以便我可以更快地访问它们呢? 你可以用做装饰,以营造一个memoize的类(某种内存中,避免重复计算):

通过这种方式,我们将把fibonacci(k)每个计算存储在一个dict ,我们将在每次调用之前检查它是否存在于字典中,如果为True返回,否则计算它。 这种方式更快更准确。

class memoize:
    def __init__(self, function):
        self.f = function
        self.memory = {}

    def __call__(self, *args):
        if args in self.memory:
            return self.memory[args]
        else:
            value = self.f(*args)
            self.memory[args] = value
            return value

@memoize
def fib(n):
  if n <= 1:
    return n
  else:
    return fib(n-1) + fib(n-2)

r = fib(300)
print(r)

输出:

222232244629420445529739893461909967206666939096499764990979600

只用了0.2716239秒。

@DarK_FirefoX 使用内置函数lru_cachememoization概念发布的答案的另一种方法是:

装饰器用记忆调用来包装函数,最多保存最近调用的 maxsize。 当使用相同的参数定期调用昂贵的或 I/O 绑定的函数时,它可以节省时间。

from functools import lru_cache 


@lru_cache() 
def fib(n): 
    if n <= 1: 
        return n 
    return fib(n-1) + fib(n-2)

print(fib(300))
# 222232244629420445529739893461909967206666939096499764990979600

奖金:

$> %timeit fib(300)                                                        
78.2 ns ± 0.453 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)

正如评论中所建议的,您的程序可用于通过取序列中的最后一个来生成第 N 个数字,即

list(fib(n))[-1]

然而,有更有效的程序来生成第 N 个斐波那契数,正如这里所讨论的

一个这样的例子是来自这个来源的第 6 个程序,即:

# Python 3 Program to find n'th fibonacci Number in 
# with O(Log n) arithmatic operations 
MAX = 1000

# Create an array for memoization 
f = [0] * MAX

# Returns n'th fuibonacci number using table f[] 
def fib(n) : 
    # Base cases 
    if (n == 0) : 
        return 0
    if (n == 1 or n == 2) : 
        f[n] = 1
        return (f[n]) 

    # If fib(n) is already computed 
    if (f[n]) : 
        return f[n] 

    if( n & 1) : 
        k = (n + 1) // 2
    else :  
        k = n // 2

    # Applyting above formula [Note value n&1 is 1 
    # if n is odd, else 0. 
    if((n & 1) ) : 
        f[n] = (fib(k) * fib(k) + fib(k-1) * fib(k-1)) 
    else : 
        f[n] = (2*fib(k-1) + fib(k))*fib(k) 

    return f[n] 


# Driver code 
n = 9
print(fib(n)

输出

34

优于 Posted Code

这种方法的优点是第 n 个斐波那契数的复杂度为O(log(n)) ,而问题中发布的代码的复杂度为 O(n)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM