【问题标题】:Put the most valuable items in a box把最有价值的东西放在一个盒子里
【发布时间】:2021-11-29 13:11:59
【问题描述】:

我正在做如下编程练习:
有一个盒子和一个项目列表。
盒子有固定的尺寸。每件商品都有自己的尺寸和价格。
如果物品大小的总和小于盒子的大小,我们可以在盒子里放任意数量的物品。 (每件物品只能放一次)。
找出可以放入箱子的物品组合,价格最高。

box: size = 10
| item | size | price |
| ---- | ---- | ----- |
| 1    | 8    | 4     |
| 2    | 10   | 5     |
| 3    | 1    | 2     |

在这种情况下,答案将是 6,因为选择了项目 1 和 3,价格 4 + 2 = 6(尺寸总和为 8,小于 10)

我的方法是执行回溯以找到所有可能的组合并记录最高价格,但我不确定如果列表中有大量项目是否足够有效。

有没有更有效的方法?

【问题讨论】:

    标签: algorithm combinations


    【解决方案1】:

    是的,有一种更有效的方法!

    动态编程 - 自下而上

    方法:不是通过评估所有可能的子集来强制解决问题,而是可以针对每个权重的每个项目迭代地解决问题。举个例子:
    假设有四个项目 i[1,2,3,4] 关联权重 w[5,3,4,2]、值 v[60,50,70,30] 和最大权重 w = 5

    我们现在将构造一个二维值数组,它保存了选择某项特定权重时的最大值V[i][w]

    填充数组的算法是:

    V[i][w] = max(V[i-1, w], V[i-1, w - w_i] + v_i) OTHERWISE V[i-1, w]

    这是做什么的? :
    对于每个重量的每个项目,我们首先看是否可以在不超过重量限制的情况下选择项目。如果不是,我们取上述项目在该重量下的值(如果该项目也无法选择,则为 0)。

    如果我们可以选择项目,有趣的事情就会发生。如果是这样,如果选择的项大于上面选择项的值,我们选择当前项代替:
    (So if V[i-1, w] < V[i-1, w - w_i] + v_i)

    对所有 n 个项目和 w 个权重执行此操作,您将获得尽可能高的值。 在上述示例中执行算法时,这将是矩阵:

    w 0 1 2 3 4 5
    Item 1 0 0 0 0 0 60
    Item 2 0 0 0 50 50 60
    Item 3 0 0 0 50 70 70
    Item 4 0 0 30 50 70 80

    现在要解决背包问题,我们看看 w = 5 时选择项目的值。我们看到选择项目 4 产生的价值最大。我们还可以看到该值的来源。如果我们选择第 4 项,从权重中减去 2,然后我们落在 w = 3 的列中。然后我们上升一行,因为我们选择了第 4 项并且不能再次选择它。然后我们看了一下第 3 项,但是如果我们从 w = 3 中减去 w_3,我们得到 -1,所以我们知道该列中的值是从上面的行继承的,所以我们查看第 2 行。从w = 3 给出 0,所以我们知道该行/列中的值来自选择第 2 项。这最终告诉我们,值 80 是通过选择第 2 项然后选择第 4 项获得的。

    与蛮力方法的 O(2 ^ N) 相比,运行它的复杂度是 O(N * W)

    【讨论】:

    • 什么是NW?这是伪多项式,对吧?
    • N 是物品的数量,W 是权重的数量(所以对于 w = 5,W = 6,如上表所示)。你是对的,它是伪多项式,因为背包程序是 NP 完全的,正如 ADdV 所提到的。
    【解决方案2】:

    这正是0/1 knapsack problem。确实尝试所有组合都可以解决问题,但是如果要超过 50 个项目,这将花费很长时间。

    这个问题是 NP-完全的,但它可以用伪多项式求解。也就是说,如果盒子的总大小相对较小,则可以有效地解决。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-07-19
      • 1970-01-01
      • 1970-01-01
      • 2017-07-09
      • 2012-05-11
      • 1970-01-01
      • 2012-08-31
      • 1970-01-01
      相关资源
      最近更新 更多