6

For the bounded knapsack problem, assuming the value of each item is the same as its weight and all weights are positive integers, I am wondering if there is an optimisation for the case where individual item weight is small compared to the number of items n and the capacity of the knapsack is half the sum of all item weights? e.g. 100k items and each item weight is restricted to [1, 10].

The algorithm should give exact solution. I am aware of the O(n*W) time and O(W) space DP algorithm but thought there might be better ways to solve it in this case. Thanks in advance.

This is from an algo challenge and the O(n*W) time solution was functionally correct but not fast enough (a magnitude slower than what was required). And I can't seem to find anything on this problem. The input is a list of item weights and required output is the maximum total value of items that can be fitted into the knapsack.

Jason L
  • 510
  • 5
  • 16
  • 1
    Are you looking for this: http://stackoverflow.com/questions/18790554/whats-it-called-when-i-want-to-choose-items-to-fill-container-as-full-as-possib/18790828#18790828 – Abhishek Bansal Sep 16 '13 at 06:23
  • @AbhishekBansal: He is aware of that solutions. He needs something better. – usamec Sep 16 '13 at 13:19
  • Btw if you have unbounded knapsack (that means you can use each item as many times as you want) and only K different weights, then you only have K different items (which already reduces time complexity). – usamec Sep 16 '13 at 13:22
  • He didn't mention the ILP approach, which is why I directed him to the link. Though I can't say it's any better. – Abhishek Bansal Sep 16 '13 at 13:23
  • So, just to understand your example, if `n=10^6` then you might have `10^5` of an item with weight `1`, `10^5` of an item with weight `2`, and so on upto weight `10`. And `W`, the total weight you are aiming towards, would also be very large? – TooTone Sep 16 '13 at 14:51
  • Oops... I meant the bounded knapsack problem. Sorry about the confusion. I have reworded the question. Thanks for all responses so far. – Jason L Sep 17 '13 at 01:28
  • Just to be clear I think you mean O (d W), where d is the no of different items. In your example I read n=100k, but d=10. – TooTone Sep 18 '13 at 12:36
  • @TooTone W is the capacity of the knapsack so in this case W is half the sum of all elements. – Jason L Sep 19 '13 at 01:14
  • @JasonL thanks I understand that. I'm really querying O(nW): I don't think this is consistent with the rest of your question. You seem to be saying that n is the number of items, n=100k in your example, with d=10 different items. The algorithm you refer to is actually O(dW) not O(nW), see [here](http://stackoverflow.com/a/18792242/834521) for my implementation which could easily be adapted to cater for limited nos of items. Of course you are probably aware of this, but if you're using math notation to communicate your problem precisely, it is helpful to get all the details right. – TooTone Sep 19 '13 at 09:47

2 Answers2

6

The paper you're looking for is Pisinger 1999, "Linear Time Algorithms for Knapsack Problems with Bounded Weights". It's a bit of a pain though because the pdf seems to have lost the distinguishing markings on some of the variables.

Add the items to your solution in any order until you reach an item b - the break item - which causes you to exceed W. The items 1, 2, ... b-1 constitute a balanced filling, and all other balanced fillings are those that can be reached by a series of two operations:

  • A balanced insert is the addition of an item at b or beyond to a balanced solution with weight <= W.
  • A balanced remove is the removal of an item before b from a balanced solution with weight > W.

It's pretty easy to see two things: first that all balanced solutions are within 10 units of weight of W, and second that an optimal solution must be a balanced solution.

We find our way from the initial solution to the optimal one by dynamic programming.

  • For each item t from b onwards,
  • and for each weight w such that W - 9 < w < W + 10,
  • we're going to keep track of the most recent item s before b
  • such that there's a balanced filling of weight w which can be reached through adding/removing items solely between s and t

Read that through a couple of times. Notice that some point along the way, we're guaranteed to run into an optimal solution (though we won't know it until the end). Letting wBreak be the weight before the break item is added, our algorithm is intitalized with:

for (w = W-9, w <= W, w++) { s(b-1, w) = 0 }
for (w = W+1, w <= W+10, w++) { s(b-1, w) = 1 }

s(b, wBreak) = b - 1

These are all defaults, apart from s(b, wBreak). Then we get to the meat:

for (t = b, t <= N, t++) 
{
    for (w = W-9, w <= W, w++) 
    {
        // Trying adding item t to the solutions with weight <= W 
        s(t, w + w_t) = max( s(t-1, w), s(t-1, w + w_t) )   
    }
    for (w = W+10, w > W, w--)
    {
        // Removing as many items as needed to get back to a balanced filling
        for (j = s(t, w) - 1, j >= s(t-1, w), j--) 
        {
            s(t, w - w_j) = max( s(t, w - w_j), j )
        }
    }
}

In all, this takes O(N) time, and we can identify the weight of the optimal filling as the nontrivial s(t,w) with w closest to W yet no larger than it.

Note this doesn't take advantage of the fact that the sum of the weights of all items is 2W. I'll try and think of a simplification using that, but it might be the question setters added that so you don't have to worry about the trivial edge cases when there's not enough items to fill W.

Andy Jones
  • 4,723
  • 2
  • 19
  • 24
  • Thank you. This looks promising. – Jason L Sep 24 '13 at 06:55
  • @AndyJones "It's pretty easy to see two things: first that all balanced solutions are within 10 units of weight of W" -- I don't understand this. Why would all balanced solutions be within 10 units of W? Say sum_so_far=9 and W=20, and my break_item=12, then (W - sum_so_far) = 11 > 10. Also, where can I find a version of Pisinger's 1999 paper? Thanks! – Nishant Kelkar Apr 05 '15 at 10:19
  • @AndyJones: Aah, I see. I read the OP's problem and it makes sense now. Earlier, I had only read the title and jumped to the solution. Thanks and sorry about that! – Nishant Kelkar Apr 05 '15 at 10:21
  • 1
    @NishantKelkar Just in case anyone else is confused, a balanced solution has to be within 10 units because the OP limits item weights to [1, 10]. As for the paper, it's been six months but I think I only managed to find a paywalled version of it. Looking again now, Chap 8 of [Pisinger's 1995 thesis *Algorithms for Knapsack Problems*](http://www.diku.dk/~pisinger/95-1.pdf) seems to cover similar material. – Andy Jones Apr 05 '15 at 10:30
1

The Pisinger 1999 paper Bounded Knapsack can be found at http://www.diku.dk/~pisinger/94-27.ps and the implemented code at http://www.diku.dk/~pisinger/codes.html as bouknap.c

nichole
  • 11
  • 1
  • The site is down but the wayback machine has the paper at https://web.archive.org/web/20170819134841/http://www.diku.dk/~pisinger/codes.html, specifically https://web.archive.org/web/20170921214911/http://www.diku.dk:80/~pisinger/bouknap.c. However, I've tried to compile it using gcc and I get WinMain errors. – Avraham Jun 20 '18 at 05:56