我在接近一周的任务中挣扎,没有找到解决方案的成功,所以这个网站是我最后的希望。0-1背包蛮力执行
我有0-1 Knapsack问题,其中有20个项目有着不同的价值观和重量,包装袋的最大重量为524。现在,我需要实现蛮力找到的20项最佳解决方案的子集,这样总权重< = 524和最大值的选择项目。
请您指出或更好地给出详细的实施方案,以分析它是如何工作的! 非常感谢您
我在接近一周的任务中挣扎,没有找到解决方案的成功,所以这个网站是我最后的希望。0-1背包蛮力执行
我有0-1 Knapsack问题,其中有20个项目有着不同的价值观和重量,包装袋的最大重量为524。现在,我需要实现蛮力找到的20项最佳解决方案的子集,这样总权重< = 524和最大值的选择项目。
请您指出或更好地给出详细的实施方案,以分析它是如何工作的! 非常感谢您
蛮力的想法很简单:
如果您需要伪代码,请发表评论。
编辑:嘿,这是伪代码以防万一。
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
(1)因为您需要检查所有子集,所以找到最大权重也是'O(2^n)'。 (2)回溯和暴力的主要优点通常是空间复杂性,通过存储所有的可能性,你的空间复杂度是'O(2^n)',你失去了这个优势。 (3)伪代码中的解决方案不是'O(2^n)',而是'O(n!)',甚至是'O(n^n)' – amit
@amit:对,获取最大元素会为O(2^n),因为有O(2^n)个子集要检查,最大元素查找代码查看它们全部。第二次批评对我来说并不是那么有意义,因为OP没有真正表明这是一个问题。注意到(3)中的批评;对于它的价值,我没有在这个代码中做很多工作。 – Patrick87
嗨请注意,如果子集A有1000个值和523个权重,B有999个值和524个权重,那么A必须是最优解 – MinhHoang
这功课吗? –
是的,这是作业,我被困在如何找到所有可能的组合,我应该存储组合数组? – MinhHoang