Here is fib(n)
again:
def fib(n):
if n <= 1:
return 1
return fib(n - 1) + fib(n - 2)
fib(n)
, the naive way¶The call tree will look like:
1 level
\
... ... 1 ....
... ... ... 5
n-2 n-3 n-3 n-4 4
\/ \/ 3
n-1 _ n-2 2
\ / 1
n 0
The longest branch is the leftmost one, and it's of length . The shortest branch is the rightmost one (which goes n, n-2, n-4, ... 1), and it's of length that's approximately (since we are going from n to 1 in steps of 2.)
It's hard to count all the calls, but we can get an upper bound and a lower bound on their number.
To get the upper bound, assume that all the "branches" of the call tree are of length n (the longest one). Here are the numbers of calls we have at each level:
level 0: 1 call (2^0)
level 1: 2 calls (2^1)
level 3: 4 calls (2^2)
...
level (n-1): 2^(n-1) calls
So in total we have fewer than calls (i.e. ). This is the upper bound on the number of calls.
Now, let's get a lower bound on the number of calls (of course, one lower bound is 0, but let's get an interesting lower bound!). The shorterst branch, which is the rightmost branch, is of length n/2. Using the same analysis, if all the branches were of length , we'll have calls, i.e., the number of calls is .
So we have more than calls and less than calls.
But we can do better!
To compute fib(n)
, we need to compute fib(n-1)
and fib(n-2)
(and add them and
return the result, but that takes almost no time at all).
Suppose it takes seconds to compute fib(n)
(and so for fib(n-1)
and for fib(n-2)
).
Since the time to compute fib(n)
is the time to compute fib(n-1)
plus the time to compute fib(n-2)
, we get, approximately,
So the time to compute a fib(n)
itself looks like fib(n)
! That means that the time to compute fib(n)
is (again, approximately, since we are ignoring a bit of computation that happens in fib
) .
(Note that it's true that T(0)=T(1)=\text{const}
.)
In fact, you can use linear algebra to prove that , where is the Golden Ratio, .
This means that fib(n)
runs in time.
We bounded the number of calls made to between and calls. The exact estimate is . We actually got a pretty nice estimate for by thinking about the complexity of fib
: