General Algorithmic Strategies:
Greedy and Dynamic Programming
Antonio Carzaniga
Faculty of Informatics
University of Lugano
December 5, 2011
© 2007 Antonio Carzaniga 1
Outline
Greedy strategy
Dynamic programming
© 2007 Antonio Carzaniga 2
Greedy Algorithms
© 2007 Antonio Carzaniga 3
Recap on MST Algorithms
Find the MST of G = (V , E) with w : E → R
◮ find a T ⊆ E that is a minimum-weight spanning tree
We naturally decompose the problem in a series of choices
◮ at each point we have a partial solution A ⊆ T
◮ we have a number of choices on how to extend A
◮ we make a “greedy” choice by selecting the lightest edge that
does not violate the constraints of the MST problem
Generic-MST(G, w)
1 A=∅
2 while A is not a spanning tree
3 find a safe edge e = (u, v) // the lightest that. . .
4 A = A ∪ {e}
© 2007 Antonio Carzaniga 4
Designing a Greedy Algorithm
1. Cast the problem as one where
◮ we make a choice, and
◮ we are left with a subproblem
2. Prove that there is always a solution to the original problem
that contains the greedy choice
◮ i.e., that the greedy choice always leads to an optimal solution
◮ not necessarily always the same one
3. Prove that the remaining subproblem is such that
◮ combining the greedy choice with the optimal solution of the
subproblem, we obtain an optimal solution to the original
problem
© 2007 Antonio Carzaniga 5
The Greedy-Choice Property
The first key ingredient of a greedy strategy is the following
greedy-choice property: one can always arrive at a
globally optimal solution by making a locally optimal
choice
At every step, we consider only what is best in the current
problem
◮ not considering the results of the subproblems
© 2007 Antonio Carzaniga 6
Optimal Substructure
The second key ingredient of a greedy strategy is the following
optimal-substructure property: an optimal solution
to the problem contains within it optimal solutions to
subproblems
It is natural to prove this by induction
◮ if the solution to the subproblem is optimal, then combining
the greedy choice with that solution yields an optimal solution
© 2007 Antonio Carzaniga 7
Example
The absolutely trivial gift-selection problem
◮ out of a set X = {x1 , x2 , . . . , xn } of valuable objects,
where v(xi ) is the value of xi
◮ you will be given, as a gift, k objects of your choice
◮ how do you maximize the total value of your gifts?
Decomposition: choice plus subproblem
◮ greedy choice: pick xi such that v(xi ) = maxx∈X v(x)
◮ subproblem: X ′ = X − {xi }, k ′ = k − 1 (same value function v)
Greedy-choice property
◮ if v(xi ) = maxx∈X v(x), then there is a globally optimal solution
A that contains xi
Optimal-substructure property
◮ if v(xi ) = maxx∈X v(x) and A′ is an optimal solution for
X ′ = X − {xi }, then A′ ⊂ A
© 2007 Antonio Carzaniga 8
Observation
Inventing a greedy algorithm is easy
◮ it is easy to come up with greedy choices
Proving it optimal may be difficult
◮ requires deep understanding of the structure of the problem
© 2007 Antonio Carzaniga 9
Making Change
My favorite pasta lunch typically costs Fr. 15.20; I usually pay
with a Fr. 20 bill, and get Fr. 4.80 of change
Question: how can I get the least amount of coins?
(Available denominations: 5, 2, 1, 0.5, 0.2, 0.1)
Solution: 2 × 2 + 0.5 + 0.2 + 0.1 = 4.8 (5 coins/bills)
Is this a greedy problem?
Suppose you are in the US and need to make $4.80 of change;
available denominations are $5, $1, $0.25, $0.1, and $.01
(you are out of “nickels”)
Greedy: 4 × 1 + 3 × 0.25 + 5 × 0.01 = 4.8 (12 coins/bills)
Optimal: 4 × 1 + 2 × 0.25 + 3 × 0.1 = 4.8 (9 coins/bills)
© 2007 Antonio Carzaniga 10
Knapsack Problem
A thief robbing a store finds n items
◮ vi is the value of item i
◮ wi is the weight of item i
◮ W is the maximum weight that the thief can carry
Problem: choose which items to take to maximize the total
value of the robbery
Is this a greedy problem?
Exercise:
1. formulate a reasonable greedy choice
2. prove that it doesn’t work with a counter-example
3. go back to (1) and repeat a couple of times
© 2007 Antonio Carzaniga 11
Fractional Knapsack Problem
A thief robbing a store finds n items
◮ vi is the value of item i
◮ wi is the weight of item i
◮ W is the maximum weight that the thief can carry
◮ the thief may take any fraction of an item (with the
corresponding proportional value)
Problem: choose which items, or fractions of items to take to
maximize the total value of the robbery
Is this a greedy problem?
Exercise: prove that it is a greedy problem
© 2007 Antonio Carzaniga 12
Activity-Selection Problem
A conference room is shared among different activities
◮ S = {a1 , a2 , . . . , an } is the set of proposed activities
◮ activity ai has a start time si and a finish time fi
◮ activities ai and aj are compatible if either fi ≤ sj or fj ≤ si
Problem: find the largest set of compatible activities
Example
activity a b c d e f g h i j k
start 8 0 2 3 5 1 5 3 12 6 8
finish 12 6 13 5 7 4 9 8 14 10 11
Is there a greedy solution for this problem?
© 2007 Antonio Carzaniga 13
Activity-Selection Problem (2)
k
j
i
h
g
f
e
d
c
b
a
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14
© 2007 Antonio Carzaniga 14
Activity-Selection Problem (3)
i
c
a
j
j
g
h
e
b
d
f
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14
Greedy choice: earliest finish time
© 2007 Antonio Carzaniga 15
Activity Selection is a Greedy Problem
Greedy choice: take ax ∈ S s.t. fx ≤ fi for all ai ∈ S
Prove: there is an optimal solution OPT ∗ that contains ax
Proof: (by contradiction)
◮ assume ax 6∈ OPT
◮ let am ∈ OPT be the earliest-finish activity in OPT
◮ construct OPT ∗ = OPT \ {am } ∪ {ax }
◮ OPT ∗ is valid
Proof:
◮ every activity ai ∈ OPT \ {am } has a starting time si ≥ fm ,
because am is compatible with ai (so either fi < sm or si > fm )
and fi > fm , because am is the earliest-finish activity in OPT
◮ therefore, every activity ai is compatible with ax , because
si ≥ fm ≥ fx
◮ thus OPT ∗ is an optimal solution, because |OPT ∗ | = |OPT |
© 2007 Antonio Carzaniga 16
Activity Selection is a Greedy Problem (2)
Optimal-substructure property: having chosen ax , let S ′ be the
set of activities in S compatible with ax , that is,
S ′ = {ai | si ≥ fx }
Prove: OPT ∗ = {ax } ∪ OPT ′ , where is optimal for S ′ if OPT ′ is
optimal for S
Proof: (by contradiction)
◮ assume to the contrary that |OPT ∗ | < |OPT |, and therefore
|OPT ′ | < |OPT | − 1
◮ let am be the earliest-finish activity in OPT , and let
S = {ai | si ≥ fm }
◮ by construction, OPT \ {am } is a solution for S
◮ by construction, S ⊆ S ′ , so OPT \ {am } is a solution also for S ′
◮ which means that there is a solution S ′ of size |OPT | − 1, which
contradicts the main assumption that |OPT ′ | < |OPT | − 1
© 2007 Antonio Carzaniga 17
Huffman Coding
Suppose you have a large sequence S of the six characters: ‘a’,
‘b’, ‘c’, ‘d’, ‘e’, and ‘f’
◮ e.g., n = |S| = 109
What is the most efficient way to store that sequence?
First approach: compact fixed-width encoding
◮ 6 symbols require 3 bits per symbol
◮ 3 × 109 /8 = 3.75 × 108 (a bit less than 400Mb)
Can we do better?
© 2007 Antonio Carzaniga 18
Huffman Coding (2)
Consider the following encoding table:
symbol code
a 000
b 001
c 010
d 011
e 100
f 101
Observation: the encoding of ‘e’ and ‘f’ is a bit redundant
◮ the second bit does not help us in distinguishing ‘e’ from ‘f’
◮ in other words, if the first (most significant) bit is 1, then the
second bit gives us no information, so it can be removed
© 2007 Antonio Carzaniga 19
Idea
Variable-length code
symbol code
a 000
b 001
c 010
d 011
e 10
f 11
Encoding and decoding are well-defined and unambiguous
How much space do we save?
◮ not knowing the frequency of ‘e’ and ‘f’, we can’t tell exactly
Given the frequencies fa , fb , fc , . . . of all the symbols in S
M = 3n(fa + fb + fc + fd ) + 2n(fe + ff )
© 2007 Antonio Carzaniga 20
Problem Definition
Given a set of symbols C and a frequency function
f : C → [0, 1]
Find a code E : C → {0, 1}∗ such that
E is a prefix code
◮ no codeword E(c1 ) is the prefix of another codeword E(c2 )
The average codeword size
X
B(S) = f (c)|E(c)|
c∈C
is minimal
© 2007 Antonio Carzaniga 21
Problem Definition (2)
E : C → {0, 1}∗ defines binary strings, so we can represent E
as a binary tree T
sym. freq. code 100
0 1
a 45% 000
b 13% 001 86 14
c 12% 010 0 1 0 1
d 16% 011
58 28 e:9 f:5
e 9% 10
0 1 0 1
f 5% 11
a:45 b:13 c:12 d:16
◮ leaves represent symbols; internal nodes are prefixes
◮ the code of a symbol c is the path from the root to c
◮ the weight f (v) of a node v is the frequency of its code/prefix
X X
B(S) = n f (c)depth(c) = n f (v)
c∈leaves(T ) v∈T
© 2007 Antonio Carzaniga 22
Huffman Algorithm
Huffman(C)
1 n = |C|
2 Q=C
3 for i = 1 to n − 1
4 create a new node z
5 z.left = Extract-Min(Q)
6 z.right = Extract-Min(Q)
7 f (z) = f (z.left) + f (z.right)
8 Insert(Q, z)
9 return Extract-Min(Q)
We build the code bottom-up
Each time we make the “greedy” choice of merging the two
least frequent nodes (symbols or prefixes)
© 2007 Antonio Carzaniga 23
Example
Huffman(C)
sym. freq. code
1 n = |C|
2 Q=C a 45% 0
3 for i = 1 to n − 1 b 13% 100
4 create a new node z c 12% 101
5 z. left = Extract-Min(Q) d 16% 110
6 z. right = Extract-Min(Q) e 9% 1110
7 f (z) = f (z. left) + f (z. right)
f 5% 1111
8 Insert(Q, z)
9 return Extract-Min(Q)
100 1
55 1
0 0 30 1
0 25 1 0 0 14 1
a:45 b:13 c:12 d:16 e:9 f:5
© 2007 Antonio Carzaniga 24
Dynamic Programming
© 2007 Antonio Carzaniga 25
Activity-Selection Problem
k
j
i
h
g
f
e
d
c
b
a
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14
© 2007 Antonio Carzaniga 26
Activity-Selection Problem
i
c
a
k
j
g
h
e
b
d
f
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14
Greedy choice: earliest finish time
© 2007 Antonio Carzaniga 27
Weighted Activity-Selection Problem
i 2
c 9
a 3
k 5
j 8
g 1
h 7
e 3
b 4
d 5
f 1
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14
Is the earliest-finish greedy choice still optimal?
Is any greedy choice optimal?
© 2007 Antonio Carzaniga 28
Case 1
i 2
c 9
a 3
k 5
j 8
g 1
h 7
e 3
b 4
d 5
f 1
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14
Case 1: activity i is in the optimal schedule
© 2007 Antonio Carzaniga 29
Case 2
i 2
c 9
a 3
k 5
j 8
g 1
h 7
e 3
b 4
d 5
f 1
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14
Case 2: activity i is not in the optimal schedule
© 2007 Antonio Carzaniga 30
Remember Bellman-Ford?
Given a graph G = (V , E) and a weight function w, we compute
the shortest distance Du (v), from u ∈ V to v ∈ V , using the
Bellman-Ford equation
Du (v) = min [w(u, x) + Dx (v)]
x∈Adj(u)
18 v
23
x3
6 x4 25
2
u 20
3
1
x2 x1
© 2007 Antonio Carzaniga 31
Shortest Paths on DAGs
Given a directed acyclic graph G = (V , E), this one with unit
weights, find the shortest distances to a given node
a f j
e b c g
h d i k
Considering V in topological order. . .
a b c d e f g h i j k
© 2007 Antonio Carzaniga 32
Shortest Paths on DAGs (2)
Considering V in topological order
Dx (k) = min [w(x, y) + Dy (k)]
y∈Adj(x)
a b c d e f g h i j k
3 3 2 3 ∞ 2 1 ∞ 1 ∞ 0
Since G is a DAG, computing Dy with y ∈ Adj(x) can be
considered a subproblem of computing Dx
◮ we build the solution bottom-up, storing the subproblem
solutions
© 2007 Antonio Carzaniga 33
Longest Increasing Subsequence
Given a sequence of numbers a1 , a2 , . . . , an , an increasing
subsequence is any subset ai1 , ai2 , . . . , aik such that
1 ≤ i1 < i2 < · · · < ik ≤ n, and such that
ai 1 < ai 2 < · · · < ai k
You must find the longest increasing subsequence
Example: find (one of) the longest increasing subsequence in
5 2 8 6 3 6 9 7
A maximal-length subsequence is
2 3 6 9
© 2007 Antonio Carzaniga 34
Longest Increasing Subsequence (2)
Intuition: let L(j) be the length of the longest subsequence
ending at aj
◮ e.g., in
5 2 8 6 3 6 9 7
we have
L(4) = 2
◮ this is our subproblem structure
Combining the subproblems
L(j) = 1 + max{L(i) | i < j ∧ ai < aj }
© 2007 Antonio Carzaniga 35
Dynamic Programming
First, the name “dynamic programming”
◮ does not mean writing a computer program
◮ term used in the 1950s, when “programming” meant “planning”
Problem domain
◮ typically optimization problems
◮ longest sequence, shortest path, etc.
General strategy
◮ decompose a problem in (smaller) subproblems
◮ must satisfy the optimal substructure property
◮ subproblems may overlap (indeed they should overlap!)
◮ solve the subproblems
◮ derive the solution from (one of) the solutions to the
subproblems
© 2007 Antonio Carzaniga 36
Examples
Unweighted shortest path: given G = (V , E), find the length of
the shortest path from u to v
◮ decompose u ⇝ v into u ⇝ w ⇝ v
◮ easy to prove that, if u ⇝ w ⇝ v is minimal, then w ⇝ v is
also minimal
◮ this is the optimal substructure property
Unweighted longest simple path: given G = (V , E), find the
length, simple (i.e., no cycles) path from u to v
◮ we can also decompose u ⇝ v into u ⇝ w ⇝ v
◮ however, we can not prove that, if u ⇝ w ⇝ v is maximal, then
w ⇝ v is also maximal
◮ exercise: find a counter-example
© 2007 Antonio Carzaniga 37
Dyn. Prog. vs. Divide-and-Conquer
Divide-and-conquer is also about decomposing a problem into
subproblems
Divide-and-conquer works by breaking the problem into
significantly smaller subproblems
◮ in dynamic programming, it is typical to reduce L(j) into
L(j − 1)
◮ this is one reason why recursion does not work so well for
dynamic programming
Divide-and-conquer splits the problem into independent
subproblems
◮ in dynamic programming, subproblems typically overlap
◮ pretty much the same argument as above
© 2007 Antonio Carzaniga 38
Dyn. Prog. vs. Greedy Algorithms
The greedy strategy requires (and exploits) the greedy-choice
property
◮ greedy does not have to look at more than one subproblem
◮ the greedy choice is typically made before proceeding to solve
the subproblem
◮ there is no need to store the result of each subproblem
Dynamic programming works without the greedy-choice
property
◮ it must look at several subproblems, and “dynamically” choose
one of them to come up with a global solution
◮ the solution is typically assembled bottom-up
◮ the solutions of the subproblems are typically reused
© 2007 Antonio Carzaniga 39
Typical Subproblem Structures
Prefix/suffix subproblems
◮ Input: x1 , x2 , . . . , xn
◮ Subproblem: x1 , x2 , . . . , xi , with i < n
◮ O(n) subproblems
Subsequence subproblems
◮ Input: x1 , x2 , . . . , xn
◮ Subproblem: xi , xi+1 , . . . , xj , with 1 ≤ i < j ≤ n
◮ O(n2 ) subproblems
© 2007 Antonio Carzaniga 40
Edit Distance
Given two strings x and y, find the smallest set of edit
operations that transform x into y
◮ edit operations: delete, insert, and modify a single character
◮ very important applications
◮ spell checker
◮ DNA sequencing
Example: transform “Carzaniga” into “Jazayeri”
⇓ − ⇓ + + − −
J y e r
C a r z a n i g a
J a z a y e r i
© 2007 Antonio Carzaniga 41
Edit Distance (2)
Align the two strings x and y, possibly inserting “gaps”
between letters
◮ a gap in the source means insertion
◮ a gap in the destination means deletion
◮ two different character in the same position means
modification
Many alignments are possible; the alignment with the smallest
number of insertions, deletions, and modifications defines the
edit distance
So, how do we solve this problem?
What are the subproblems?
© 2007 Antonio Carzaniga 42
Edit Distance (3)
Idea: consider a prefix of x and a prefix of y
Let E(i, j) be the smallest set of changes that turn the first i
characters of x into the first j characters of y
Now, the last column of the alignment of E(i, j) can have either
◮ a gap for x (i.e., insertion)
◮ a gap for y (i.e., deletion)
◮ no gaps (i.e., modification iff x[i] 6= y[j])
This suggests a way to combine the subproblems; let
diff (i, j) = 1 iff x[i] 6= y[j] or 0 otherwise
E(i, j) = min{1 + E(i − 1, j),
1 + E(i, j − 1),
diff (i, j) + E(i − 1, j − 1)}
© 2007 Antonio Carzaniga 43
Knapsack
Problem definition
◮ Input: a set of n objects with their weights w1 , w2 , . . . wn and
their values v1 , v2 , . . . vn , and a maximum weight W
P
◮ Output: a Psubset K of the objects such that i∈K wi ≤ W and
such that i∈K vi is maximal
Dynamic-programming solution
◮ let K(w, j) be the maximum value achievable at maximum
capacity w using the first j items (i.e., items 1 . . . j)
◮ considering the jth element, we can either “use it or loose it,”
so
K(w, j) = max{K(w − wj , j − 1) + vj , K(w, j − 1)}
© 2007 Antonio Carzaniga 44
Recursion?
The breakdown of a problem into subproblem suggests the
use of a recursive function. Is that a good idea?
◮ No! As we already said, recursion doesn’t quite work here
◮ Why?
Remember Fibonacci?
Fibonacci(n)
1 if n = = 0
2 return 0
3 elseif n = = 1
4 return 1
5 else return Fibonacci(n − 1) + Fibonacci(n − 2)
Recursion tries to solve the same problem over and over again
© 2007 Antonio Carzaniga 45
Memoization
Problem: recursion solves the same problems repeatedly
Idea: “cache” the results
Fibonacci(n)
1 if n = = 0
2 return 0
3 elseif n = = 1
4 return 1
5 elseif (n, x) ∈ H // a hash table H “caches” results
6 return x
7 else x = Fibonacci(n − 1) + Fibonacci(n − 2)
8 Insert(H, n, x)
9 return x
Idea also known as memoization
© 2007 Antonio Carzaniga 46
Complexity
What is the general complexity of the greedy strategy
1. start with the greedy choice
2. add the solution to the remaining subproblem
A nice tail-recursive algorithm
◮ the complexity of the greedy strategy per-se is Θ(n)
Contrast this with the dynamic programming strategy
1. break down the problem in subproblems—O(1), O(n), O(n2 ),
. . . subproblems
2. you solve the main problem by choosing one of the
subproblems
3. in practice, solve the subproblems bottom-up
© 2007 Antonio Carzaniga 47
Exercise
Puzzle 0: is it possible to insert some ‘+’ signs in the string
“213478” so that the resulting expression would equal 214?
◮ Yes, because 2 + 134 + 78 = 214
Puzzle 1: is it possible to insert some ‘+’ signs in the strings
of digits to obtain the corresponding target number?
digits target
646805736141599100791159198 472004
6152732017763987430884029264512187586207273294807 560351
48796142803774467559157928 326306
195961521219109124054410617072018922584281838218 7779515
© 2007 Antonio Carzaniga 48