Document 7477349

Download Report

Transcript Document 7477349

Fibonacci numbers
• Fibonacci numbers:
0, 1, 1, 2, 3, 5, 8, 13, 21, 34,
...
where each number is the sum of the
preceding two.
• Recursive definition:
– F(0) = 0;
– F(1) = 1;
– F(number) = F(number-1)+ F(number2);
Redundant Calculations I
• To compute fib(n), we recursively compute
fib(n-1). When the recursive call return, we
compute fib(n-2) using another recursive
call
– We have already computed fib(n-2) in the
process of computing fib(n-1)
– We make two calls to fib(n-2)
Redundant Calculations II
• Making two method calls would double the
running time
• Compounding effect: each recursive call
does more and more redundant work
– Each call to fib(n-1) and each call to fib(n-2)
makes a call to fib(n-3); there are 3 calls to
fib(n-3)
– Each call to fib(n-2) or fib(n-3) results in a call
to fib(n-4), so 5 calls to fib(n-4)
Redundant Calculations III
• C(n): number of calls to fib method
• C(0)=C(1)=1;
• For n>=2, we call fib(n) and plus all the
calls needed to evaluate fib(n-1) and fib(n2) recursively and independently; so
C(n)=c(n-1)+c(n-2)+1
• The recursive routine fib is exponential
Analyzing the Binary Recursion
Fibonacci Algorithm
• Let nk denote number of recursive calls made by
BinaryFib(k). Then
–
–
–
–
–
–
–
–
–
n0 = 1
n1 = 1
n2 = n1 + n0 + 1 = 1 + 1 + 1 = 3
n3 = n2 + n1 + 1 = 3 + 1 + 1 = 5
n4 = n3 + n2 + 1 = 5 + 3 + 1 = 9
n5 = n4 + n3 + 1 = 9 + 5 + 1 = 15
n6 = n5 + n4 + 1 = 15 + 9 + 1 = 25
n7 = n6 + n5 + 1 = 25 + 15 + 1 = 41
n8 = n7 + n6 + 1 = 41 + 25 + 1 = 67.
• Note that the value at least doubles for every other
value of nk. That is, nk > 2k/2. It is exponential!
n
n-2
n-1
n-3
…
n-2
1
0
Height=n, #nodes=2n,
complexity=O(2n)
n-3
n-4
A Better Fibonacci Algorithm
• Use linear recursion instead:
Algorithm LinearFibonacci(k):
Input: A nonnegative integer k
Output: Pair of Fibonacci numbers (Fk, Fk-1)
if k = 1 then
return (k, 0)
else
(i, j) := LinearFibonacci(k - 1)
return (i +j, i)
• Linear recursion: a method makes at most
one recursive call each time it is invoked.
• Runs in O(k) time.
Dynamic Programming –
Example
• Dynamic programming version of fibonacci(n)
– If n is 0 or 1, return 1
– Else solve fibonacci(n-1) and fibonacci(n-2)
• Look up value if previously computed
• Else recursively compute
– Find their sum and store
– Return result
• Dynamic programming algorithm  O(n) time
– Since solving fibonacci(n-2) is just looking up
value