confusion about rod cutting algorithm - dynamic programming - algorithm

I recently saw a rod cutting problem, where B(i) = optimal price for cutting a rod of length i units and p(i) = price of a rod of length i units.
The algorithm given is something like this:
B(i) = max(1<=k<=i) {p(k) + B(i-k)}
Shouldn't it be something like this:
B(i) = max(1<=k<=floor(i/2)) {B(k) + B(i-k)}
where B(1) = p(1);
so that both parts 've the optimal cost instead of cost for a single rod for one part and optimal cost for the second part.
for example: B(4) = max{ (B(1) + B(3)); (B(2) + B(2)) }
instead of max{ (p(1) + B(3)); (p(2) + B(2)); (p(3) + B(1)) }
Can someone please explain this?

Actually the formula is correct. You have B(i) = max(1<=k<=i) {p(k) + B(i-k)}. Let's assume you have a rope of length i. If you are to cut it then you will cut a piece of length k where k is between 1 and i and will go on cutting the remaining part of the rope. So overall it costs you p(k)(price to cut the initial part that you decided you will not cut anymore) and the price to cut the remaining B(i-k). This is precisely what the formula does.
Your solution will also do the job but it has a slight drawback - the solution for each subproblem depends on the solution of two(instead of one) simpler subproblems. I believe because of that it will perform worse on the average. Of course having a subproblem depend on several simpler problems is not forbidden or wrong.

Let us assume that the optimal price of the rod of length i will be obtained by cutting the rod into p parts of length l1, l2, .., lp such that i= l1+ l2 +..+ lp and l1<l2<l3<…<lp (for simplicity).
There exists a rod piece of length l1 in the optimal solution means that if the rod piece of length l1 is further broken into smaller pieces, then the price of the rod piece of length l1 will decrease. Hence for a rod piece of length l1, we can say that b[l1] = p[l1]. Similarly we have established, b[l2] = p[l2], b[l3]= p[l3], ….., b[lp]= p[lp]. => b(i) = b(l1) + b(l2) +..+ b(lp) is optimal………………..Condition 1
Now consider the case of rod of length l1+l2. The claim is b(l1+l2) = b(l1) + b(l2) is optimal. Let us assume it is not the case. There exists an L such that b(l1+l2) = b(L) + b(l1+l2-L) is optimal. It means that there exists rods of length L and (l1+l2-L) such that:
b(L) + b(l1+l2-L)>b(l1)+b(l2).
=> b(l1) + b(l2) + b(l3) +..+ b(lp) < b(L) + b(l1+l2-L) +b(l3) +…+ b(lp).
=> Which is a contradiction { See Condition 1}
=> b(l1+l2) = b(l1) + b(l2) is optimal
=> Similarly b(l2+l3+l4) = b(l2) + b(l3) + b(l4) is optimal and so on.
Now we have a recurrence b(i) = b(k) + b(i-k) for 1<=k<i.
For k=l1, b(i) = b(l1) + b(i-l1) = p[l1] + b(i-l1).
For k=l1+l2, b(i) = b(l1+l2) + b(i-l1-l2)
= b(l1+l2) + b(l3 + l4 +…+lp)
= [b(l1) + b(l2)] + b(l3 + l4 +…+lp)
= b(l1) + [b(l2) + b(l3 + l4 +…+lp)]
= b(l1) + b(l2+l3+l4+…+lp)
= b(l1) + b(i-l1)
= p[l1] + b(i-l1)
Or for k= l1+l2, b(i) = p[k’] + b(i-k’) where k’=l1.
So to conclude, if we want to find optimal solution of a rod of length i, we try to break the rod of length i into 2 parts of length (l1+l2) and (i-l1+l2) and then we recursively find optimal solutions of the two rod pieces, we end up finding an optimal rod piece of length l1 and optimal solution of rod of length i-l1. Thus we can say:
b(i) = b(k) + b(i-k ) = p[k’] + b(i-k’) for 1<=k,k’<i.

The formula is correct. I think the confusion arises when we think of both formulas to be replacement of the other.
Though they count the same phenomena, it is done in two different ways:
Let, B(i) = optimal price for cutting a rod of length i units and
p(i) = price of a rod of length i units.
Formula 1: B(i) = max(1<=k<=floor(i/2)) {B(k) + B(i-k)} and P(i)
Formula 2: B(i) = max(1<=k<=i) {p(k) + B(i-k)})
Consider a rod of length 4,
it can be cut in the following ways :
1) uncut of length 4
2) 3, 1
3) 2, 2
4) 2, 1, 1
5) 1, 3
6) 1, 2, 1
7) 1, 1, 2
8) 1, 1, 1, 1
According to Formula 1:
option 1 corresponds to P(4)
option 2,5,6,7,8 corresponds to B(1) + B(3)
option 3,4,6,7,8 corresponds to B(2) + B(2)
According to Formula 2:
option 1 corresponds to P(4)
option 2 corresponds to P(3) + B(1)
option 3,4 corresponds to P(2) + B(2)
option 5,6,7,8 corresponds to P(1) + B(3)
So to conclude, 1 and 2 are counting the optimal solution but in different ways, where 2 is more compact and makes lesser recursive calls compared to 1.

Related

Recursive Solution for Rod Cutting problem - dynamic programming

Problem Statement: Given a rod of length n inches and an array of
prices that includes prices of all pieces of size smaller than n.
Determine the maximum value obtainable by cutting up the rod and
selling the pieces.
For this problem, I am confused as to why everywhere I see the solution to this problem i.e. the maximum value of the Rod defined as
R[n] = Max (p[n], R[n-1] + P[1], R[n-2] + P[2] + ... P[1] + R[n-1] --- 1
and not as
R[n] = Max (p[n], R[n-1] + R[1], R[n-2] + R[2] + ... R[1] + R[n-1] --- 2
where R[n] means the maximum revenue that we can get by selling n rods.
Base case as:
R[0] = some value
R[1] = somevalue
The eq 2 is more correct and apt because at no point R[i] will ever be less than P[i].
What am I missing?
Both equations give the same answer. In that sense none of them is more correct than the other. It is a matter of taste which one you prefer. I found eq 1 a bit more intuitive. The solution is the maximum of taking the whole rod, or cutting off a piece of length 1 and do the best with the rest, or cutting off a piece of length 2 and do the best with the rest, ...

Solve recurrence relation in which there is a separate relation for even and odd values

Can someone help me how to solve these type of questions? What kind of approach should I follow?
Looking over the question, since you will be asked to
evaluate the recurrence lots of times
for very large inputs,
you will likely need to either
find a closed-form solution to the recurrence, or
find a way to evaluate the nth term of the recurrence in sublinear time.
The question, now, is how to do this. Let's take a look at the recurrence, which was defined as
f(1) = f(2) = 1,
f(n+2) = 3f(n) if n is odd, and
f(n+2) = 2f(n+1) - f(n) + 2 if n is even.
Let's start off by just exploring the recurrence to see if any patterns arise. Something that stands out here - the odd terms of this recurrence only depend on other odd terms in the recurrence. This means that we can imagine trying to split this recurrence into two smaller recurrences: one that purely deals with the odd terms, and one that purely deals with the even terms. Let's have D(n) be the sequence of the odd terms, and E(n) be the sequence of the even terms. Then we have
D(1) = 1
D(n+2) = 3D(n)
We only need to evaluate D on odd numbers, so we can play around with that to see if a pattern emerges:
D(2·0 + 1) = 1 = 30
D(2·1 + 1) = 3 = 31
D(2·2 + 1) = 9 = 32
D(2·3 + 1) = 27 = 33
The pattern here is that D(2n+1) = 3n. And hey, that's great news! That means that we have a direct way of computing D(2n+1).
With that in mind, notice that E(n) is defined as
E(2) = 1 = D(1)
E(n+2) = 2D(n+1) - E(n) + 2
Remember that we know the exact value of D(n+1), which is going to make our lives a lot easier. Let's see what happens if we iterate on this recurrence a bit. For example, notice that
E(8)
= 2D(7) - E(6) + 2
= 2D(7) + 2 - (2D(5) - E(4) + 2)
= 2D(7) - 2D(5) + E(4)
= 2D(7) - 2D(5) + (2D(3) - E(2) + 2)
= 2D(7) - 2D(5) + 2D(3) + 2 - D(1)
= 2D(7) - 2D(5) + 2D(3) - D(1) + 2
Okay... that's really, really interesting. It seems like we're getting an alternating sum of the D recurrence, where we alternate between including and excluding 2. At this point, if I had to make a guess, I'd say that the way to solve this recurrence is going to be to think about subdividing the even case further into cases where the inputs are 2n for an even n and 2n for an odd n. In fact, notice that if the input is 2n for even n, then there won't be a +2 term at the end (all the +2's are balanced out by -2's), whereas if the input is odd, then there will be a +2 term at the end (all the +2's are balanced out by -2's).
Now, let's turn to a different aspect of the problem. You weren't asked to query for individual terms of the recurrence. You were asked to query for the sum of the recurrence, evaluated over a range of inputs. The fact that we're getting alternating sums and differences of the D terms here is really, really interesting. For example, what is f(10) + f(11) + f(12)? Well, we know that f(11) = D(11), which we can compute directly. And we also know that f(10) and f(12) are E(10) and E(12). And watch what happens if we evalute E(10) + E(12):
E(10) + E(12)
= (D(9) - D(7) + D(5) - D(3) + D(1) + 2) + (D(11) - D(9) + D(7) - D(5) + D(3) - D(1))
= D(11) + (D(9) - D(9)) + (D(7) - D(7)) + (D(5) - D(5)) + (D(3) - D(3)) + (D(1) - D(1)) + 2
= D(11) + 2.
Now that's interesting. Notice that all of the terms have cancelled out except for the D(11) term and the +2 term! More generally, this might lead us to guess that there's some rule about how to simplify E(n+2) + E(n). In fact, there is. Specifically:
E(2n) + E(2n+2) = D(2n+1) + 2
This means that if we're summing up lots of consecutive values in a range, every pair of adjacent even terms will simplify instantly to something of the form D(2n+1) + 2.
There's still some more work to be done here. For example, you'll need to be able to sum up enormous numbers of D(n) terms, and you'll need to factor in the effects of all the +2 terms. I'll leave those to you to figure out.
One hint: all the values you're asked to return are modulo some number P. This means that the sequence of values 0, D(1), D(1) + D(3), D(1) + D(3) + D(5), D(1) + D(3) + D(5) + D(7), etc. eventually has to reach 0 again (mod P). You can both compute how many terms have to happen before this occurs and write down all the values encountered when doing this by just computing these values explicitly. That will enable you to sum up huge numbers of consecutive D terms in a row - you can mod the number of terms by the length of the cycle, then look up the residual sum in the table.
Hope this helps!

Algorithm that uses second powers of linear series

I'm not quite sure if it should come here or on mathematics stack exchange, posting here to find more practical cases.
Is there any formula / algorithm that uses second powers of linear series?
Meaning: a(1)^2 + a(2)^2 + a(3)^2 + ... + a(n)^2
Where a(n) is linear series.
Let a_k = a_0 + d°(k-1)
Then: (I use ° for multiplication)
sum(a_k^2) = sum( (a_0 + d°(k-1))^2) =sum( a_0^2 + d°d°(k-1)^2 + 2°d°(k-1)) = n°a_0°a_0 + d°d°sum((k-1)^2) + 2°d°sum(k-1)
(The sum goes from 1 to n)
We know that sum(k) = n°(n+1)/2, and sum(k^2)=n°(n+1)°(2n+1)/6
Therefore the above
sum(a_k^2) = n°a_0°a_0 + d°d°(n-1)°n°(2n-1)/6 + 2°(n-1)°n/2
Which can be simplified a little more, and be calculated in constant time.

Find price for Rod cutting

Given Length of Rod and P (Price ) for the first 3 rods. We are to fill in the possible price we can get for the rest of rods. Assuming we can cut the longer pieces as needed.
L = 1 2 3 4 5 6 7 8
p = 3 8 12
We basically want to get the maximum price we can get for each missing length price.
My approach
I believe that since we are given the best possible price for a rod of length 1,2, and 3 we can generate all possible combinations for the next rods.
For example to get price of rod where L = 4
price of rod where L = 1 + rod where L = 3 = 15
price of rod where L = 2 + rode where L = 2 = 16
Therefore price of rod wehre L = 4 = 16 since 16 > 15.
For example to get price of rod where L = 5
price of rod where L = 1 + rod where L = 2 and rod where L = 2 = 19
price of rod where L = 3 + rod where L = 2 = 20
price of rod where L = 4 + rod where L = 1 = 19
So this is kind of the approach i am following. However I am not sure if i am correct. I would also like it if someone can verify this approach and also maybe help me derive a formula from this. I am not looking for code as understanding the problem is enough to write the code.
You can check the explanation of a variation of this problem in CLRS (section 15.1, page 360). The problem is called the Rod Cutting problem.
Your approach is correct, and you can formalize it as a recurrence relation.
f(n) = min(f(n - i) + price(i)). 1 <= i <= n - 1
where f(n) is the minimum price to buy a rod of length n.
using memoization, this can be calculated in O(n^2).
Your approach is correct.
It can also be done in another way as answered by MrGreen (https://stackoverflow.com/a/29352580/13106102)
Let, B(i) = optimal price for cutting a rod of length i units and p(i) = price of a rod of length i units.
Formula 1: B(i) = max(1<=k<=floor(i/2)) {B(k) + B(i-k)} and P(i)
Formula 2: B(i) = max(1<=k<=i) {p(k) + B(i-k)})
Consider a rod of length 4, it can be cut in the following ways :
1) uncut of length 4
2) 3, 1
3) 2, 2
4) 2, 1, 1
5) 1, 3
6) 1, 2, 1
7) 1, 1, 2
8) 1, 1, 1, 1
According to Formula 1:
option 1 corresponds to P(4)
option 2,5,6,7,8 corresponds to B(1) + B(3)
option 3,4,6,7,8 corresponds to B(2) + B(2)
According to Formula 2:
option 1 corresponds to P(4)
option 2 corresponds to P(3) + B(1)
option 3,4 corresponds to P(2) + B(2)
option 5,6,7,8 corresponds to P(1) + B(3)
So to conclude, 1 and 2 are counting the optimal solution but in different ways, where 2 is more compact and makes lesser recursive calls compared to 1.

Simpler recurrence of Dynamic Programming Rod-cutting

In CLRS, the recurrence solution to the rod cutting problem is:
rn = max (pn, r1+rn-1,...,rn-1+r1)
This recurrence is pretty clear and I understood it.
However, I am facing difficulty in understanding the simpler version of this recurrence provided in the book, which is:
rn = max1<=i<=n(pi + rn-i) , where pi is the cost of piece of length i.
I don't understand, how this recurrence is similar to the first recurrence. To me the second recurrence may miss the optimal solution as we are not considering the optimal cost of first cut (we are simply taking it's normal price).
Shouldn't we always consider the optimize cost of the both sides like the first equation?
Here is the reasoning.
An optimal cut must include a piece of some length i. That piece will be sold for price pi. You will then cut the rest of the rod into other pieces, and can do no better than to cut it optimally.
Therefore we just need to find ONE of the pieces in the cut. Recursion will take care of figuring out the rest.
And that is exactly what the simpler recurrence does.
Though this reply is late. I anyway thought of posting it because I got confused along the same lines.
I think the confusion arises when we think of both formulas to be replacement of the other.
Though they count the same phenomena, it is done in two different ways:
Let, B(i) = optimal price for cutting a rod of length i units and p(i) = price of a rod of length i units.
Formula 1: B(i) = max(1<=k<=floor(i/2)) {B(k) + B(i-k)} and P(i)
Formula 2: B(i) = max(1<=k<=i) {p(k) + B(i-k)})
Consider a rod of length 4, it can be cut in the following ways :
1) uncut of length 4
2) 3, 1
3) 2, 2
4) 2, 1, 1
5) 1, 3
6) 1, 2, 1
7) 1, 1, 2
8) 1, 1, 1, 1
According to Formula 1:
option 1 corresponds to P(4)
option 2,5,6,7,8 corresponds to B(1) + B(3)
option 3,4,6,7,8 corresponds to B(2) + B(2)
According to Formula 2:
option 1 corresponds to P(4)
option 2 corresponds to P(3) + B(1)
option 3,4 corresponds to P(2) + B(2)
option 5,6,7,8 corresponds to P(1) + B(3)
So to conclude, 1 and 2 are counting the optimal solution but in different ways, where 2 is more compact and makes lesser recursive calls compared to 1.
In addition to the explanations given by the others, I would like to point out that the second recursion actually eliminates the common rod cutting sub-problems, such as the rutting a rod of size n=4 at either position i=1 or i=3, i.e., cutting off a one-unit piece from either end.

Resources