1

I'm working on a program to solve a variant of the 0/1 Knapsack problem.

The original problem is described here: https://en.wikipedia.org/wiki/Knapsack_problem. In case the link goes missing in the future, I will give you a summary of the 0/1 Knapsack problem (if you are familiar with it, jump this paragraph): Let's say we have n items, each with weight wi and value vi. We want to put items in a bag, that supports a maximum weight W, so that the total value inside the bag is the maximum possible without overweighting the bag. Items cannot have multiple instances (i.e., we only have one of each). The objective of the problem is to maximize SUM(vi.xi) so that SUM(wi.xi) <= W and xi = 0, 1 (xi represents the state of an item being or not in the bag).

For my case, there are small differences in both conditions and objective:

  • The weight of all items is 1, wi = 1, i = 1...n

  • I always want to put exactly half the items in the bag. So, the maximum weight capacity of the bag is half (rounded up) of the number of items.W = ceil[n/2] or W = floor[(n+1)/2].

  • Also, the weight inside the bag must be equal to its maximum capacity SUM(wi.xi) = W

Finally, instead of maximizing the value of the items inside the bag, the objective is that the value of the items inside is as close as possible to the value of the items outside. Hence, my objective is to minimize |SUM(vi.-xi) - SUM[vi(1-xi)]|, which simplifies into something like minimize |SUM[vi(2xi - 1)]|.

Now, there is a pseudo-code for the original 0/1 Knapsack problem in the Wikipedia page above (you can find it on the bottom of this text), but I am having trouble adapting it to my scenario. Can someone help? (I am not asking for code, just for an idea, so language is irrelevant)

Thanks!


Wikipedia's pseudo-code for 0/1 Knapsack problem:

Assume w1, w2, ..., wn, W are strictly positive integers. Define m[i,w] to be the maximum value that can be attained with weight less than or equal to w using items up to i (first i items).

We can define m[i,w] recursively as follows:

  • m[0, w]=0
  • m[i, w] = m[i-1, w] if wi > w (the new item is more than the current weight limit)
  • m[i, w]= max(m[i-1, w], m[i-1, w-wi] + vi) if wi <= w.

The solution can then be found by calculating m[n,W].

// Input:
// Values (stored in array v)
// Weights (stored in array w)
// Number of distinct items (n)
// Knapsack capacity (W)

for j from 0 to W do:
    m[0, j] := 0

for i from 1 to n do:
    for j from 0 to W do:
        if w[i-1] <= j then:
            m[i, j] := max(m[i-1, j], m[i-1, j-w[i-1]] + v[i-1])
        else:
            m[i, j] := m[i-1, j]
Marco Castanho
  • 395
  • 1
  • 7
  • 24
  • 1
    As a general rule, do not depend on pointing us to a web page to describe your problem. That webpage may not be there in the future, which would make it impossible for others to know if they had the same problem that you do. It's OK to include the link but we should be able to understand your problem without having to go to the link. – RBarryYoung Jan 29 '16 at 16:15
  • @RBarryYoung, I was about to explain the problem, but I thought the link would suffice and users could find further explanation redundant. I'll edit it. Thanks! – Marco Castanho Jan 29 '16 at 16:18
  • 2
    This is actually the partition problem (optimization variant) – harold Jan 29 '16 at 16:48
  • @harold. Well, it seems to be exactly it. It also seems like Wikipedia also has pseudo-codes for that. Thanks a lot! – Marco Castanho Jan 29 '16 at 16:52

1 Answers1

2

Thanks to @harold, it seems like this problem is not a Knapsack problem, but a Partition problem. Part of the pseudo-code I was seeking is in the corresponding Wikipedia page: https://en.wikipedia.org/wiki/Partition_problem

EDIT: well, actually, Partition problem algorithms tell you whether a Set of items can be partitioned in 2 sets of equal value or not. Suppose it can't, you have approximation algorithms, which say whether you can have the set partiotioned in 2 sets with the difference their values being lower than d. BUT, they don't tell you the resulting sub-sets, and that's what I was seeking.

I ended up finding a question here asking for that (here: Balanced partition), with a code example which I have tested and works fine.

Community
  • 1
  • 1
Marco Castanho
  • 395
  • 1
  • 7
  • 24