From pseudo-code to python
Recursive top-down implementation
p = [0, 1, 5, 8, 9, 10, 17, 17, 20, 24, 30]
def cut_rod(p, n):
if n == 0:
return 0
q = p[0]
for i in range(1, n+1):
q = max(q, p[i] + cut_rod(p, n-i))
return q
res = cut_rod(p, 4)
print(res)
Memoized cut rod
def memoized_cut_rod(p, n):
r = [-1 for _ in range(n + 1)]
return memoized_cut_rod_aux(p, n, r)
def memoized_cut_rod_aux(p, n, r):
if r[n] >= 0:
return r[n]
q = p[0]
if n == 0:
q = 0
else:
for i in range(1, n + 1):
q = max(q, p[i] + memoized_cut_rod_aux(p, n - i, r))
r[n] = q
return q
res = memoized_cut_rod(p, 4)
print(res)
Bottom up cut rod
def bottom_up_cut_rod(p, n):
r = [0 for _ in range(n + 1)]
for j in range(1, n + 1):
q = p[0]
for i in range(1, j + 1):
q = max(q, p[i] + r[j - i])
r[j] = q
return r[n]
res = bottom_up_cut_rod(p, 4)
print(res)
15.1-1
Show that equation (15.4) follows from equation (15.3) and the initial condition .
Binomial of one variable refer here counts the number of calls (including recursive calls) due to the call CUT-ROD. It also means how many ways we can cut the rod.
Let so we can get
Now we want to run how many ways to cut the rod from until . This recursion tree has
incase I forgot, the sum of power of 2 is a geometric series
15.1-2
Show, by means of a counterexample, that the following “greedy” strategy does not always determine an optimal way to cut rods. Define the density of a rod of length to be , that is, its value per inch. The greedy strategy for a rod of length cuts off a first piece of length , where , having maximum density. It then continues by applying the greedy strategy to the remaining piece of length .
15.1-3
Consider a modification of the rod-cutting problem in which, in addition to a price for each rod, each cut incurs a fixed cost of . The revenue associated with a solution is now the sum of the prices of the pieces minus the costs of making the cuts. Give a dynamic-programming algorithm to solve this modified problem.
def bottom_up_cut_rod(p, n, c):
r = [0 for _ in range(n + 1)]
for j in range(1, n + 1):
q = p[0]
for i in range(1, j + 1):
q = max(q, p[i] + r[j - i] - c)
r[j] = q
return r[n]
res = bottom_up_cut_rod(p, 4, 0.5)
print(res)
15.1-4
Modify MEMOIZED-CUT-ROD to return not only the value but the actual solution, too.
15.1-5
The Fibonacci numbers are defined by recurrence (3.22). Give an -time dynamic programming algorithm to compute the th Fibonacci number. Draw the subproblem graph. How many vertices and edges are in the graph?
def fibonacci_dynamic(n):
a, b = 0, 1
while n > 0:
a, b = b, a + b
n -= 1
return a
res = fibonacci_dynamic(8)
print(res)