当前位置:  开发笔记 > 人工智能 > 正文

Fibonacci序列的计算复杂性

如何解决《Fibonacci序列的计算复杂性》经验,为你挑选了8个好方法。

我理解Big-O表示法,但我不知道如何为许多函数计算它.特别是,我一直试图弄清楚Fibonacci序列的幼稚版本的计算复杂性:

int Fibonacci(int n)
{
    if (n <= 1)
        return n;
    else
        return Fibonacci(n - 1) + Fibonacci(n - 2);
}

Fibonacci序列的计算复杂度是多少以及如何计算?



1> Mehrdad Afsh..:

您将时间函数建模为计算Fib(n)时间总和Fib(n-1)加上计算Fib(n-2)时间加上将它们加在一起的时间(O(1)).这是假设对它的重复评估Fib(n)需要相同的时间 - 即不使用任何记忆.

T(n<=1) = O(1)

T(n) = T(n-1) + T(n-2) + O(1)

你解决了这种递归关系(例如使用生成函数),你最终会得到答案.

或者,您可以绘制递归树,它将具有深度n并直观地确定此函数是渐近的.然后,您可以通过归纳证明您的猜想.O(2n)

基地:n = 1很明显

假设,因此T(n-1) = O(2n-1)

T(n) = T(n-1) + T(n-2) + O(1) 等于

T(n) = O(2n-1) + O(2n-2) + O(1) = O(2n)

但是,如评论中所述,这不是紧张的约束.关于这个函数的一个有趣的事实是T(n)渐近地与相同,Fib(n)因为两者都被定义为

f(n) = f(n-1) + f(n-2).

递归树的叶子将始终返回1.值Fib(n)是递归树中叶子返回的所有值的总和,它等于叶子的数量.由于每个叶子将采用O(1)来计算,T(n)等于Fib(n) x O(1).因此,该函数的紧束缚是Fibonacci序列本身(〜).你可以通过使用我上面提到的生成函数找出这个紧密的界限.?(1.6n)





也通过归纳证明.尼斯.+1

2> Jason Cohen..:

只要问问自己需要执行多少语句F(n)才能完成.

因为F(1),答案是1(条件的第一部分).

F(n),答案是F(n-1) + F(n-2).

那么什么功能满足这些规则呢?尝试n(a> 1):

a n == a (n-1) + a (n-2)

除以(n-2):

a 2 == a + 1

解决a,你得到(1+sqrt(5))/2 = 1.6180339887,或称为黄金比例.

所以它需要指数时间.


通过归纳证明.尼斯.+1
答案没错.它是无症状的.另一个解决方案是否定的,所以在物理上没有意义.
有人可以解释^ n == a ^(n-1)+ a ^(n-2)如何满足这些规则?如何完全满足,请具体说明.
30赞成错误答案?:-)是否遵循1 = F(1)=(1 + sqrt(5))/ 2?那另一个解决方案呢,(1-sqrt(5))/ 2?

3> J.P...:

我同意pgaur和rickerbh,recursive-fibonacci的复杂性是O(2 ^ n).

我以相当简单的方式得出了相同的结论,但我相信仍然是有效的推理.

首先,它是关于计算在计算第N个斐波那契数时调用递归的斐波那契函数(从现在开始的F())的次数.如果在序列0到n中每个数字调用一次,那么我们有O(n),如果每个数字被调用n次,那么我们得到O(n*n)或O(n ^ 2),等等.

因此,当为数字n调用F()时,对于0和n-1之间的给定数字,调用F()的次数随着接近0而增加.

作为第一印象,在我看来,如果我们以可视方式放置它,每次为一个给定的数字调用F()绘制一个单位,wet得到一种金字塔形状(也就是说,如果我们水平居中单位) ).像这样的东西:

n              *
n-1            **
n-2           ****  
...
2           ***********
1       ******************
0    ***************************

现在,问题是,随着n的增长,这个金字塔的基数有多快?

我们来看一个真实案例,例如F(6)

F(6)                 *  <-- only once
F(5)                 *  <-- only once too
F(4)                 ** 
F(3)                ****
F(2)              ********
F(1)          ****************           <-- 16
F(0)  ********************************    <-- 32

我们看到F(0)被调用32次,这是2 ^ 5,对于这个样本情况是2 ^(n-1).

现在,我们想知道F(x)被调用多少次,我们可以看到调用F(0)的次数只是其中的一部分.

如果我们在精神上将所有*从F(6)移动到F(2)线到F(1)线,我们看到F(1)和F(0)线的长度现在相等.这意味着,当n = 6时,调用总次数F()为2x32 = 64 = 2 ^ 6.

现在,就复杂性而言:

O( F(6) ) = O(2^6)
O( F(n) ) = O(2^n)


F(3)只被调用3次而不是4次.第二个金字塔是错误的.

4> Bob Cross..:

麻省理工学院对这个具体问题进行了非常好的讨论.在第5页,他们指出,如果你假设一个加法需要一个计算单位,那么计算Fib(N)所需的时间与Fib(N)的结果密切相关.

因此,您可以直接跳到Fibonacci系列的非常接近的近似值:

Fib(N) = (1/sqrt(5)) * 1.618^(N+1) (approximately)

并且因此说,天真算法的最坏情况表现是

O((1/sqrt(5)) * 1.618^(N+1)) = O(1.618^(N+1))

PS:如果您想了解更多信息,请在维基百科上讨论Nth Fibonacci数字的封闭形式表达式.



5> Tony Tannous..:

您可以扩展它并进行可视化

     T(n) = T(n-1) + T(n-2) <
     T(n-1) + T(n-1) 

     = 2*T(n-1)   
     = 2*2*T(n-2)
     = 2*2*2*T(n-3)
     ....
     = 2^i*T(n-i)
     ...
     ==> O(2^n)



6> Dave L...:

它位于下端2^(n/2)和上端2 ^ n(如其他注释中所述).递归实现的一个有趣的事实是它具有Fib(n)本身的紧密渐近界.这些事实可以概括为:

T(n) = ?(2^(n/2))  (lower bound)
T(n) = O(2^n)   (upper bound)
T(n) = ?(Fib(n)) (tight bound)

如果您愿意,可以使用封闭形式进一步减少紧密限制.



7> benkc..:

证明答案是好的,但我总是需要手工做几次迭代才能真正说服自己.所以我在我的白板上画了一个小的调用树,并开始计算节点.我将计数分为总节点,叶节点和内部节点.这是我得到的:

IN | OUT | TOT | LEAF | INT
 1 |   1 |   1 |   1  |   0
 2 |   1 |   1 |   1  |   0
 3 |   2 |   3 |   2  |   1
 4 |   3 |   5 |   3  |   2
 5 |   5 |   9 |   5  |   4
 6 |   8 |  15 |   8  |   7
 7 |  13 |  25 |  13  |  12
 8 |  21 |  41 |  21  |  20
 9 |  34 |  67 |  34  |  33
10 |  55 | 109 |  55  |  54

立即跳出的是叶子节点的数量fib(n).需要多次迭代注意的是内部节点的数量是多少fib(n) - 1.因此节点的总数是2 * fib(n) - 1.

由于在对计算复杂性进行分类时丢弃了系数,因此最终的答案是?(fib(n)).



8> nikhil kekan..:

通过绘制递归树可以更好地估计递归算法的时间复杂度.在这种情况下,绘制递归树的递归关系将是T(n)= T(n-1)+ T(n-2)+ O(1)注意每一步都需要O(1)意味着恒定的时间,因为如果 block.Recursion树看起来只有一个比较来检查n的值.

          n
   (n-1)      (n-2)
(n-2)(n-3) (n-3)(n-4) ...so on

这里可以说上面树的每个级别由i表示,因此,

i
0                        n
1            (n-1)                 (n-2)
2        (n-2)    (n-3)      (n-3)     (n-4)
3   (n-3)(n-4) (n-4)(n-5) (n-4)(n-5) (n-5)(n-6)

假设在i的特定值,树结束,那个情况将是当ni = 1时,因此i = n-1,意味着树的高度是n-1.现在让我们看看树中每个n层的工作量是多少.注意每个步骤需要O(1)时间,如递归关系中所述.

2^0=1                        n
2^1=2            (n-1)                 (n-2)
2^2=4        (n-2)    (n-3)      (n-3)     (n-4)
2^3=8   (n-3)(n-4) (n-4)(n-5) (n-4)(n-5) (n-5)(n-6)    ..so on
2^i for ith level

因为i = n-1是在每个级别完成的树木工作的高度

i work
1 2^1
2 2^2
3 2^3..so on

因此,完成的总工作将是在每个级别完成的工作的总和,因此它将是2 ^ 0 + 2 ^ 1 + 2 ^ 2 + 2 ^ 3 ... + 2 ^(n-1),因为i = n-1.通过几何级数,这个和是2 ^ n,因此这里的总时间复杂度是O(2 ^ n)

推荐阅读
放ch养奶牛
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有