斐波那契算法分析

时间:2012-09-12 13:01:26

标签: algorithm

我正在阅读对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);
}

6 个答案:

答案 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次。