只有重量的背包

knapsack with weight only

本文关键字:背包      更新时间:2023-10-16

如果我给出了最大权重,比如w=20。并且我给出了一组权重,比如m=[5,7,12,18],那么我如何使用m来计算我们可以保持在最大权重内的最大可能权重。在这种情况下,通过加12+7=19,答案是19。我的代码是18。请帮我。

int weight(int W, vector<int> &m) {
  int current_weight = 0;
  int temp;
  for (int i = 0; i < w.size(); i++) {
    for (int j = i + 1; j < m.size(); j++) {
      if (m[i] < m[j]) {
        temp = m[j];
        m[j] = m[i];
        m[i] = temp;
        }
      }
    }
  for (size_t i = 0; i < m.size(); ++i) {
    if (current_weight + m[i] <= W) {
       current_weight += m[i];
      }
    }
 
  return current_weight;
  }

您描述的问题看起来更像是最大子集和问题的一个版本。基本上,你的实施一开始没有错;显然你已经正确地实现了贪婪算法来解决这个问题。也就是说,这种算法无法为每个输入生成最优解。您找到的实例就是这样一个例子。

然而,这个问题可以使用一种称为动态规划的不同方法来解决,这种方法可以被视为解决方案的递归公式的组织形式。

m = { m_1, ... m_n }是正项目大小的集合,W是顶点约束,其中n是正整数。将阵列A[n][W]组织为所在的状态空间

A[i][j] = the maximum weight at most j attainable for the set of items
          with indices from 0 to i if such a solution exists and 
          minus infinity otherwise

对于每个CCD_ 5和CCD_;为了便于演示,假设A在其他任何地方都具有负无穷大的值。注意,对于每个这样的ij,递归关系

A[i][j] = min { A[i-1][W-m_j] + m_j, A[i-1][W] }

成立,其中第一种情况对应于将项目i选择到解决方案中,而第二种情况则对应于而不是选择项目i到解决方案。

接下来,组织一个循环,该循环按ij的值递增的顺序填充该表,其中i = 1的初始化必须在之前完成。填充状态空间后,最后一列中的最大可行值

max{ A[n][j] : j in {1,...,W}, A[n][j] is not minus infinity }

产生最优解。如果还需要相关联的项集合,则必须使用一些回溯或适当的辅助数据结构。

因此,通过将权重数组的副本作为值数组传递,这个解决方案对常见的0-1背包问题来说可能是一个微不足道的更改。