knapsack multiple constraints
I have a dynamic programming question which I have spent hours researching to no avail.
The first part is easy: you have a knapsack of items, and you have to maximise the value of these items, whilst keeping them below a certain weight.
The second part of the question is the same, except now there is also an item limit. so for example:
What is the max value of items you could put in the bag such that value is maximised with both weight and item limit?
I have no idea how to implement the second part of this question, Im looking for a general algorithm.
In the dynamic programming solution without item limit you have 2D matrix where Y-axis is item index and X-axis is weight. Then for each item, weight pair you choose maximum between
Here's example of the standard solution in 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]
Now when you add the item limit you have to choose maximum value for each item, value, number of items used triplet from
In order to represent number of items you can just add third dimension to the previously used matrix that represents the number of used items:
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]
Simple demo:
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)))
Output:
Max value for weight limit 5, no item limit: 7
Max value for weight limit 5, item limit 2: 5
Note that you could optimize the example a bit regarding memory consumption since when adding zth item to the solution you only need to know the solution for z - 1 items. Also you could check if it's is possible to fit z items under the weight limit to begin with and if not reduce the item limit accordingly.
链接地址: http://www.djcxy.com/p/59948.html上一篇: 使用cakephp将amazon s3帐户中的文件下载到另一个s3帐户
下一篇: 背包多重约束