Suppose that there are n items, e.g i1, i2, .... in, each of them with a known bounded weight w1, w2, ... wn. There are also a set of m knapsacks e.g. k1, k2 and km. Knapsacks are homogeneous, that they all have the same capacity W. The function F can determine the score of each knapsack. The inputs of F are the items in each knapsack. So,
Score of each knapsack i = F(Items in knapsack i)
Now I want to put SOME items in the knapsacks in such a way that:
Is there a polynomial time solution for this problem or not?
Note: The problem is 0-1, that is each item can be selected or not. All the problem parameters are bounded.
Edit 1: Isn't it possible to reduce this problem to bin packing and then conclude that it is an NP-hard problem?
Edit 2 In this problem, each item has three attributes, e.g. attributes ai, bi and ci. The F function is a linear function that gets the attributes of items inside it and produces the output.
Edit3: It seems that this paper has proposed a exact solution for the multi- knapsack problem. Can it be used in my case?
Table 1: The amounts of time required to solve some worst-case inputs to the Knapsack problem. The Dynamic Programming solution to the Knapsack problem is a pseudo-polynomial algo- rithm, because the running time will not always scale linearly if the input size is doubled.
A pseudo-polynomial algorithm is an algorithm whose worst-case time complexity is polynomial in the numeric value of input (not number of inputs). For example, consider the problem of counting frequencies of all elements in an array of positive numbers.
Bounded Knapsack problem in Javascript. Pick the current item and recur for the remaining items with the reduced capacity of knapsack until the capacity becomes negative. Leave the current item from knapsack and recur for remaining items. Finally return the maximum value we get by picking or leaving the current item.
Theorem 1 Knapsack is NP-complete. Proof: First of all, Knapsack is NP. The proof is the set S of items that are chosen and the verification process is to compute ∑i∈S si and ∑i∈S vi, which takes polynomial time in the size of input.
How about this?
Given a standard dynamic solution in Haskell for a 0-1 knapsack problem, found here,
inv = [("map",9,150), ("compass",13,35), ("water",153,200), ("sandwich",50,160),
("glucose",15,60), ("tin",68,45), ("banana",27,60), ("apple",39,40),
("cheese",23,30), ("beer",52,10), ("cream",11,70), ("camera",32,30),
("tshirt",24,15), ("trousers",48,10), ("umbrella",73,40),
("trousers",42,70), ("overclothes",43,75), ("notecase",22,80),
("sunglasses",7,20), ("towel",18,12), ("socks",4,50), ("book",30,10)]
knapsack = foldr addItem (repeat (0,[])) where
addItem (name,w,v) list = left ++ zipWith max right newlist where
newlist = map (\(val, names)->(val + v, name:names)) list
(left,right) = splitAt w list
main = print $ (knapsack inv) !! 400
we add a stuffing mechanism, placing the inventory permutations sequentially in the next knapsack that has space,
stuff (name,w,v) left (v2,[]) = (v2,left)
stuff (name,w,v) left (v2,(cap, lst):xs) =
if w <= cap
then (v + v2, left ++ [(cap - w, (name,w,v):lst)] ++ xs)
else stuff (name,w,v) (left ++ [(cap,lst)]) (v2,xs)
and substitute it for the mapped function. Putting it all together:
inv = [("map",9,150), ("compass",13,35), ("water",153,200), ("sandwich",50,160),
("glucose",15,60), ("tin",68,45), ("banana",27,60), ("apple",39,40),
("cheese",23,30), ("beer",52,10), ("cream",11,70), ("camera",32,30),
("tshirt",24,15), ("trousers",48,10), ("umbrella",73,40),
("trousers",42,70), ("overclothes",43,75), ("notecase",22,80),
("sunglasses",7,20), ("towel",18,12), ("socks",4,50), ("book",30,10)]
capacity = 200::Int
numKnapsacks = 3
stuff (name,w,v) left (v2,[]) = (v2,left)
stuff (name,w,v) left (v2,(cap, lst):xs) =
if w <= cap
then (v + v2, left ++ [(cap - w, (name,w,v):lst)] ++ xs)
else stuff (name,w,v) (left ++ [(cap,lst)]) (v2,xs)
knapsack = foldr addItem (repeat (0, replicate numKnapsacks (capacity,[])))
where addItem (name,w,v) list = left ++ zipWith max right newlist
where newlist = map (stuff (name,w,v) []) list
(left,right) = splitAt w list
main = print $ (knapsack inv) !! 600
OUTPUT (total value followed by each knapsack's remaining weight capacity and contents):
*Main> main
(1062,[(1,[("map",9,150),("tshirt",24,15),("trousers",42,70),
("overclothes",43,75),("notecase",22,80),("sunglasses",7,20),
("towel",18,12),("socks",4,50),("book",30,10)]),
(0,[("compass",13,35),("cheese",23,30),("cream",11,70),
("camera",32,30),("trousers",48,10),("umbrella",73,40)]),
(1,[("sandwich",50,160),("glucose",15,60),("tin",68,45),("banana",27,60),
("apple",39,40)])])
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With