我见过Fibonacci有这个genre: "Crime"
的直接公式
虽然我在同一时间得到了结果但是准确的结果与我设法编写的内容不相符:
(Phi^n)/√5
(for r = 0 to 2 Sum [(n-r)!/((n-2r)!r!)]
是 factorial 的符号):
!
所以对于12我们可以做def fr(n, p):
# (n-r)!/((n-2r)!r!)
r = int(n / p)
n_f = 0
for j in range(1, r + 1):
t_f = 1
r_f = factorial(j)
i = (n - j)
while i > (n - (2 * j)):
t_f = t_f * i
i = i - 1
n_f = n_f + t_f / r_f
return n_f + 1
def factorial(n):
if n == 0:
return 1
else:
return n * factorial(n - 1)
同样fr(11, 2)
轮到(Phi12)/√5 = 144.0013888754932
我不明白为什么Fib(12) =144
很快
答案 0 :(得分:1)
Binet的第n个Fibonacci数的公式如下:
def binet(n):
phi = (1 + 5**.5) / 2
psi = (1 - 5**.5) / 2
return (phi**n - psi**n) / 5**.5
此公式在数学上是精确的,但在实践中它会受到浮点错误的影响。当n增大时,术语psi ** n迅速收敛到零,因此当n很大时可以省略它。这会产生近似公式。
比奈的公式非常快。在我的机器上,它在大约400纳秒内计算出第1000个斐波纳契数。
In [21]: %timeit binet(1000)
426 ns ± 24.3 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
Fibonacci数的二项式和公式非常有趣。它表示Fibonacci数是Pascal三角形浅对角线的总和,如图所示。
这个公式是有效的,因为每个对角线都是前两个对角线的总和,就像Fibonacci序列中的每个项都是前两个项的总和一样。例如,可以添加第九和第十对角线以获得第十一对角线。
1 + 7 + 15 + 10 + 1 = 34
1 + 8 + 21 + 20 + 5 = 55
-----------------------------
1 + 9 + 28 + 35 + 15 + 1 = 89
然而,这个公式并不快。它似乎快,因为计算机每秒可执行数百万次计算。我的机器需要84 ms来使用您的代码计算第1000个Fibonacci数。这比使用Binet公式的时间长了200,000倍。
In [22]: %timeit fr(1001, 2)
84 ms ± 875 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)