Rod Cutting Educative

Download as pdf or txt
Download as pdf or txt
You are on page 1of 6

Ask a Question

Back To Course Home

Dynamic Programming in
Python: Optimizing Programs
for Efficiency

0% completed

Search Course

Chapter 1: From
Recursion to Dynamic
Programming
Introduction

What is Recursion?

Thinking Recursively

The Fibonacci Numbers

Challenge: Find All Permutations of


a String

Solution Review: Find All


Permutations of a String

Challenge: Place N Queens on an


NxN Chessboard

Solution Review: Place N Queens on


an NxN Chessboard

Is Plain Recursion Good Enough?

What is Dynamic Programming?

Approaches of Dynamic
Programming

Where to Use Dynamic


Programming

Quiz

Chapter 2: Top-Down
Dynamic Programming
with Memoization
What is Memoization?

The Fibonacci Numbers Algorithm


with Memoization

Challenge: The Staircase Problem

Solution Review: The Staircase


Problem

Challenge 2: The Knapsack Problem

Solution Review: The Knapsack


Problem

Quiz

Chapter 3: Bottom-Up
Ask a Question

Solution Review: The Rod Cutting


Problem
In this lesson, we will look at different algorithms to solve the rod cutting problem we
saw in the last lesson.

We'll cover the following

• Solution 1: Simple recursion


• Explanation
• Time complexity
• Solution 2: Top-down dynamic programming
• Optimal substructure
• Overlapping subproblems
• Explanation
• Time and space complexity
• Solution 3: Bottom-up dynamic programming
• Explanation
• Time and space complexity

Solution 1: Simple recursion


1 def rodCutting(n, prices):
2 if n<0:
3 return 0
4 max_val = 0
5 for i in range(1,n+1):
6 max_val = max(max_val, prices[i-1] + rodCutting(n - i, prices))
7 return max_val
8
9 print(rodCutting(3, [3,7,8]))

Run Save Reset

Explanation
The idea of this algorithm is to exhaustively find the most optimal cuts
from every combination of cuts. We do this by making recursive calls
with all possible values of length and choosing those that give us the
highest revenue (lines 5-7).

The crux of this algorithm is in line 6. We make recursive calls for each
possible length of the piece (i); the updated value of n now is i units
smaller. Once this result is evaluated, we add this length’s price and find
the max.

The visualization below shows a dry run of this algorithm.


Ask a Question

We can make cuts at 3 different points

5 of 15

Time complexity
Can you think of the number of combinations of cuts for a rod of length
n? It is 2n−1 ! For a rod of length n, at each position, we have two choices.
Either we can make a cut, or we can leave it as it is. All combinations are
bounded by O(2^n) as is the time complexity of this solution.

Solution 2: Top-down dynamic


programming
Let’s see if this problem satisfies both the properties of dynamic
programming.

Optimal substructure
We want to find the optimal answer for a rod of length n, and we have
optimal answers to all the subproblems, i.e., rods of length n-1, n-2, … , 2,
1. We can find the maximum of all the subproblem’s results plus the
price of the rod length that remains along with that subproblem. The
following would be the equation for finding the optimal cut’s revenue
for a rod of length n.

RC(n) = max(RC(n − 1) + price(1), RC(n − 2) +


price(2)  ...  RC(1) + price(n − 1))

Thus, if we have answers to the subproblems of rods of length n-1, n-2 …


2 and 1, we can construct the solution for the rod of length n by only
using these results.

Overlapping subproblems
By looking at the visualization above, you can already see one
overlapping subproblem. For bigger inputs, this overlap will increase
substantially.
substantially.
Ask a Question

r=3 r=7 r=8

revenue = 8

r=3 r=3 r=3 r=7 r=7 r=3

revenue = 10 revenue = 10

r=3r=3 r=3

revenue = 9

Let's try to find some overlapping subproblems.

1 of 3

This calls for the memoization of results! Let’s look at the top-down
implementation of this algorithm.

1 def rodCutting_(n, prices, memo):


2 if n<0:
3 return 0
4 if n in memo:
5 return memo[n]
6 max_val = 0
7 for i in range(1,n+1):
8 max_val = max(max_val, prices[i-1] + rodCutting_(n - i, prices, memo))
9 memo[n] = max_val
10 return memo[n]
11
12 def rodCutting(n, prices):
13 memo = {}
14 return rodCutting_(n, prices, memo)
15
16 print(rodCutting(3, [3,7,8]))

Run Save Reset

Explanation
You have seen this many times now: there’s nothing fancy here! Before
evaluating a result, we check if it is already computed and available in
the memo (lines 4-5); in this case, we do not need to evaluate it. If we have
to evaluate it, we simply store results in the memo for future reuse (line 9).

Time and space complexity


Each problem depends on the smaller subproblems; to evaluate
rodCutting(n), we need the answer to rodCutting(n-1), rodCutting(n-2),

and so on until . Thus, the time complexity would be O(n2 )


and so on until rodCutting(1). Thus, the time complexity would be O(n2 ).
Ask a Question
Moreover, we can only have n unique subproblems, making the space
complexity of this algorithm O(n).

Solution 3: Bottom-up dynamic


programming
1 def rodCutting(n, prices):
2 # Create a dp array the size of (n+1)
3 dp = [0 for _ in range(n + 1)]
4 # starting from rod of length 1, find optimal answer to all subproblems
5 for i in range(1, n + 1):
6 max_val = 0
7 # for a rod of length i, we can find what cuts give max answer since we have answe
8 for j in range(i):
9 max_val = max(max_val, prices[j]+dp[i-j-1])
10 dp[i] = max_val
11 # return answer to n length rod
12 return dp[n]
13
14 print(rodCutting(3, [3,7,8]))
15

Run Save Reset

Explanation
The idea is to start building from the case of a rod of length 1, and then
use these results to solve the problems for bigger lengths. The solution to
a problem of the rod of length n would not require answers to the
problems of rods greater in length than n. Therefore, the for loop at line
eight only iterates until i, which is any given length of the rod up to n.
We make every possible cut, and for the remaining rod length, we would
already have the solution in dp. Thus, we choose the cut that gives the
highest possible answers (line 10).

Look at the following visualization for an understanding of this


algorithm.
rodCutting(3, [3,7,8])
Ask a Question 1 of 25

Time and space complexity


Similar to the top-down solution, the time complexity here would be
quadratic. You can sense this from nested for loops as well. The intuitive
reasoning behind this is that to construct an optimal answer to any
subproblem, you require optimal solutions to all the smaller
subproblems. Thus, the time complexity becomes O(n2 ). Moreover, since
there are n possible subproblems, the size of the tabulation table, dp,
would be n, making the space complexity O(n).

In the next lesson, you will solve another coding challenge.

Back Next

Challenge: The Rod Cutting Problem Challenge: Weighted Scheduling Problem

Mark as Completed

Report an Issue

You might also like