本文翻译自:Computational complexity of Fibonacci Sequence
I understand Big-O notation, but I don't know how to calculate it for many functions. 我了解Big-O表示法,但是我不知道如何为许多函数计算它。 In particular, I've been trying to figure out the computational complexity of the naive version of the Fibonacci sequence: 特别是,我一直在尝试找出Fibonacci序列的朴素版本的计算复杂性:
int Fibonacci(int n)
{
if (n <= 1)
return n;
else
return Fibonacci(n - 1) + Fibonacci(n - 2);
}
What is the computational complexity of the Fibonacci sequence and how is it calculated? 斐波那契数列的计算复杂度是多少?如何计算?
#1楼
参考:https://stackoom.com/question/1VqW/斐波那契数列的计算复杂度
#2楼
Well, according to me to it is O(2^n)
as in this function only recursion is taking the considerable time (divide and conquer). 好吧,对我来说,它是O(2^n)
因为在此函数中,仅递归需要花费大量时间(分而治之)。 We see that, the above function will continue in a tree until the leaves are approaches when we reach to the level F(n-(n-1))
ie F(1)
. 我们看到,以上功能将在树中继续,直到达到F(n-(n-1))
即F(1)
的水平为止。 So, here when we jot down the time complexity encountered at each depth of tree, the summation series is: 因此,在这里,当我们记下在树的每个深度遇到的时间复杂度时,求和序列为:
1+2+4+.......(n-1)
= 1((2^n)-1)/(2-1)
=2^n -1
that is order of 2^n [ O(2^n) ]
. 那是2^n [ O(2^n) ]
。
#3楼
The proof answers are good, but I always have to do a few iterations by hand to really convince myself. 证明答案是好的,但是我总是必须手动做几次迭代才能真正说服自己。 So I drew out a small calling tree on my whiteboard, and started counting the nodes. 因此,我在白板上绘制了一个小的调用树,并开始计算节点数。 I split my counts out into total nodes, leaf nodes, and interior nodes. 我将计数分为总节点,叶节点和内部节点。 Here's what I got: 这是我得到的:
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
What immediately leaps out is that the number of leaf nodes is fib(n)
. 立即跃出的是叶子节点的数量为fib(n)
。 What took a few more iterations to notice is that the number of interior nodes is fib(n) - 1
. 需要更多迭代才能注意到,内部节点的数量为fib(n) - 1
。 Therefore the total number of nodes is 2 * fib(n) - 1
. 因此,节点总数为2 * fib(n) - 1
。
Since you drop the coefficients when classifying computational complexity, the final answer is θ(fib(n))
. 由于在对计算复杂度进行分类时会丢弃系数,因此最终答案是θ(fib(n))
。
#4楼
I agree with pgaur and rickerbh, recursive-fibonacci's complexity is O(2^n). 我同意pgaur和rickerbh的观点,递归斐波那契的复杂度为O(2 ^ n)。
I came to the same conclusion by a rather simplistic but I believe still valid reasoning. 我得出的结论很简单,但我认为推理仍然有效。
First, it's all about figuring out how many times recursive fibonacci function ( F() from now on ) gets called when calculating the Nth fibonacci number. 首先,所有要弄清楚计算第N个斐波那契数时递归斐波那契函数(从现在开始F())被调用多少次。 If it gets called once per number in the sequence 0 to n, then we have O(n), if it gets called n times for each number, then we get O(n*n), or O(n^2), and so on. 如果它按从0到n的顺序被每个数字调用一次,则为O(n),如果被每个数字调用n次,则得到O(n * n)或O(n ^ 2),等等。
So, when F() is called for a number n, the number of times F() is called for a given number between 0 and n-1 grows as we approach 0. 因此,当F()被调用为数字n时,在0和n-1之间的给定数字被调用F()的次数随着我们接近0而增加。
As a first impression, it seems to me that if we put it in a visual way, drawing a unit per time F() is called for a given number, wet get a sort of pyramid shape (that is, if we center units horizontally). 作为第一印象,在我看来,如果我们以可视的方式进行描述,则每次给定数字调用F()时绘制一个单位,湿式就会得到一种金字塔形状(也就是说,如果我们将单位水平居中)。 Something like this: 像这样:
n *
n-1 **
n-2 ****
...
2 ***********
1 ******************
0 ***************************
Now, the question is, how fast is the base of this pyramid enlarging as n grows? 现在的问题是,随着n的增长,这个金字塔的底数会以多快的速度增长?
Let's take a real case, for instance F(6) 让我们来看一个真实的例子,例如F(6)
F(6) * <-- only once
F(5) * <-- only once too
F(4) **
F(3) ****
F(2) ********
F(1) **************** <-- 16
F(0) ******************************** <-- 32
We see F(0) gets called 32 times, which is 2^5, which for this sample case is 2^(n-1). 我们看到F(0)被调用32次,即2 ^ 5,在此示例情况下为2 ^(n-1)。
Now, we want to know how many times F(x) gets called at all, and we can see the number of times F(0) is called is only a part of that. 现在,我们想知道F(x)被调用了多少次,我们可以看到F(0)的调用次数只是其中的一部分。
If we mentally move all the *'s from F(6) to F(2) lines into F(1) line, we see that F(1) and F(0) lines are now equal in length. 如果我们将所有*从F(6)线到F(2)线智能地移到F(1)线,我们将看到F(1)和F(0)线的长度现在相等。 Which means, total times F() gets called when n=6 is 2x32=64=2^6. 这意味着,当n = 6为2x32 = 64 = 2 ^ 6时,调用总时间F()。
Now, in terms of complexity: 现在,就复杂性而言:
O( F(6) ) = O(2^6)
O( F(n) ) = O(2^n)
#5楼
http://www.ics.uci.edu/~eppstein/161/960109.html http://www.ics.uci.edu/~eppstein/161/960109.html
time(n) = 3F(n) - 2 时间(n)= 3F(n)-2
#6楼
Just ask yourself how many statements need to execute for F(n)
to complete. 只是问问自己,要完成F(n)
,需要执行多少条语句。
For F(1)
, the answer is 1
(the first part of the conditional). 对于F(1)
,答案是1
(条件的第一部分)。
For F(n)
, the answer is F(n-1) + F(n-2)
. 对于F(n)
,答案是F(n-1) + F(n-2)
。
So what function satisfies these rules? 那么什么功能满足这些规则? Try a n (a > 1): 尝试n (a> 1):
a n == a (n-1) + a (n-2) a n == a (n-1) + a (n-2)
Divide through by a (n-2) : 除以(n-2) :
a 2 == a + 1 a 2 == a + 1
Solve for a
and you get (1+sqrt(5))/2 = 1.6180339887
, otherwise known as the golden ratio . 求解a
得到(1+sqrt(5))/2 = 1.6180339887
,也就是黄金分割率 。
So it takes exponential time. 因此,它花费了指数时间。