Lukas' Notes

Definition

Two-Bag Knapsack Dynamic Programming Algorithm

For the Two-Bag Knapsack decision problem, process indexed items one at a time. Store the greatest profit achievable for each pair of exact bag weights:

An unreachable state has value . Each item is skipped, placed in bag 1, or placed in bag 2. Accept precisely when some final state satisfies

This dynamic programme is pseudopolynomial and becomes polynomial when the input integers are encoded in unary, including for signed weights.

State space and recurrence

Bound every reachable weight, not just the final capacities

Define

Every subset of items has total weight in the integer interval . Thus each bag needs possible weight indices. Negative indices can be stored at array offset .

With signed weights, an intermediate weight above a capacity may later fall below it. For weights and capacity , selecting both gives a feasible final weight despite the intermediate weight .

Therefore the signed-weight algorithm applies the capacity bounds only when examining the final layer. It does not discard intermediate states merely for exceeding or .

Keep the best profit for each exact weight pair

Initialise and every other state to . For ,

A lookup outside returns , and . Each transition reads the previous layer, so even zero-weight items cannot be reused.

Two partial assignments with the same exact weights leave identical choices for the remaining items. Keeping only the greater profit cannot destroy a solution: every continuation adds the same weights and profit to either assignment.

Pseudocode

L = sum(min(w[i], 0) for i = 1,...,r)
U = sum(max(w[i], 0) for i = 1,...,r)
previous[a,b] = -infinity for all a,b in [L,U]
previous[0,0] = 0
 
for i = 1,...,r:
    current[a,b] = -infinity for all a,b in [L,U]
    for a,b in [L,U]:
        current[a,b] = max(
            previous[a,b],
            lookup(previous, a-w[i], b) + p[i],
            lookup(previous, a, b-w[i]) + p[i]
        )
    previous = current
 
return any(previous[a,b] >= t
           for a,b in [L,U] with a <= W1 and b <= W2)

Here lookup returns outside the table. The two arrays are separate layers; after swapping them, the next output layer is reinitialised.

Correctness

The table has the stated meaning at every layer

Base layer

With no items, the only assignment has weights and profit . Every other exact weight pair is unreachable, matching .

Exhaust all assignments by the last item's destination

Assume layer is correct. Every assignment of the first items places item in exactly one of the three destinations. Removing it produces the predecessor weights in the corresponding recurrence term. Its profit is the predecessor profit plus if selected, or unchanged if skipped. Hence no assignment beats the maximum in the recurrence.

Conversely, each finite recurrence term is attained by a predecessor assignment, extended by the indicated destination. Thus the maximum is attainable. This proves the invariant for layer .

Apply the final constraints

Every complete assignment appears in layer at its exact weight pair, and every finite entry represents such an assignment. Testing the two weight bounds and profit threshold therefore accepts exactly the yes-instances.

Running time and encoding

There are states and at most three candidates per state. The algorithm uses arithmetic operations and stored profit values with rolling layers.

Let . Every finite table value has magnitude at most , so arithmetic takes polynomial time in the bit length of . The operation bound is not a claim that arbitrary-size integer arithmetic costs one bit operation.

For unary input length ,

Consequently there are arithmetic operations on -bit profits, giving polynomial bit complexity. Under binary encoding, may be exponential in ; the same algorithm is only pseudopolynomial.

Nonnegative-weight restriction

If all weights and capacities are nonnegative, an over-capacity state can never become feasible later. Restrict the two axes to and . The same recurrence then uses

arithmetic operations. The additions of account for zero weights and zero capacities. Negative profits do not invalidate either recurrence; skipping and taking maxima handle them directly.