给出一组代表(成本,收益)的样本数据
items = [ (1000, 300), (500, 150), (400, 120), (300, 100), (200, 50), (55, 25) ]
我有一个算法可以找到这些项目的倍数的最佳组合来填充给定的费用
f(items,capacity,maxCost)
将生成一个条目,指定受容量和成本约束的最有效数量的项目。
class BestCombo(object):
def __init__(self, items, qtyLimit, costLimit):
self.bestPerf = 0
self.best = None
self.items = items
self.qtyLimit = qtyLimit
self.costLimit = costLimit
self._findBest(load=[], qty=0, cost=0, perf=0)
def _findBest(self, load, qty, cost, perf):
idx = len(load)
if idx >= len(self.items):
if qty <= self.qtyLimit and cost <= self.costLimit:
if perf > self.bestPerf:
self.bestPerf = perf
self.best = list(load)
return
item = self.items[idx]
maximum = min(self.qtyLimit - qty, (self.costLimit - cost) // item[0])
for q in range(0, maximum + 1):
self._findBest(load + [[item, q]], qty + q, cost + item[0] * q, perf + item[1] * q)
items = [ (1000, 300), (500, 150), (400, 120), (300, 100), (200, 50), (55, 25) ]
print("3, 900")
print(BestCombo(items, 3, 900).best)
print("3, 1100")
print(BestCombo(items, 3, 1100).best)
print("3, 3000")
print(BestCombo(items, 3, 3000).best)
print("10, 900")
print(BestCombo(items, 10, 900).best)
print("42, 21000")
print(BestCombo(items, 42, 21805).best)
所以这会产生一个最好的&#39;这表示3个单位的900穿孔最适合(300,100)项中的3个,而3,1100最佳的1x500和2x300。
虽然这种方法有效,但对于非平凡的值来说,它的速度非常慢。
我尝试过多种变体,包括基于产量的变体,但它们都会因某些变异而变慢(我似乎无法想出一个很好的方法来实现产量并没有#&# 39;在其生命周期中生成一个荒谬的数量的列表)
&#34; items&#34;列表最多可能有64-90项,容量不可能超过255.
我似乎记得过去使用算法来解决这个问题,但也许是因为我对Python比较新,而且我在Python中这样做,我在那里画了一个空白。
是否有可能非暴力强制查找?
答案 0 :(得分:1)
这看起来很像http://en.wikipedia.org/wiki/Knapsack_problem。在一般情况下,这将需要指数时间,但其中一种动态编程方法可能会变得切合实际,特别是如果您准备完善一些数字以获得圆形数字问题的精确答案,这将是一个对您的问题的近似答案。