1
$\begingroup$

I have tried researching how I can handle multiple optimal solutions based using dynamic programming. The answer is found from this question is simply that you have to backtrack. What if this is not possible and one of my solutions can't be found this way?

From this YouTube video we are given the problem of finding the optimal rod cuttings for maximizing profit.

The rod has a length of $n=5$, and the possible ways to cut with its respective values in parenthesis are $1(2)$, $2(5)$, $3(7)$ and $4(8)$. By setting up a matrix as in the video we end up finding that the optimal solution is $12$. By backtracking this we are only able to find one of the solutions $1,2,2$ and not the other solution consisting of $2,3$.

My question is, how can I combine dynamic programming with some sort of best sequence sum algorithm so that I am able to backtrack both solutions? The algorithm he proposes uses the max of the previous subproblem, however, that might not be the only solution as a combination of the current subproblem might also be feasible.

The matrix proposed in the video looks like this (rows are the possible cuts and columns are the rod length): $$ \begin{bmatrix} 0 & 2 & 4 & 6 & 8 & 10 \\ 0 & 2 & 5 & 7 & 10 & 12 \\ 0 & 2 & 5 & 7 & 10 & 12 \\ 0 & 2 & 5 & 7 & 10 & 12 \\ \end{bmatrix} $$

$\endgroup$
1
$\begingroup$

Assume you already computed the dynamic programming table DP[SIZE][LENGTH] where DP[s][l] stands for maximum profit that can be obtained by using cuts up to size s on a rod of length l. You want to find all decomposition to get the value DP[SIZE][LENGTH], to do this notice that at every step DP[s][l] we have two options, use the cut of size s or don't use it (possibly using both values we get optimal answer). The pseudo code will look like this:

PROFIT[s] = value of using a cut of size `s`.

def find_answers(s, l, partial_answer):
    """ Populate in `partial_answer` possible ways to
        partition a rod of length `l` using cuts of
        size up to `s` and report them. 

        `partial_answer` is a multiset that will contain all cuts
        done so far.
    """

    # Base case when length is `0`.
    if l == 0:
        report partial_answer

    best = DP[s][l]

    # If not using the cut of size `s` gets a profit as good
    # as best expected profit, find solutions.
    if DP[s - 1][l] == best:
        find_answers(s - 1, l, partial_answer)

    # Try to find an answer that uses current cut size if `s` is
    # less than current length, and profit using this cut is as good
    # as best expected profit.
    if s <= l and DP[s][l - s] + PROFIT[s] == best:
        find_answers(s, l - s, partial_answer + {s})

Call this function like find_answers(SIZE, LENGTH, {}) with an empty multi-set as partial_answer. Since it is doing backtracking it is possible to get to the same state (s, l) several times with different partial_answers. This function will call report partial_answer exactly once per valid decomposition, also notice that the number of optimal decomposition can be exponentially large.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.