Làm thế nào về điều này?
Cho một giải pháp năng động tiêu chuẩn trong Haskell cho một vấn đề 0-1 ba lô, tìm thấy 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
chúng ta thêm một cơ chế nhồi nhét, đặt các hoán vị hàng tồn kho liên tục trong ba lô tiếp theo mà có không gian,
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)
và thay thế nó cho hàm được ánh xạ. Đưa nó tất cả cùng nhau:
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 (tổng giá trị tiếp theo khả năng của mỗi chiếc ba lô còn lại trọng lượng và nội dung):
*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)])])
Khi không có những hạn chế về F, vấn đề này là một mục tiêu lớn cho mục tiêu bảo quản giảm các vấn đề khó khăn của APX. –
Bạn cần cho chúng tôi biết thêm về chức năng ghi điểm. Vì nó đứng nó được phép tùy ý - ví dụ nó có thể cung cấp cho sự kết hợp của các mục 3, 5 và 17 một số điểm 100 và mọi kết hợp khác 0: không có cách nào để tối ưu hóa điều này mà không thử mọi tập con của các mục phù hợp. –
Ngoài ra để chứng minh nó NP-cứng bạn sẽ giảm bin-đóng gói * với nó *, không ngược lại. Nhưng (giả sử cho thời điểm này một chức năng chấm điểm hợp lý) bạn không cần phải bận tâm với điều đó vì nó tầm thường để giảm * knapsack bình thường * cho vấn đề này bằng cách thiết lập m = 1 :-P –