Dynamic programming
One more recursive example
Last time we saw this tree method:
def to_list_at(self, node): if not node: return [] return self.to_list_at(node.left) + [node.data] + self.to_list_at(node.right) def to_list(self): return self.to_list_at(self.root)
Let’s walk through its execution on a small tree:
name | value |
---|---|
s |
loc 1 |
location | data |
loc 1 |
BST { root -> loc 2 } |
loc 2 |
BSTNode { data -> 10, parent -> None, left -> loc 3, right -> loc 4 } |
loc 3 |
BSTNode { data -> 7, parent -> loc 3, left -> None, right -> None } |
loc 4 |
BSTNode { data -> 20, parent -> loc 3, left -> None, right -> None } |
See the lecture capture for details.
Where we’ve been and where we’re going
On the first day of class, I talked about the two big themes of the course: algorithms and software engineering. I’d like to revisit those themes in the context of what we’ve learned so far.
Algorithms | Software engineering |
---|---|
while loops | |
sorting | |
objects | |
encapsulation | |
polymorphism | |
inheritance | |
trees | trees |
linked lists | linked lists |
iteration vs. recursion |
At the end of the week, we’re going to transition to a new programming language, Scala. Before we get there, we’re going to discuss one more algorithmic technique, called dynamic programming.
Recursion revisited
The Fibonacci sequence is defined by the following function:
Fib(0) = 1 Fib(1) = 1 Fib(n) = Fib(n - 1) + Fib(n - 2) [when n > 1]
How would we implement the fibonacci sequence in Python? The natural way might be to write something like this:
def fib(n): if n == 0: return 1 if n == 1: return 1 return fib(n - 1) + fib(n - 2)
We can step through the computation of fib(4)
(which will only require the
program dictionary, not memory). See lecture capture for details.
This solution works, but we might be able to come up with something more
efficient. In computing fib(4)
, how many times is fib(2)
called? It’s called
twice: once in computing fib(4)
and once when computing fib(3)
. How can we
do better?
def fib(n): fibs = [0, 1] i = 2 while i <= n: fibs.append(fibs[i - 1] + fibs[i - 2]) return fibs[n]
This solution uses dynamic programming, which we’ll talk more about next class.