Forth
Forth
md 2024-10-27
Assignment 4
Question 1
import time
fib_memo = {}
recursive_calls = 0
dictionary_lookups = 0
dictionary_updates = 0
def fibonacci(n):
global recursive_calls, dictionary_lookups, dictionary_updates
recursive_calls += 1
if n in fib_memo:
dictionary_lookups += 1
return fib_memo[n]
if n <= 1:
return n
fib_memo[n] = result
dictionary_updates += 1
return result
Example Usage:
n = 10
start_time = time.time()
result = fibonacci(n)
execution_time = time.time() - start_time
# Output results
print(f"Fibonacci({n}) = {result}")
print(f"Recursive calls: {recursive_calls}")
print(f"Dictionary lookups: {dictionary_lookups}")
print(f"Dictionary updates: {dictionary_updates}")
print(f"Execution time: {execution_time} seconds")
Output:
Fibonacci(10) = 55
Recursive calls: 19
Dictionary lookups: 7
Dictionary updates: 9
Execution time: 7.867813110351562e-06 seconds
Question 2
import matplotlib.pyplot as plt
import time
def fibonacci_recursive(n):
if n <= 1:
return n
return fibonacci_recursive(n - 1) + fibonacci_recursive(n - 2)
def measure_performance(n):
global recursive_calls, dictionary_lookups, dictionary_updates
recursive_calls = dictionary_lookups = dictionary_updates = 0
start_time = time.time()
fibonacci(n)
dp_time = time.time() - start_time
dp_calls = recursive_calls
start_time = time.time()
fibonacci_recursive(n)
recursive_time = time.time() - start_time
simple_calls = 2**n if n < 32 else "Too many calls"
2/4
Forth.md 2024-10-27
for n in n_values:
dp_time, recursive_time, dp_call, simple_call = measure_performance(n)
dp_times.append(dp_time)
recursive_times.append(recursive_time)
dp_calls.append(dp_call)
simple_calls.append(simple_call)
plt.figure(figsize=(5, 12))
plt.subplot(2, 1, 1)
plt.plot(n_values, dp_times, label='Dynamic Programming')
plt.plot(n_values, recursive_times, label='Simple Recursion')
plt.xlabel("Fibonacci Number (n)")
plt.ylabel("Time (seconds)")
plt.legend()
plt.title("Time Comparison for Fibonacci Calculation")
plt.subplot(2, 1, 2)
plt.plot(n_values, dp_calls, label='Dynamic Programming')
plt.plot(n_values, [2**n for n in n_values], label='Simple Recursion')
plt.xlabel("Fibonacci Number (n)")
plt.ylabel("Number of Calls")
plt.yscale("log")
plt.legend()
plt.title("Function Call Comparison for Fibonacci Calculation")
plt.tight_layout()
plt.show()
This code uses the previously defined fibonacci function. It compares the performance of calculating
Fibonacci numbers using dynamic programming with memoization and simple recursion.
. fibonacci_recursive(n): Calculates the Fibonacci number using simple recursion.
. measure_performance(n):
• Calculates the execution time and function calls for both methods.
• For dynamic programming (fibonacci function), it tracks the time and counts recursive calls.
• For simple recursion, it measures time and estimates the number of calls (approximated as 2^n).
. Data Collection:
• Runs measure_performance for Fibonacci numbers from 1 to 32, storing the time and call counts for
both methods.
. Plotting:
• The first plot compares the time taken by both methods.
• The second plot compares the number of function calls, using a logarithmic scale for clarity.
This visualization helps demonstrate that dynamic programming is significantly faster and involves far fewer
recursive calls than simple recursion as n increases.
3/4
Forth.md 2024-10-27
4/4