具有两个约束的背包问题的伪代码算法

时间:2019-03-31 01:53:29

标签: algorithm dynamic-programming pseudocode knapsack-problem

我正试图通过两个约束来解决以下背包问题。

我们所知道的:

  • 列出项目总项目数
  • 列出商品重量
  • 列出项目值
  • 列出项目是否为易碎项目(是/否)

约束:

  • 列表项目背包的最大重量
  • 列表项目背包最多可容纳的易碎物品数量。

任何人都可以给我一些有关我应该使用的算法的建议,伪代码还是不错的文章?

更新:

我忘记提及的重要事情是,我还需要知道我在袋子里放了哪些物品。

2 个答案:

答案 0 :(得分:0)

对背包的修改似乎可以解决它。

比方说,我们有N个物品,最大背包重量为W,最大易碎物品数量为F

让我们将dp表定义为3维数组dp [N + 1] [W + 1] [F + 1]

现在dp [n] [w] [f]存储我们从背包中填充某些物品子集就可以得到的最大值 n个物品,重量都在w左右,而物品却很脆弱。

将dp [n] [w] [f]放到状态:

    如果我们跳过第n + 1个项目,则
  • dp [n + 1] [w] [f]
  • dp [n + 1] [w +重量(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;
}

答案 1 :(得分:0)

非递归方法

# 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