I write 2 fibonacci functions, one is to use recursion, and as expected, fibonacci_recursive(4) has 9 function calls in the call stacks:
def fibonacci_recursive_1(n):
if n == 0 or n == 1: # base case
result = n
print('return from base case, n = ', n, ', fib({}) = '.format(n), result)
return result
else: # recursive case
result = fibonacci_recursive_1(n-2) + fibonacci_recursive_1(n-1)
print('return from recursive case, n = ', n, ', fib({}) = '.format(n), result)
return result
fibonacci_recursive_1(4)
return from base case, n = 0 , fib(0) = 0
return from base case, n = 1 , fib(1) = 1
return from recursive case, n = 2 , fib(2) = 1
return from base case, n = 1 , fib(1) = 1
return from base case, n = 0 , fib(0) = 0
return from base case, n = 1 , fib(1) = 1
return from recursive case, n = 2 , fib(2) = 1
return from recursive case, n = 3 , fib(3) = 2
return from recursive case, n = 4 , fib(4) = 3
3
Then I did one with dynamic programming memoization
stored_results = {}
def fibonacci_dynamic_1(n):
result = 0
if n in stored_results: # memoization
result += stored_results[n]
print('return from cached results, n = ', n, ', fib({}) = '.format(n), result)
return result
else:
if n == 0 or n == 1: # base case
result = n
stored_results[n] = result
print('return from base case, n = ', n, ', fib({}) = '.format(n), result)
return result
else: # recursive case
result = fibonacci_dynamic_1(n-2) + fibonacci_dynamic_1(n-1)
stored_results[n] = result
print('return from recursive case, n = ', n, ', fib({}) = '.format(n), result)
return result
fibonacci_dynamic_1(4)
To my surprise, there are only 7 function calls left in the call stack for fibonacci_dynamic(4):
return from base case, n = 0 , fib(0) = 0
return from base case, n = 1 , fib(1) = 1
return from recursive case, n = 2 , fib(2) = 1
return from cached results, n = 1 , fib(1) = 1
return from cached results, n = 2 , fib(2) = 1
return from recursive case, n = 3 , fib(3) = 2
return from recursive case, n = 4 , fib(4) = 3
3
I understand that, if I use dictionary to store previously computed results, it would speed up the computations and will not repeat computing.
But shouldn't there be the same 9 function calls for dynamic programming, which some of them will be replaced with "return from cached results" (because they were computed), instead of just showing that only 7 function calls left?
Is there anything missing or I did not code it correctly?