DAA(Lecture 5)
DAA(Lecture 5)
Algorithms (CS-306)
Dynamic Programming
Lecture No. 5
The problem:
◦ Lots and lots of calls to Fib(1) and Fib(0) are made.
It would be nice if we only made those method calls once, then
simply used those values as necessary.
If I asked you to compute the 10th Fibonacci number, you would never do
it using the recursive steps above. Instead, you'd start making a chart:
◦ F1 = 1, F2 = 1, F3 = 2, F4 = 3, F5 = 5, F6 = 8, F7 = 13, F8 = 21, F9 = 34, F10 = 55.
◦ First you calculate F3 by adding F1 and F2, then F4, by adding F3 and F4, etc.
Dynamic Programming
The idea of dynamic programming is to avoid
making redundant method calls
◦ Instead, one should store the answers to all necessary method calls in
memory and simply look these up as necessary.
return fibnumbers[n];
}
Dynamic Programming
Usually, a dynamic programming algorithm
presents a time-space trade off.
◦ More space is used to store values,
◦ BUT less time is spent because these values
can be looked up.
Dynamic Programming Example
Problems
◦ “ODOR” is a subsequence
made up of the characters at indices 1, 3, 5, and 6.
LCS(“FU”, “FI”)= 1
◦ Last chars Do NOT match:
max(LCS(“FU”, “F”), LCS(“F”, “FI”)
= max (1 , 1) = 1
return lengths[a.length()][b.length()];
}
Edit Distance
The Edit Distance (or Levenshtein distance)
is a metric for measuring the amount of
difference between two.
◦ The Edit Distance is defined as the minimum number
of edits needed to transform one string into the
other.
◦ Also, in our recursive solution, we must note that the edit distance
between the empty string and another string is the length of the
second string. (This corresponds to having to insert each letter for
the transformation.)
Edit Distance
So, an outline of our recursive solution is as follows:
1) If either string is empty, return the length of the other string.
Or more simply…
Given a positive integer n, how many ways
can we make change for n cents using
pennies, nickels, dimes and quarters?
The Change Problem
Recursively, we could break down the problem as follows:
◦ To make change for n cents we could:
1) Give the customer a quarter. Then we have to make change for n-25 cents
2) Give the customer a dime. Then we have to make change for n-10 cents
3) Give the customer a nickel. Then we have to make change for n-5 cents
4) Give the customer a penny. Then we have to make change for n-1 cents.
1) If d is 25, give out a quarter and make change for n-25 cents using the largest
coin as a quarter.
2) If d is 10, give out a dime and make change for n-10 cents using the largest coin
as a dime.
3) If d is 5, give out a nickel and make change for n-5 cents using the largest coin
as a nickel.
4) If d is 1, we can simply return 1 since if you are only allowed to give pennies,
you can only make change in one way.
The Change Problem
There's a whole bunch of stuff going on here,
but one of the things you'll notice is that the
larger n gets, the slower and slower this will
run, or maybe your computer will run out of
stack space.
◦ Further analysis will show that many, many method
calls get repeated in the course of a single initial
method call.
// Initialize table
for (int i=0; i<n+1;i++)
table[0][i] = 1;
for (int i=0; i<5; i++) {
table[1][i] = 1;
table[2][i] = 1;
table[3][i] = 1;
}
for (int i=5;i<n+1;i++) {
table[1][i] = 0;
table[2][i] = 0;
table[3][i] = 0;
// Fill in table, row by row. Remember,
for (int i=1; i<4; i++) { int[] denominations = {1, 5, 10, 25};
for (int j=5; j<n+1; j++) {
for (int k=0; k<=i; k++) {
if ( j >= denominations[k])
table[i][j] +=
table[k][j - denominations[k]];
}
}
}
return table[lookup(d)][n];
}
}
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
5 1 1 1 1 1 2 2 2 2 2 3 3 3 3 3 4
10 1 1 1 1 1 2 2 2 2 2 4 4 4 4 4 6
25 1 1 1 1 1 2 2 2 2 2 4 4 4 4 4 6
The Change Problem
To make this change in the code, just
substitute this line for the for loop with k
in the previous code:
if ( j >= denominations[i])
table[i][j] = table[i-1][j] + table[i][j - denominations[k]];
else
table[i][j] = table[i-1][j]
Now see if you can finish filling in the zeroed out
portion of the table using the code above.
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
5 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0
10 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0
25 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0
References
Slides adapted from Arup Guha’s Computer
Science II Lecture notes:
http://www.cs.ucf.edu/~dmarino/ucf/cop3503/le
ctures/
Additional material from the textbook:
Data Structures and Algorithm Analysis in Java (Second
Edition) by Mark Allen Weiss
Additional images:
www.wikipedia.com
xkcd.com