背包约束python

时间:2013-10-15 19:58:47

标签: python algorithm knapsack-problem

假设我有一个代表篮球运动员的元组列表及其名称,位置,成本和预测点数,

listOfPlayers = [
                 ("Player1","PG",Cost,projectedPoints),
                 ("Player2","PG",Cost,projectedPoints),
                 ("Player3","SG",Cost,projectedPoints),
                 ("Player4","SG",Cost,projectedPoints),
                 ("Player5","SF",Cost,projectedPoints),
                 ("Player6","SF",Cost,projectedPoints),
                 ("Player7","PF",Cost,projectedPoints),
                 ("Player8","PF",Cost,projectedPoints),
                 ("Player9","C",Cost,projectedPoints),
                 ("Player10","C",Cost,projectedPoints) 
                ]

假设所有名称,成本和预测点都是可变的。

我有传统的背包问题,他们可以根据给定的重量对背包进行分类和包装。但这并不能说明这些立场 我想知道是否有办法编辑背包代码只包括每个位置之一,即(pg,sg,sf,pf,c)。

传统的0/1背包可以做到这一点还是我需要切换到别的东西?

2 个答案:

答案 0 :(得分:4)

这被称为“多选背包问题”。

对于0/1背包问题,您可以使用类似于动态编程解决方案的算法。

0/1背包问题的解决方案如下:(来自Wikipedia

  

使用最多m[i, w]的项目,将w定义为权重小于或等于i时可以达到的最大值。
  我们可以递归地定义m[i, w],如下所示:

m[i, w] = m[i-1, w] if w_i > w   (new item is more than current weight limit)
m[i, w] = max(m[i-1, w], m[i-1, w-w_i] + v_i) if w_i <= w.
     

然后可以通过计算m[n,W]找到解决方案。为了有效地做到这一点,我们可以使用表来存储以前的计算。

现在,扩展只是为了找到所有选择的最大值。

对于某些职位n可选的i名玩家(c_i_j选择费用为jp_i_j为分),我们我有:

m[i, c] = max(m[i-1, c],
              m[i-1, c-c_i_1] + p_i_1   if c_i_1 <= c, otherwise 0,
              m[i-1, c-c_i_2] + p_i_2   if c_i_2 <= c, otherwise 0,
              ...
              m[i-1, c-c_i_n] + p_i_n   if c_i_n <= c, otherwise 0)

所以,我们说:

Name     Position  Cost  Points
Player1  PG        15    5
Player2  PG        20    10
Player3  SG        9     7
Player4  SG        8     6

然后我们有2个位置“PG”和“SG”,每个位置将有2个选择。

因此,对于位置“PG”(在i=1),我们将:

m[i, c] = max(m[i-1, c],
              m[i-1, c-15] + 5    if 15 <= c, otherwise 0,
              m[i-1, c-20] + 10   if 20 <= c, otherwise 0)

对于位置“SG”(在i=2),我们将:

m[i, c] = max(m[i-1, c],
              m[i-1, c-9] + 7    if 9 <= c, otherwise 0,
              m[i-1, c-8] + 6    if 8 <= c, otherwise 0)

答案 1 :(得分:0)

首先,Dukeling的出色回答。我没有评论的特权,所以我正在写一个答案。这实际上是一个多选背包问题&#34;。我实现了这种问题之一并在Online Judge中运行它,它在那里成功执行。 Dukeling算法的唯一问题是它不会考虑前一组项目中的至少一项。所以,从上面:

m[i, c] = max(m[i-1, c],
              m[i-1, c-15] + 5    if 15 <= c, otherwise 0,
              m[i-1, c-20] + 10   if 20 <= c, otherwise 0)`

这只适用于最多的一种。如果你添加一点零支票,那么对于i=1(&#34; PG&#34;)来说,它对于每种类型的一个项目都是完美的:

m[i, c] = max(m[i-1, c],
          m[i-1, c-15] + 5    if 15 <= c and  m[i-1, c-15] != 0, otherwise 0,
          m[i-1, c-20] + 10   if 20 <= c and  m[i-1, c-20] != 0, otherwise 0)

对于i=2(&#34; SG&#34;):

m[i, c] = max(m[i-1, c],
          m[i-1, c-9] + 7    if 9 <= c and m[i-1, c-9] != 0, otherwise 0,
          m[i-1, c-8] + 6    if 8 <= c and m[i-1, c-8] != 0, otherwise 0)

等等。