具有两个约束的背包问题的伪代码算法
Pseudo code Algorithm for Knapsack Problem with Two Constrains
我正在尝试用两个约束解决以下背包问题。
我们知道的:
- 列表项目项目总数
- 列表项重量
- 列表项值
- 列出物品是否易碎(true/false)
约束:
- 列表项背包最大重量
- 列表项背包可容纳的易碎物品的最大数量。
任何人都可以给我一些关于我应该使用的算法、伪代码或好文章的建议吗?
更新:
我忘记说的重要一点是,我还需要知道我在包里放了哪些物品。
看来修改背包就可以解决。
假设我们有 N 件物品,背包的最大重量为 W,易碎物品的最大数量为 F
让我们定义我们的 dp table 为 3 维数组 dp[N+1][W+1][F+1]
现在 dp[n][w][f] 存储我们可以得到的最大值,如果我们用第一个项目的一些子集填充背包
n 件物品,重量恰好为 w,易碎物品恰好为 f。
frop dp[n][w][f] 我们可以移动到状态:
- dp[n+1][w][f] 如果我们跳过第 n+1 项
- dp[n+1][w + weight(n+1)][f + isFragile(n+1)] 如果我们取第 n+1 项
所以伪代码:
dp[N+1][W+1][F+1] // memo table, initially filled with -1
int solve(n,w,f)
{
if(n > N)return 0;
if(dp[n][w][f] != -1) return dp[n][w][f];
dp[n][w][f] = solve(n+1,w,f); //skip item
if(w + weight(n) <= W && f + isFragile(n) <=F)
dp[n][w][f] = max(dp[n][w][f], value(n) + solve(n+1, w + weight(n), f + isFragile(n)));
return dp[n][w][f]
}
print(solve(1,0,0))
得到实际的子集也不难:
vector<int> getSolution(n,w,f)
{
int optimalValue = solve(n,w,f);
vector<int>answer; //just some dynamic array / arrayList
while(n <= N)
{
if(solve(n+1,w,f) == optimalValue)n++; //if after skipping item we can still get optimal answer we just skip it
else //otherwise we cant so current item must be taken
{
int new_w = w + weight(n);
int new_f = f + isFragile(n);
answer.push_back(n); //so we just save its index, and update all values
optimalValue -= value(n);
n++;
w = new_w;
f = new_f;
}
}
return answer;
}
非递归方法
# N: number of items, W: max weight of knapsack, F: max amount of fragile items
# if item doesn't fit, then skip
# if it fits, check if it's worth to take it
dp[N+1][W+1][F+1] # filled with zeros
benefit, weight, fragility = [] # arrays filled with respective item properties
for n in range(1, N + 1):
for w in range(1, W + 1):
for f in range(0, F + 1):
if weight[n-1] > w or fragility[n-1] > f:
dp[n][w][f] = dp[n-1][w][f]
else:
dp[n][w][f] = max(dp[n-1][w][f],
dp[n-1][w-weight[n-1]][f-fragility[n-1]] + benefit[n-1])
print(dp[N][W][F]) # prints optimal knapsack value
列出项目
knapsack = [] # indexes of picked items
n = N
w = W
f = F
while n > 0:
if dp[n][w][f] != dp[n-1][w][f]:
knapsack.append(n-1)
w -= weight[n-1]
f -= fragility[n-1]
n -= 1
print(knapsack) # prints item indexes
我正在尝试用两个约束解决以下背包问题。
我们知道的:
- 列表项目项目总数
- 列表项重量
- 列表项值
- 列出物品是否易碎(true/false)
约束:
- 列表项背包最大重量
- 列表项背包可容纳的易碎物品的最大数量。
任何人都可以给我一些关于我应该使用的算法、伪代码或好文章的建议吗?
更新:
我忘记说的重要一点是,我还需要知道我在包里放了哪些物品。
看来修改背包就可以解决。
假设我们有 N 件物品,背包的最大重量为 W,易碎物品的最大数量为 F
让我们定义我们的 dp table 为 3 维数组 dp[N+1][W+1][F+1]
现在 dp[n][w][f] 存储我们可以得到的最大值,如果我们用第一个项目的一些子集填充背包 n 件物品,重量恰好为 w,易碎物品恰好为 f。
frop dp[n][w][f] 我们可以移动到状态:
- dp[n+1][w][f] 如果我们跳过第 n+1 项
- dp[n+1][w + weight(n+1)][f + isFragile(n+1)] 如果我们取第 n+1 项
所以伪代码:
dp[N+1][W+1][F+1] // memo table, initially filled with -1
int solve(n,w,f)
{
if(n > N)return 0;
if(dp[n][w][f] != -1) return dp[n][w][f];
dp[n][w][f] = solve(n+1,w,f); //skip item
if(w + weight(n) <= W && f + isFragile(n) <=F)
dp[n][w][f] = max(dp[n][w][f], value(n) + solve(n+1, w + weight(n), f + isFragile(n)));
return dp[n][w][f]
}
print(solve(1,0,0))
得到实际的子集也不难:
vector<int> getSolution(n,w,f)
{
int optimalValue = solve(n,w,f);
vector<int>answer; //just some dynamic array / arrayList
while(n <= N)
{
if(solve(n+1,w,f) == optimalValue)n++; //if after skipping item we can still get optimal answer we just skip it
else //otherwise we cant so current item must be taken
{
int new_w = w + weight(n);
int new_f = f + isFragile(n);
answer.push_back(n); //so we just save its index, and update all values
optimalValue -= value(n);
n++;
w = new_w;
f = new_f;
}
}
return answer;
}
非递归方法
# N: number of items, W: max weight of knapsack, F: max amount of fragile items
# if item doesn't fit, then skip
# if it fits, check if it's worth to take it
dp[N+1][W+1][F+1] # filled with zeros
benefit, weight, fragility = [] # arrays filled with respective item properties
for n in range(1, N + 1):
for w in range(1, W + 1):
for f in range(0, F + 1):
if weight[n-1] > w or fragility[n-1] > f:
dp[n][w][f] = dp[n-1][w][f]
else:
dp[n][w][f] = max(dp[n-1][w][f],
dp[n-1][w-weight[n-1]][f-fragility[n-1]] + benefit[n-1])
print(dp[N][W][F]) # prints optimal knapsack value
列出项目
knapsack = [] # indexes of picked items
n = N
w = W
f = F
while n > 0:
if dp[n][w][f] != dp[n-1][w][f]:
knapsack.append(n-1)
w -= weight[n-1]
f -= fragility[n-1]
n -= 1
print(knapsack) # prints item indexes