Approximate overview
Other good things
When do we get to redo stuff?
Finals week.
Are we going to have to redo stuff?
I hope not.
Are you going to be lenient, given how bad you are at returning stuff?
Yes.
Can I take an incomplete in this class?
Yes.
What will be hard?
We hate implementing things.
The layers/levels.
Writing in three languages at once.
Getting the probability right.
Off by one errors.
How do I get the probability right?
Read the article.
Start at level 1. Repeatedly generate a random number. If it’s less than p, add another level. If it’s greater than or equal to p, stop. If you reach the max level, stop.
Bring more questions on Monday!
You are a burglar.
You have a backpack that can hold up to k cubic centimetres of stuff.
You are in a warehouse. It’s unguarded, so you have a lot of time to look at what’s there.
In the warehouse are a variety of boxes. Each box has a value v[i], and size s[i]. Your backpack is magic! It can stretch to hold exactly k cubic centimeters (i.e., you don’t have to worry about layout).
Your goal: Get the most value for the size.
Box Size Value
0 0 0
1 1 1
2 1 5
3 2 2
4 2 1
5 2 7
6 3 2
7 5 2
8 6 11
9 8 3
10 10 19
11 15 10
Size 0 1 2 3 4 5 6 7 8 9 10
Value 0 5 7 12 13 ....
knapsack(boxes, capacity)
solution = [];
value = 0;
for (int i = 1; i <= n; i++) {
if (size[i] <= capacity) {
int hypothesis = value[i] + knapsack(boxes.remove(i), capacity-size[i]);
if (hypothesis < size) {
solution = solution + ...
value = hypothesis;
}
} // if small enough
} // for each box
return solution,value
} // for
Two problems:
TPS
Suppose we’ve solved the problem using boxes 0 through k-1 (and for all capacity <= c). How does it help us solve the problem for boxes 0 through k?
Phrase this recursively in terms of size[k], value[k], and a recursive call.
; knapsack(c, k, const boxes) - Find the maximum value for
; a capacity of c using boxes 0 .. k.
; c: capacity of the knapsack
; k: The portion of the list of boxes we're using
; boxes: The list of boxes
knapsack(c, k, const boxes) =
if (k == 0)
return 0;
else if (size[k] > c)
return knapsack(c, k-1, boxes);
else
return max(knapsack(c, k-1, boxes), // Don't take the kth box
knapsack(c-size[k], k-1, boxes) + value[k]) // Take the kth box
This remains exponential! Whoops!
We know that dynamic programming helps with recursive optimization algorithms because we can build a table to cache values; we should build that table iteratively.
We’re going to do a two-dimensional table.
Row k gives knapsack for the first k boxes. Column c gives capacity of c
Capacity
k 0 1 2 3 4 5 6 7 8 9 10 11
----------------------------------------------
0| 0 0 0 0 0 0 0 0 0 0 0 0
1| 0 0 2 2 2 2 2 2 2 2 2 2 ; size 2, value 2
2| 0 0 2 2 2 3 3 3 3 3 3 3 ; size 3, value 1
3| 0 4 4 6 6 6 7 7 7 7 7 7 ; size 1, value 4
4| 0 4 6 6 8 8 8 9 9 9 9 9 ; size 1, value 2
5| 0 4n 6n 7y 11 13 13 15 15 15 16 16 ; size 3, value 7
6|
7|
Running time? O(cn), where n is max number of boxes.
How do I know which boxes I took?
Phrase recursively, trust the magic recursion fairy. (“My recursive call works.”)
Turn into a table.
Built table iteratively.
We have two strings, s1 and s2. We want to know the fewest number of “edits” (delete a letter, insert a letter) necessary to go from s1 to s2.
hello
hlli
Requires us to delete the h and the o, and to insert the i.
Think about working with the last letter in each string, and
shortening one or both strings. You can use last(str) to
get the last character and allbutlast(str) to delete the
last character.
editDistance("","") = 0
editDistance(s1,"") = length(s1) * deleteCost
editDistance("",s2) = length(s2) * insertCost
editDistance(s1,s2) = ? (some recursive formulation)
min(????)
Suppose we want to change “????a” to “????a”.
Suppose we want to change “????a” to “????b”.