背包的变体

时间:2016-01-29 16:00:41

标签: algorithm pseudocode knapsack-problem partition-problem

我正在研究一个解决0/1背包问题变体的程序。

此处描述了原始问题:https://en.wikipedia.org/wiki/Knapsack_problem。 如果以后链接丢失,我会给你一个0/1背包问题的摘要(如果你熟悉它,跳过这一段): 假设我们有n项,每项都有权重wi和值vi。我们希望将物品放入一个支撑最大重量W的袋子中,这样袋子内的总值就可以达到最大值,而不会超过袋子。项目不能有多个实例(即,我们只有一个实例)。问题的目标是maximize SUM(vi.xi),以便SUM(wi.xi) <= Wxi = 0, 1xi代表商品中包含或不包含的商品的状态。)

就我而言,条件和目标都存在细微差别:

  • 所有项目的权重为1,wi = 1, i = 1...n

  • 我总是想把一半的物品放在包里。因此,行李的最大重量容量是物品数量的一半(四舍五入)。W = ceil[n/2]W = floor[(n+1)/2]

  • 此外,包内的重量必须等于其最大容量SUM(wi.xi) = W

最后,不是最大化包内物品的价值,而是目标是内部物品的价值尽可能接近外面物品的价值。因此,我的目标是minimize |SUM(vi.-xi) - SUM[vi(1-xi)]|,简化为minimize |SUM[vi(2xi - 1)]|

现在,上面的维基百科页面中有一个原始0/1背包问题的伪代码(你可以在本文的底部找到它),但我无法适应我的场景。有人可以帮忙吗? (我不是要求代码,只是为了一个想法,所以语言无关紧要)

谢谢!

维基百科的0/1背包问题的伪代码:

  

假设w1, w2, ..., wn, W是严格正整数。限定   m[i,w]是重量减去可以达到的最大值   使用最多w项(i个项目)的i以上。

     

我们可以递归地定义m[i,w],如下所示:

     
      
  • m[0, w]=0
  •   
  • m[i, w] = m[i-1, w] if wi > w(新项目超过当前的重量限制)
  •   
  • m[i, w]= max(m[i-1, w], m[i-1, w-wi] + vi) if wi <= w
  •   
     

然后可以通过计算m[n,W]找到解决方案。

// Input:
// Values (stored in array v)
// Weights (stored in array w)
// Number of distinct items (n)
// Knapsack capacity (W)

for j from 0 to W do:
    m[0, j] := 0

for i from 1 to n do:
    for j from 0 to W do:
        if w[i-1] <= j then:
            m[i, j] := max(m[i-1, j], m[i-1, j-w[i-1]] + v[i-1])
        else:
            m[i, j] := m[i-1, j]

1 个答案:

答案 0 :(得分:2)

感谢@harold,似乎这个问题不是背包问题,而是分区问题。我正在寻找的部分伪代码位于相应的维基百科页面中:https://en.wikipedia.org/wiki/Partition_problem

编辑:实际上,分区问题算法会告诉您一组项目是否可以分为两组相等的值。假设它不能,你有近似算法,它表示你是否可以将这些集合分成两组,差别是它们的值低于d。 但是,他们并没有告诉你所产生的子集,而这正是我所寻求的。

我最终在这里找到了一个问题(这里:Balanced partition),并且我已经测试了一个代码示例并且工作正常。