简体   繁体   English

背包约束python

[英]Knapsack constraint python

Lets say I have a list of tuples representing basketball players and their name, position, cost, and their projected points, 假设我有一个代表篮球运动员的元组列表,以及他们的姓名,位置,费用和预计得分,

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) 
                ]

Assume all of the names, costs, and projected points are variable. 假设所有名称,成本和预计点都是可变的。

I have a traditional knapsack problem working, they can sort and pack a knapsack based on a given weight. 我有一个传统的背包问题,他们可以根据给定的重量对背包进行分类和包装。 But this does not account for the positions. 但是,这并不说明职位。
I was wondering if there is a way to edit the knapsack code to only include one of every position, ie, (pg, sg, sf, pf, c). 我想知道是否有一种方法可以编辑背包代码,使其仅包含每个位置之一,即(pg,sg,sf,pf,c)。

Can a traditional 0/1 knapsack do this or do i need to switch to something else? 传统的0/1背包可以做到这一点,还是我需要切换到其他东西?

This is called the "multiple-choice knapsack problem". 这称为“多项选择背包问题”。

You can use an algorithm similar to the dynamic programming solution for the 0/1 knapsack problem. 您可以使用类似于动态编程解决方案的算法来解决0/1背包问题。

The 0/1 knapsack problem's solution is as follows: (from Wikipedia ) 0/1背包问题的解决方案如下:(来自Wikipedia

Define m[i, w] to be the maximum value that can be attained with weight less than or equal to w using items up to i . m[i, w]定义为重量小于或等于w使用i项可获得的最大值。
We can define m[i, w] recursively as follows: 我们可以递归定义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. 

The solution can then be found by calculating m[n,W] . 然后可以通过计算m[n,W]找到解决方案。 To do this efficiently we can use a table to store previous computations. 为了有效地做到这一点,我们可以使用一个表来存储以前的计算。

Now the extension is just to find the maximum of all choices instead. 现在,扩展名只是查找所有选择中的最大值。

For n players available as choices for some position i (with c_i_j being the cost of choice j and p_i_j being the points), we'd have: 对于n位置i可供选择的玩家( c_i_j是选择j的成本, p_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)

So, say we have: 所以,说我们有:

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

Then we'd have 2 positions "PG" and "SG" and each position will have 2 choices. 然后,我们将有2个职位“ PG”和“ SG”,每个职位将有2个选择。

Thus, for position "PG" (at i=1 ), we'll have: 因此,对于位置“ 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)

And for position "SG" (at i=2 ), we'll have: 对于位置“ 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)

First of all, excellent answer by Dukeling. 首先,达克林的出色回答。 I don't have the privilege of commenting, so I am writing an answer. 我没有发表评论的特权,所以我正在写答案。 This is in fact a "Multiple-Choice Knapsack Problem". 这实际上是一个“多选择背包问题”。 I implemented one of this kind of problem and ran it in Online Judge, where it was executed successfully. 我实现了其中一种问题,并在Online Judge中成功运行了该问题。 The only problem with Dukeling's algorithm is that it will not take into consideration that at least one item of previous set of items. 杜克林算法的唯一问题是,它不会考虑先前项目集中的至少一项。 So, from above : 因此,从上面:

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)`

This would only work for at most one of a kind. 这最多只适用于一种。 If you add a little check for zero, it will be perfect for exactly one item of each type, if for i=1 ("PG") : 如果您为零添加一点校验,那么对于i=1 (“ PG”)而言,它恰好适合每种类型的一项:

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)

For i=2 ("SG") : 对于i=2 (“ SG”):

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)

And, so on. 等等。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM