Syx Pek / Jan 24 2019

0-1 Knapsacks

You have NNitems, the ii-th item having integer weight wiZ0w_i \in \mathbb{Z}_{\geq 0}and integer value viZ0v_i \in \mathbb{Z}_{\geq 0}, and a bag with carrying capacity BB. Your goal is to take items such that their value is maximized, but their weight cannot exceed the carrying capacity of the bag. In other words, find a subset of S{1,2,...,N}S \subseteq \{1, 2, ..., N\}such that iSvi\sum_{i \in S} v_i is minimized but iSwiB\sum_{i \in S} w_i \leq B.

This is known as the 0-1 Knapsack problem. Naïvely, by trying all the subsets, we can derive a Θ(N2N)\Theta(N \cdot 2^N)algorithm.

using Pkg; Pkg.add("Combinatorics");
using Combinatorics;
struct Item
  value ::Number
  weight::Number
end

function NaiveKnapsack(ItemList :: Vector{Item}, B :: Number)
  bestvalue  = 0
  bestsubset = Vector{Item}()
  for subset in combinations(ItemList)
    if sum([item.weight for item in subset]) <= B
      # Valid Subset of Items
      currvalue = sum([item.value for item in subset])
      if currvalue > bestvalue
        bestvalue  = currvalue
        bestsubset = subset
      end
    end
  end
  bestsubset
end

ItemList = [Item(3,2), Item(4,2), Item(5,3), Item(6,4)]
NaiveKnapsack(ItemList, 4)