简体   繁体   English

背包问题:用值替换所有项目

[英]Knapsack Problem: Replaces all items with value

I am trying to solve the knapsack problem by applying my own algorithm.我正在尝试通过应用我自己的算法来解决背包问题。 I give each item a score (values[i] - weights[i]) and add high score items to my knapsack.我给每个项目一个分数(values[i] - weights[i])并将高分项目添加到我的背包中。 But this code replaces each item with the first item of values (5).但是此代码将每个项目替换为值的第一项 (5)。

def knapsack(weights, values, capacity):
  knapsack = []
  scores = []
  for i in range(len(values)):
    score = values[i] - weights[i]
    scores.append(score)
  weight = 0
  while weight < capacity:
    if len(scores) != 0:
      valuable = max(scores)
      knapsack.append(values[scores.index(valuable)])
      weight += weights[scores.index(valuable)]
      scores.pop(scores.index(valuable))
    else:
      break
  return knapsack

weights = [1, 2, 4, 2, 5]
values  = [5, 3, 5, 3, 2]
capacity = 10

print(knapsack(weights, values, capacity))

What is wrong with this code?这段代码有什么问题?

Edit: I fixed it but there seems to be a logical error.编辑:我修复了它,但似乎存在逻辑错误。 If:如果:

weights = [8, 2,  6,  7, 9]
values  = [3, 11, 13, 7, 4]
capacity = 24

Then there are two items with the same score (8, 3 and 9, 4), but 9, 4 is better since it fits exactly into the knapsack and it has higher value.然后有两个项目得分相同(8、3和9、4),但9、4更好,因为它完全适合背包,价值更高。 Even changing line 8 to <= does not help.即使将第 8 行更改为 <= 也无济于事。

You are not removing the appended values from the list as well.您也没有从列表中删除附加值。 Try adding尝试添加

values.pop(scores.index(valuable))
weights.pop(scores.index(valuable))

to the line before scores.pop(...) .scores.pop(...)之前的行。

Additionally, you need to break out of the loop if the added item would make you over capacity, eg:此外,如果添加的项目会使您超出容量,您需要跳出循环,例如:

if (weight + weights[scores.index(valuable)]) > capacity:
    break

You need code to deal with tie-breakers, which reassigns the score index to the highest-valued item which fits under the capacity, eg:您需要处理决胜局的代码,它将分数索引重新分配给适合容量的最高价值项目,例如:

ties = [i for i, x in enumerate(scores) if x == valuable]
if len(ties) > 1:
    most_valuable = -1
    for idx in ties:
        if values[idx] > most_valuable and (weight + weights[idx]) <= capacity:
            most_valuable = values[idx]
            scores_idx = idx

Full code:完整代码:

def knapsack(weights, values, capacity):
    knapsack = []
    scores = []
    for i in range(len(values)):
        score = values[i] - weights[i]
        scores.append(score)
    weight = 0
    while weight < capacity:
        if len(scores) != 0:
            valuable = max(scores)
            scores_idx = scores.index(valuable)
            ties = [i for i, x in enumerate(scores) if x == valuable]
            if len(ties) > 1:
                most_valuable = -1
                for idx in ties:
                    if values[idx] > most_valuable and (weight + weights[idx]) <= capacity:
                        most_valuable = values[idx]
                        scores_idx = idx
            if (weight + weights[scores_idx]) > capacity:
                break
            knapsack.append(values[scores_idx])
            weight += weights[scores_idx]
            values.pop(scores_idx)
            weights.pop(scores_idx)
            scores.pop(scores_idx)
        else:
            break
    return knapsack

#  weights = [1, 2, 4, 2, 5]
#  values  = [5, 3, 5, 3, 2]
#  capacity = 10
weights = [8, 2, 6, 7, 9]
values = [3, 11, 13, 7, 4]
capacity = 24

print(knapsack(weights, values, capacity))

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

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