【问题标题】:Knapsack DP with array of hashes带有哈希数组的背包 DP
【发布时间】:2012-08-20 11:10:56
【问题描述】:

我正在尝试使用非整数值减少 Knapsack DP 算法所需的时间和空间。

http://en.wikipedia.org/wiki/Knapsack_problem#Meet-in-the-Middle_Algorithm

In particular, if the [elements] are nonnegative but not integers, we could 
still use the dynamic programming algorithm by scaling and rounding (i.e. using 
fixed-point arithmetic), but if the problem requires  fractional digits of 
precision to arrive at the correct answer, W will need to be scaled by 10^d,  
and the DP algorithm will require O(W * 10^d) space and O(nW * 10^d) time.

DP 背包算法使用 [ n x W ] 矩阵,用结果填充它,但有些列永远不会被填充 - 它们不匹配对象权重的任何组合。这样一来,它们最终只会在每一行上填充零,而且只是浪费时间和空间。

如果我们使用哈希数组而不是矩阵,我们可以减少所需的时间和空间。

edit:
knapsack capacity = 2
items: [{weight:2,value:3} ]

   [0   1   2]
   [0   0   0] 
2: [0   0   3]
        ^
Do we need this column?

Substitution with hash:
2: {0:0, 2:3}

在 Python 中,dict 插入有 O(n) 更坏的情况和 O(1) 的“摊销”线性时间。

我错过了什么吗?

背包 DP 算法的这种变体的复杂性是多少?

【问题讨论】:

  • 我不关注。你试图如何改变它?你的字典的键/值是什么?
  • 哈希将替换矩阵的“行”。键是权重,值是子集总和
  • 您到底想保存什么? “行”仍然需要相同数量的元素(权重)。如果您对此有不同的想法 - 我们很乐意听到。
  • 这是一个例子。背包容量 2,物品:{重量:2,价值:3}。解决方案是微不足道的,取唯一的项目。我们真的需要代表权重“1”的列吗?
  • 为了降低复杂性,与总行数相比,“需要”行数必须有一个上限。但是,上限等于总行数 - 可能需要所有行,因此这显然不会降低复杂性。在一般情况下,我们必须假设大多数行都已填充,例如:容量 1000, items = {2, 3}

标签: algorithm optimization dynamic-programming knapsack-problem decimal


【解决方案1】:

如果我可以这么说的话,您所说的是快乐的情况——在这种情况下,您可以将很少的物品放入一个容量很大的背包中。在这种情况下,hashmap 可以证明是优化触发复杂性从O(W * n) 到只是O(min(O(2^n * n), O(W * n)))2^n 是 n 个元素的组合数)。但是,通过这种估计,很明显,对于没有那么多元素,O(2^n * n) 将主导其他估计。另外请注意,虽然O(W * n) 属于同一类,但后一种情况下的常数要大得多(甚至更多:第二种情况下的估计考虑了摊销复杂性,而不是最坏的情况)。

因此您会发现,在某些情况下,哈希映射可能会更好,但在通常情况下,情况正好相反。

【讨论】:

  • 我认为您将相同的“n”名称赋予不同的事物。有效列上的哈希插入可能是 O(n) - 表示可用子集数量的列。与背包的容量 O(W) 没有直接关系。那么平均复杂度将是 O(nm),最坏的情况是 O(nm^2)?
  • @lordkrandel:我很抱歉我的第一个答案,当我在 3 小时后读到它时,它甚至让我感到困惑。我现在改写了。希望它会有所帮助。
猜你喜欢
  • 2020-07-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-04-28
  • 1970-01-01
  • 2018-11-20
  • 1970-01-01
相关资源
最近更新 更多