[英]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
在哪里
Phi=(1+√5)/2= and -Phi=(1-√5)/2
(1+√5)/2
也称为黄金比例。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_cache
的memoization
概念发布的答案的另一种方法是:
装饰器用记忆调用来包装函数,最多保存最近调用的 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.