# We noticed this morning that some functionstake longer than others -- even our computer isn't fast enough to do every function "instantly"
# Let's look at fibonacci numbers again
def fib_recursive(n):
if n == 0 or n == 1:
return n
return fib_recursive(n-1) + fib_recursive(n-2)
print(fib_recursive(35))
9227465
# Wow, how long does this take? Why is it so slow?
print(fib_recursive(50))
# How about we try measuring the time it takes to run? We can use the `time` module.
import time
# time.time() gives us the number of seconds since January 1, 1970.
# We can use this to measure the time it takes to run a function.
start = time.time()
# time.sleep(x) forces the code to pause execution for x seconds
time.sleep(2)
end = time.time()
print(end-start)
2.0049819946289062
# Iterative Fibinocci
def fib_iterative(n):
fib_i_prev_prev = 0 # initialized to F(0)
fib_i_prev = 1 # initialized to F(1)
for i in range(n - 1):
# compute the next number in the sequence
fib_i = fib_i_prev_prev + fib_i_prev
# save state to use for the next computation
fib_i_prev_prev = fib_i_prev
fib_i_prev = fib_i
return fib_i
# Let's compare runtimes of iterative Fibonacci and Recursive Fibonocci.
def compare_runtimes(n):
start = time.time()
fib_iterative(n)
end = time.time()
print("Iterative Fibonacci: " + str(end-start))
start = time.time()
fib_recursive(n)
end = time.time()
print("Recursive Fibonacci: " + str(end-start))
compare_runtimes(20)
Iterative Fibonacci: 2.1457672119140625e-06 Recursive Fibonacci: 0.0008518695831298828
What are problems with using time to benchmark our algorithm? Runtime differs depending on the machine you're running on.
Instead, let's use the number of operations.
A "tree" is a special kind of graph where there are no loops.
We can draw a graph of the call structure to visualize what's going on. Each node is a distinct call. (Draw on board if available)
Since this graph has a root and no loops, we call it a "tree".
# So, how many operations does it take to compute fib(n) recursively?
# Let's try to count the number of operations it takes to compute fib(n) recursively:
# We can actually write a recursive function to compute that :)
def num_fib_operations(n):
# base case:
if n == 0 or n == 1:
return 1
# recursion step:
return 1 + num_fib_operations(n - 1) + num_fib_operations(n - 2)
print(num_fib_operations(10))
177
# Let's graph the number of operations it takes to compute fib(n) recursively:
import matplotlib.pyplot as plt
import numpy as np
n = np.arange(0, 20)
plt.plot(n, [num_fib_operations(i) for i in n])
plt.xlabel("n")
plt.ylabel("number of operations")
plt.title("Number of operations to compute fib(n) recursively")
plt.show()
We can use this same approach for many different algorithms we've writtens of far.
# We can count the number of operations it takes for different algorithms
# Example: O(n):
# 2n + 2
def sum_to_n(n):
sum = 0 # 1 operation
for i in range(n): # n times
sum = sum + i # 2 operation
return sum # 1 operation
# Example: O(n^2):
# n^2 + 2 operations
def sum_to_n_squared(n):
sum = 0 # 1 operation
for i in range(n): # n times
for j in range(n): # n times
sum += i + j # 1 operation
return sum # 1 operation
# Example: O(n^3):
# n^3 + 2 operations
def sum_to_n_cubed(n):
sum = 0 # 1 operation
for i in range(n): # n times
for j in range(n): # n times
for k in range(n): # n times
sum += i + j + k # 1 operation
return sum # 1 operation
# Example: O(1):
# 3 operations
def sum_to_n_constant(n):
return n * (n + 1) // 2 # 3 operations
# Example: O(log(n)):
# 2log(n) + 2 operations
def sum_to_n_log(n):
sum = 0 # 1 operation
i = 1 # 1 operation
while i <= n: # log(n) times
sum += i # 1 operation
i *= 2 # 1 operation
return sum # 1 operation
tas = ['hailey','wassim','shalom','monica','bre','aku','kidist','bruk']
Where in the list is aku
? (at which index -- remember indices start from 0)
# Linear search: this is O(n)
Where in the list is wassim
? (at which index -- remember indices start from 0)
Write a function to find the index of a TA in the list
def find_index_of_name(lst,name):
return 0
What if the list is sorted?
tas_sorted = ['sxrtu6etraku','bre','bruk','hailey','kidist','monica','shalom','wassim']
Write a function to find aku
in the sorted list
# binary search —— this is O(log(n))!
Write a function to find wassim
in the sorted list