【问题标题】:knapsack with requirement to select one item each from many sets要求从多组中各选择一项的背包
【发布时间】:2015-10-08 10:13:35
【问题描述】:

我对基本的0-1 knapsack problem 及其解决方案有所了解。我试图通过 0-1 问题的变体进行推理,在该变体中,您不能从单个列表中选择任何项目组合,而 必须 从许多不同的项目集中分别选择一个项目.

例如,在我的问题中,项目列表如下所示:

食物

  • 香蕉(重量 9,价值 10)
  • 面包(重量 3,价值 25)
  • 苹果(重量 4,价值 30)
  • ...

衬衫

  • T 恤(重量 2,价值 20)
  • 纽扣衬衫(重量 3,价值 25)
  • ...

裤子

  • 卡其布(重量 4,价值 30)
  • 牛仔裤(重量 2,价值 30)
  • ...

以此类推,问题要求您从 Food 中准确选择一项,从 Shirts 中选择一项,从 Pants 中选择一项,等等。

认为有一个我从 Rosetta Code 修改的蛮力解决方案,并且似乎可以工作(如下),但我无法弄清楚如何创建更有效的动态编程解决方案。任何人都可以帮助或指出我正确的方向吗?我会很感激的。

from itertools import product

def anycomb(item1, item2, item3, item4):
    return ( comb
             for comb in product(item1, item2, item3, item4)
             )

def totalvalue(comb):
    ' Totalise a particular combination of items'
    totwt = totval = 0
    for item, wt, val in comb:
        totwt  += wt
        totval += val
    return (totval, -totwt) if totwt <= 400 else (0, 0)

itemset_1 = (
    ("map", 9, 150), ("compass", 13, 35), ("water", 153, 200), ("sandwich", 50, 160),
    ("glucose", 15, 60))
itemset_2 = (
    ("tin", 68, 45), ("banana", 27, 60), ("apple", 39, 40),
    ("cheese", 23, 30), ("suntan cream", 11, 70))
itemset_3 = (
    ("beer", 52, 10), ("camera", 32, 30),
    ("t-shirt", 24, 15), ("trousers", 48, 10), ("umbrella", 73, 40),
    ("waterproof trousers", 42, 70))
itemset_4 = (
    ("waterproof overclothes", 43, 75),
    ("note-case", 22, 80), ("sunglasses", 7, 20), ("towel", 18, 12),
    ("socks", 4, 50), ("book", 30, 10))

bagged = max( anycomb(itemset_1, itemset_2, itemset_3, itemset_4), key=totalvalue) # max val or min wt if values equal
print("Bagged the following items\n  " +
      '\n  '.join(sorted(item for item,_,_ in bagged)))
val, wt = totalvalue(bagged)
print("for a total value of %i and a total weight of %i" % (val, -wt))

【问题讨论】:

  • 你可以在这里做一个 3D DP,状态为 DP(列表中剩余的项目数,列表数,总和)。然后,每当您选择当前项目时,只需减少列表数量!它有一个标签 python 否则我可以给你一些 c++ 代码
  • 有什么限制?

标签: python algorithm dynamic-programming knapsack-problem


【解决方案1】:

稍加改动即可使用basic 0-1 knapsack问题的解决方案。 当您选择选择一个项目时,您必须转到上一组的最后一个项目。 这意味着:

F(i,w) = max[ F(i-1 , w) , F(A[i]-1 , w-w[i]) + P[i] ]

其中 A[i] 表示第 i 项所属集合的第一项的索引。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-24
    • 1970-01-01
    • 1970-01-01
    • 2018-01-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多