2011-10-31 61 views
1

我在接近一周的任务中挣扎,没有找到解决方案的成功,所以这个网站是我最后的希望。0-1背包蛮力执行

我有0-1 Knapsack问题,其中有20个项目有着不同的价值观和重量,包装袋的最大重量为524。现在,我需要实现蛮力找到的20项最佳解决方案的子集,这样总权重< = 524和最大值的选择项目。

请您指出或更好地给出详细的实施方案,以分析它是如何工作的! 非常感谢您

+0

这功课吗? –

+1

是的,这是作业,我被困在如何找到所有可能的组合,我应该存储组合数组? – MinhHoang

回答

6

蛮力的想法很简单:

  1. 生成的20个项目的所有可能的子集,只保存那些满足你的体重限制。如果你想要看起来很花哨,你甚至可以考虑在不违反重量限制的情况下不能添加任何东西的子集,因为只有这些子集才可能是正确的答案。 O(2^n)
  2. 查找具有最大权重的子集。就候选人数量而言是线性的,并且由于我们有O(2^n)个候选人,所以这是O(2^n)。

如果您需要伪代码,请发表评论。

编辑:嘿,这是伪代码以防万一。

GetCandidateSubsets(items[1..N], buffer, maxw) 
    1. addedSomething = false 
    2. for i = 1 to N do 
    3. if not buffer.contains(item[i]) and 
      weight(buffer) + weight(items[i]) <= maxw then 
    4.  add items[i] to buffer 
    5.  GetCandidateSubsets(items[1..N], buffer) 
    6.  remove items[i] from buffer 
    7.  addedSomething = true 
    8. if not addedSomething then 
    9. emit & store buffer 

请注意,GetCandidateSubsets函数效率不高,即使是暴力破解实施。感谢阿米特指出了这一点。作为第一遍优化,您可以对此进行重新设计,以便只对项目集合的组合进行排序,而不是排列组合。

GetMaximalCandidate(candidates[1..M]) 
    1. if M = 0 then return Null 
    2. else then 
    3. maxel = candidates[1] 
    4. for i = 2 to M do 
    5.  if weight(candidates[i]) > weight(maxel) then 
    6.   maxel = candidates[i] 
    7. return maxel 
+0

(1)因为您需要检查所有子集,所以找到最大权重也是'O(2^n)'。 (2)回溯和暴力的主要优点通常是空间复杂性,通过存储所有的可能性,你的空间复杂度是'O(2^n)',你失去了这个优势。 (3)伪代码中的解决方案不是'O(2^n)',而是'O(n!)',甚至是'O(n^n)' – amit

+0

@amit:对,获取最大元素会为O(2^n),因为有O(2^n)个子集要检查,最大元素查找代码查看它们全部。第二次批评对我来说并不是那么有意义,因为OP没有真正表明这是一个问题。注意到(3)中的批评;对于它的价值,我没有在这个代码中做很多工作。 – Patrick87

+0

嗨请注意,如果子集A有1000个值和523个权重,B有999个值和524个权重,那么A必须是最优解 – MinhHoang