Commit e8fbb0e5 authored by Ben Glocker's avatar Ben Glocker
Browse files

updated fibonacci challenge

parent f3f53c84
%% Cell type:markdown id: tags:
# CO202 - Software Engineering - Algorithms
%% Cell type:markdown id: tags:
## Fibonacci Challenge: Dynamic Programming vs. Divide-and-Conquer
%% Cell type:markdown id: tags:
### DP Fibonacci - Bottom-up (space efficient)
%% Cell type:code id: tags:
``` python
def fib_dp_bottom_up(n):
if n == 0:
return 0
f = [0]*(n+1)
f[0] = 0
f[1] = 1
for i in range(2,n+1):
f[i] = f[i-1] + f[i-2]
return f[n]
print(fib_dp_bottom_up(10))
%timeit fib_dp_bottom_up(10)
```
%% Cell type:code id: tags:
``` python
def fib_dp_bottom_up(n):
i,j = 1,0
for k in range(1,n + 1):
i,j = j, i + j
return j
print(fib_dp_bottom_up(10))
%timeit fib_dp_bottom_up(10)
```
%% Cell type:markdown id: tags:
### DP Fibonacci - Top-down with Memoization
%% Cell type:code id: tags:
``` python
m = {0: 0, 1: 1}
def fib_dp_top_down(n):
m.clear()
m[0] = 0
m[1] = 1
return fib_dp_top_down_aux(n)
def fib_dp_top_down_aux(n):
if n not in m:
m[n] = fib_dp_top_down_aux(n-1) + fib_dp_top_down_aux(n-2)
return m[n]
print(fib_dp_top_down_aux(10))
%timeit fib_dp_top_down(10)
```
%% Cell type:markdown id: tags:
### D&C Fibonacci
%% Cell type:code id: tags:
``` python
import math
def fib_dc(n):
if n == 0:
return 0
elif n == 1:
return 1
else:
a = fib_dc(math.ceil(n / 2))
b = fib_dc(math.ceil(n / 2) - 1)
if n % 2 == 0:
return a * (a + 2 * b)
else:
return a * a + b * b
print(fib_dc(10))
%timeit fib_dc(10)
```
%% Cell type:markdown id: tags:
### D&C Fast Fibonacci (v1) - provided by Jacek Burys
%% Cell type:code id: tags:
``` python
import numpy as np
dt = np.int64
def fib_dc_fast(n):
init = np.matrix([[1], [0]], dtype=dt )
transform = matrix_pow(np.matrix([[1,1],[1,0]], dtype=dt), n)
return (transform * init).item(1)
return transform[0,1]
def matrix_pow(m, n):
if n == 0:
return np.matrix([[1,0],[0,1]], dtype=dt)
if n == 1:
return m
temp = matrix_pow(m, n // 2)
if n % 2 == 0:
return temp * temp
else:
return temp * temp * m
print(fib_dc_fast(10))
%timeit fib_dc_fast(10)
```
%% Cell type:markdown id: tags:
### D&C Fast Fibonacci (v2)
%% Cell type:code id: tags:
``` python
def fib_dc_fast2(n):
init = [1,0]
transform = matrix_pow2([1,1,1,0], n)
return matrix_vec_mul(transform,init)[1]
return transform[1]
def matrix_pow2(m, n):
if n == 0:
return [1,0,0,1]
if n == 1:
return m
temp = matrix_pow2(m, n // 2)
if n % 2 == 0:
return matrix_mul(temp,temp)
else:
return matrix_mul(matrix_mul(temp,temp),m)
def matrix_vec_mul(m,v):
r = [0]*2
r[0] = m[0]*v[0] + m[2] * v[1]
r[1] = m[1]*v[0] + m[3] * v[1]
return r
def matrix_mul(m1,m2):
r = [0]*4
r[0] = m1[0]*m2[0] + m1[2] * m2[1]
r[1] = m1[1]*m2[0] + m1[3] * m2[1]
r[2] = m1[0]*m2[2] + m1[2] * m2[3]
r[3] = m1[1]*m2[2] + m1[3] * m2[3]
return r
print(fib_dc_fast2(10))
%timeit fib_dc_fast2(10)
```
%% Cell type:markdown id: tags:
### Closed form expression - Binet's formula
%% Cell type:code id: tags:
``` python
import math
def fib_binet(n):
f = (1 + math.sqrt(5))/2
return (f**n - (-f)**-n)/math.sqrt(5)
print(fib_binet(10))
%timeit fib_binet(10)
```
%% Cell type:markdown id: tags:
### Sanity check
%% Cell type:code id: tags:
``` python
n = 500
print("DP Bottom-up\t" + str(fib_dp_bottom_up(n)))
print("DP Top-down\t" + str(fib_dp_top_down(n)))
print("D&C\t\t" + str(fib_dc(n)))
print("D&C Fast\t" + str(fib_dc_fast(n)))
print("D&C Fast v2\t" + str(fib_dc_fast2(n)))
print("Binet\t\t" + str(int(fib_binet(n))))
```
%% Cell type:markdown id: tags:
### Comparison
%% Cell type:code id: tags:
``` python
import time
def time_f(f):
before = time.clock()
f()
after = time.clock()
return after - before
n_max = 10000
samples = 50
step = int(n_max/samples)
data = range(1,n_max,step)
```
%% Cell type:code id: tags:
``` python
t1 = []
for i in data:
t1.append(time_f(lambda: fib_dp_bottom_up(i)))
```
%% Cell type:code id: tags:
``` python
t2 = []
for i in data:
t2.append(time_f(lambda: fib_dc(i)))
```
%% Cell type:code id: tags:
``` python
%matplotlib inline
from matplotlib import pyplot as plt
plt.scatter(data, t1, c='green')
plt.scatter(data, t2, c='red')
plt.xlabel('n')
plt.ylabel('time (/s)')
plt.legend(['dp bottom-up','d&c'],loc='upper left')
plt.xlim(0)
plt.ylim(0)
```
%% Cell type:code id: tags:
``` python
t3 = []
for i in data:
t3.append(time_f(lambda: fib_dc_fast2(i)))
```
%% Cell type:code id: tags:
``` python
%matplotlib inline
from matplotlib import pyplot as plt
plt.scatter(data, t1, c='green')
plt.scatter(data, t2, c='red')
plt.scatter(data, t3, c='blue')
plt.xlabel('n')
plt.ylabel('time (/s)')
plt.legend(['dp bottom-up','d&c','d&c fast'],loc='upper left')
plt.xlim(0)
plt.ylim(0)
```
%% Cell type:code id: tags:
``` python
n_max = 1000000
samples = 50
step = int(n_max/samples)
data = range(1,n_max,step)
t3 = []
for i in data:
t3.append(time_f(lambda: fib_dc_fast2(i)))
%matplotlib inline
from matplotlib import pyplot as plt
plt.scatter(data, t3, c='blue')
plt.xlabel('n')
plt.ylabel('time (/s)')
plt.legend(['d&c fast'],loc='upper left')
plt.xlim(0)
plt.ylim(0)
```
%% Cell type:code id: tags:
``` python
```
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment