【问题标题】:Python Knapsack with Constraint by Type具有类型约束的 Python 背包
【发布时间】:2013-10-17 01:13:28
【问题描述】:

这是我从here 参加的 MIT 公开课程中学习的一个简单的背包问题。

脚本针对权重和值进行了优化,但我希望它进行优化,这样就不会出现类重复。因此,例如,如果我的上限为 10,它将返回 w[0] v[0] c[0] and w[2] v[2] c[2] 而不是 w[0] v[0] c[0] and w[1] v[1] c[1] and w[2] v[2] c[2]

weight= [5,3,2]
value = [9,7,8]
the_class = ["A","C","C"]
cap = 5

'''
w = the weight of item
v = the value of item
i = index of the item
aW = availible weight left (cap - w[i])
c = class of item
'''

def maxVal(w, v, i, aW,c): 
    if i == 0: 
        if w[i] <= aW: 
            return v[i] 
        else: 
            return 0 
    without_i = maxVal(w, v, i-1, aW, c) 
    if w[i] > aW: 
        return without_i 
    else: 
        with_i = v[i] + maxVal(w, v, i-1, aW - w[i], c) 

    return max(with_i, without_i)

res = maxVal(weight,value, len(value)-1, cap, the_class)
print "The result: ",res

【问题讨论】:

  • 它不应该产生 repeats - 是吗?权重为 2 且值为 8 的类“C”与“C”/7/3 是同一类吗?从数据中删除错误值可能会更好。
  • @wwii 是的,他们是同一个班级。但我需要该程序只参加每个班级的 1 个。
  • 你怎么知道该拿哪一个?还是有关系 - 只拿一个?
  • @wwii 你会选择价值较高的那个,因为这是在给定权重的情况下优化价值。
  • 在运行优化之前通过删除价值较低的重复数据来预处理数据可能更容易、更有效。

标签: python dynamic-programming knapsack-problem


【解决方案1】:

首先从列表中删除不需要的项目。

import itertools as it
from operator import itemgetter
weight= [5,3,2]
value = [9,7,8]
the_class = ["A","C","C"]
cap = 5

# define functions to sort with
classitem = itemgetter(0)
valueitem = itemgetter(1)
weightitem = itemgetter(2)

# combine the list elements to keep them together
classes = zip(the_class, value, weight)
classes.sort(key = classitem)

# use itertools.groupby() to aggregate the classes
for k, g in it.groupby(classes, classitem):
    things = list(g)
    print k, len(things)
    # remove the least valuable duplicates from the class list
    if len(things) > 1:
        things.sort(key = valueitem)
        for thing in things[:-1]:
            classes.remove(thing)

# reconstruct the original lists, sans unwanted duplicates
the_class = map(classitem, classes)
value = map(valueitem, classes)
weight = map(weightitem, classes)

【讨论】:

  • 抱歉,这不起作用,因为权重、值和类列表的大小是可变的。
  • 你是说len(the_class) != len(weight) != len(values)吗?这应该适用于任何长度的列表 - 它确实假设三个列表的长度相同 - 如果它们的长度不同,那就没有意义了。你试过了吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-03-22
  • 2013-09-19
  • 2018-05-16
  • 1970-01-01
  • 2018-03-05
  • 1970-01-01
相关资源
最近更新 更多