我正在阅读对fibanocci数字程序的分析,如下所示。提到这种实现效率低下。实际上,计算Fn的递归调用的数量是F(n + 1)。
我的问题是:“计算Fn的递归调用的数量是F(n + 1)”是什么意思?
int F(int i)
{
if (i < 1) return 0;
if (i == 1) return 1;
return F(i-1) + F(i-2);
}
答案 0 :(得分:4)
计算斐波纳契数的天真实现需要F(n + 1)个递归调用来计算数字F(n);即要计算f(10)= 55,你需要89个递归调用,89个是F(11)。
答案 1 :(得分:3)
如果我们想要计算Nth Fibonacci数F(n)= F(n-1)+ F(n-2)。我们可以用迭代方法和递归方法来做。如果我们用迭代方法做到这一点
#include<stdio.h>
main()
{
int a=0,b=1,c,i,n;
//clrscr();
printf("enter the limit of series\n");
scanf("%d",&n);
if(n==0)
printf("%d\n",a);
else
printf("%d\n%d\n",a,b);
for(i=2;i<=n;i++)
{
c=a+b;
printf("%d\n",c);
a=b;
b=c;
}
}
从i = 0到N迭代需要O(n)时间。
但是使用递归方法
int F(int i)
{
if (i < 1) return 0;
if (i == 1) return 1;
return F(i-1) + F(i-2);
}
重现关系是
___________ 0 if(n<=0)
/___________ 1 if(n==1)
Fibonacci(n) ____/
\
\___________ Fibonacci(n-1)+Fibonacci(n-2)
所以我们的问题是n =(n-1)的子问题+(n-2)的子问题因此我们的时间函数T(n)如下
T(n)=T(n-1)+T(n-2)+O(1)
T(n)={T(N-2)+T(n-3)}+T(n-2) since T(n-1)=T(n-2)+T(n-3) -------- equation(1)
from above you can see T(n-2) is calculated twice. If we expand the recursion tree for N=5 . The recursion tree is as follows
Fib(5)
|
_____________________/ \__________________
| |
Fib(4) + fib(3)
| |
_______/ \_______ ________/ \_______
| + | | + |
Fib(3) Fib(2) Fib(2) Fib(1)
| | |
_______/ \____ ____/ \_______ _______/ \_____
| + | | + | | + |
Fib(2) Fib(1) Fib(1) Fib(0) Fib(1) Fib(0)
_______/ \_______
| + |
Fib(1) Fib(0)
如果我们观察到复发树,我们发现Fib(1)被细胞化5次 将Fib(2)细胞化3次 将Fib(3)细胞2次
因此,使用递归我们实际上正在进行冗余计算。如果使用迭代方法,则可以避免这些还原剂计算。
T(N)= T(N-1)+ T(N-2)1
来自之前的SO Computational complexity of Fibonacci Sequence
程序的复杂性近似等于bigoh(2power(n))。 因为O(n)&lt; O(2powerN)递归方法效率不高。
答案 2 :(得分:2)
“程序的复杂性大约等于bigoh(2power(n))。 因为O(n)&lt; O(2powerN)递归方法效率不高。 “
如果他们根据所需的递归调用量来计算这种复杂性,那么我不知道他们在哪里得到2 ^ n。该图表根本不模拟2 ^ n,对于较大的值,建模显着衰减。到了第32个术语832,040,需要2,692,536个递归调用来计算它,远远小于2 ^ 30,超过10亿。它不到1%!
答案 3 :(得分:0)
这意味着要计算10个数字的Fibonacci数,您需要运行递归10 + 1次才能获得它。有各种算法可以改善这个时间表。
请看这篇文章,它解释了发现斐波那契数字及其改进的时间复杂性:Computational complexity of Fibonacci Sequence
答案 4 :(得分:0)
这是我对斐波纳契的算法
#include<stdio.h>
main()
{
// If we walk backwards in the fibonacci series, the values before
// zero will be 1 and -1. i.e the series can be re imagined as
// -1, 1, 0, 1, 1, 2, 3.
// This will spare us from adding special handling for first
// and second element of the series
int a=-1,b=1,c,i,n;
printf("enter the limit of series\n");
scanf("%d",&n);
printf("The series is : ");
for(i=1;i<=n;i++)
{
c=a+b;
printf("%d\n",c);
// move a and b forward
a=b;
b=c;
}
}
答案 5 :(得分:0)
这是斐波纳契的一些改进版本,我们只计算一次数字的斐波纳契:
dicFib = { 0:0 ,1 :1 }
iterations = 0
def fibonacci(a):
if (a in dicFib):
return dicFib[a]
else :
global iterations
fib = fibonacci(a-2)+fibonacci(a-1)
dicFib[a] = fib
iterations += 1
return fib
print ("fibonacci of 10 is:" , fibonacci(10))
print ("fibonacci of all numbers:" ,dicFib)
print ("iterations:" ,iterations)
# ('fibonacci of 10 is:', 55)
# ('fibonacci of all numbers:', {0: 0, 1: 1, 2: 1, 3: 2, 4: 3, 5: 5, 6: 8, 7: 13, 8: 21, 9: 34, 10: 55})
# ('iterations:', 9)
这里我们将每个数字的fibonnaci存储在字典中。所以你可以看到它只为每次迭代计算一次,对于斐波那契(10)它只计算9次。