背包多重约束

Posted

技术标签:

【中文标题】背包多重约束【英文标题】:knapsack multiple constraints 【发布时间】:2017-08-26 04:43:27 【问题描述】:

我有一个动态编程问题,我花了数小时研究却无济于事。

第一部分很简单:你有一个背包物品,你必须最大化这些物品的价值,同时保持它们低于一定的重量。

问题的第二部分是一样的,除了现在还有一个项目限制。比如:

您可以放入包中的物品的最大值是多少,以使重量和物品限制都最大化?

我不知道如何实现这个问题的第二部分,我正在寻找一个通用算法。

【问题讨论】:

【参考方案1】:

在没有项目限制的动态编程solution 中,您有二维矩阵,其中 Y 轴是项目索引,X 轴是重量。然后对于每个项目,您选择的最大重量对之间

如果物品重量 不包括物品的重量值

以下是 Python 中标准解决方案的示例:

def knapsack(n, weight, values, weights):
    dp = [[0] * (weight + 1) for _ in range(n + 1)]

    for y in range(1, n + 1):
        for x in range(weight + 1):
            if weights[y - 1] <= x:
                dp[y][x] = max(dp[y - 1][x],
                               dp[y - 1][x - weights[y - 1]] + values[y - 1])
            else:
                dp[y][x] = dp[y - 1][x]

    return dp[-1][-1]

现在,当您添加项目限制时,您必须为每个项目选择最大值、值、使用的项目数量三元组

重量和 n 件物品的值,包括物品重量 重量值和 n 项不包括项

为了表示项目的数量,您只需将第三维添加到先前使用的表示已使用项目数量的矩阵中:

def knapsack2(n, weight, count, values, weights):
    dp = [[[0] * (weight + 1) for _ in range(n + 1)] for _ in range(count + 1)]
    for z in range(1, count + 1):
        for y in range(1, n + 1):
            for x in range(weight + 1):
                if weights[y - 1] <= x:
                    dp[z][y][x] = max(dp[z][y - 1][x],
                                      dp[z - 1][y - 1][x - weights[y - 1]] + values[y - 1])
                else:
                    dp[z][y][x] = dp[z][y - 1][x]

    return dp[-1][-1][-1]

简单演示:

w = 5
k = 2
values = [1, 2, 3, 2, 2]
weights = [4, 5, 1, 1, 1]
n = len(values)

no_limit_fmt = 'Max value for weight limit , no item limit: '
limit_fmt = 'Max value for weight limit , item limit : '

print(no_limit_fmt.format(w, knapsack(n, w, values, weights)))
print(limit_fmt.format(w, k, knapsack2(n, w, k, values, weights)))

输出:

Max value for weight limit 5, no item limit: 7
Max value for weight limit 5, item limit 2: 5

请注意,您可以在内存消耗方面对示例进行一些优化,因为在将第 z 个项目添加到解决方案时,您只需要知道 z - 1 个项目的解决方案。您还可以检查是否可以将 z 件物品放在重量限制以下,如果不能相应减少物品限制。

【讨论】:

非常感谢!这是超级有见地。我希望你是我的讲师!

以上是关于背包多重约束的主要内容,如果未能解决你的问题,请参考以下文章

无重量约束背包

如何扩展满足多重约束的协议 - Swift 2.0

背包问题怎样给出符号说明,目标函数和约束条件

带有要考虑约束的物品的背包

基于多重约束算法寻找最优值

如何在 R 中为背包问题的线性规划添加约束?