了解背包解决方案

时间:2016-03-04 16:13:08

标签: haskell knapsack-problem

我无法理解以下针对背包问题的解决方案from Rosetta Code

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),
   ("waterproof 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

根据我的理解,foldr的结果将是每个容量的无限解决方案列表。然后,我们将列表索引到所需的容量以找到解决方案。但是,为什么在newList中,我们是否为列表中的每个元素添加新项的值?我们不应该只将它添加到right,因为它是容量超过当前对象权重的列表吗?

zipWith max包含每个容量的条目(包括right中包含的条目时)时,为什么newListnewList列表上的left为什么?{ / p>

我还想了解如何分析时间复杂性。我很难想到使用延迟评估的Haskell程序的复杂性。

0 个答案:

没有答案