我正在尝试针对以下情况找到最佳算法:我有许多不同的产品,每个产品有4个方案(彼此无关)以及该方案的成本和收入。例如:
然后,我想找到方案的最佳组合,以便它在不超过给定成本约束的情况下返回最多的收入。例如。我希望它返回:
我考虑过创建每种可能的组合并计算每种组合的成本和收入(并且只选择成本<£x的最大收入),但是组合太多了,因为我有大约120种产品和5种方案(宇宙中有原子。
有人知道有什么算法可以对最佳方案做出最佳猜测吗?
非常感谢
答案 0 :(得分:3)
这是著名的运筹学问题的一个版本,称为“ The Knapsack Problem”。
通常,这是一个“ NP-Hard”问题,因此没有已知的方法可以有效,最佳地解决此问题。 (而且您的版本比基本问题还要难。)
如果仍然需要最佳解决方案,则可以使用整数编程优化器/求解器来求解以下模型:
maximize sum( Revenue_ik * I_ik ) over all product-scenarios i,k # maximize revenue
s.t.
sum( Cost_ik * I_ik ) over all product-scenarios i,k <= BUDGET # Total cost should be lower than the budget
sum( I_ik ) over all scenarios k <= 1 for all products i # Choose at most 1 scenario per product (we can make it equals if we *have* to choose)
I_ik in {0, 1} # Decision variables are binary: not choose or choose
话虽这么说,还有其他方法可以找到一个好的解决方案。例如,您可以使用试探法和本地搜索方法,例如:
此外,通常存在伪多项式算法来解决这类问题。对于您而言,(除非我丢失了某些东西)以下动态编程关系成立:
f(i, w) = max revenue possible using products 0...i, which costs at most w.
f(i, w) = max{ f(i-1, w) , f(i-1, w-Cost_ik) + Revenue_ik for each scenario k for product i }
f(-1, w) = 0 # base case
f(i, w) = -INFINITY if w < 0 # base case
如果最大预算W是合理的,则此算法可以非常有效地找到最佳解决方案。例如,下面是一个Python代码段,该代码段可以以275美元的预算最佳地解决您的当前实例:
cache = {}
chosen = {}
revenue = [[0, 200, 240, 250], [0, 207, 257, 398], [0, 115, 400, 350], [0, 240, 300, 340]]
cost = [[0, 30, 40, 60], [0, 35, 38, 70], [0, 110, 160, 240], [0, 80, 200, 350]]
scenarios = [[0, 1, 2, 3], [0, 1, 2, 3], [0, 1, 2, 3], [0, 1, 2, 3]]
BUDGET = 275
def f(i, w):
if w < 0:
return -10000000
if i == -1:
return 0
if (i, w) in cache:
return cache[(i, w)]
vals = [f(i - 1, w - cost[i][k]) + revenue[i][k] for k in scenarios[i]]
max_val = max(vals)
chosen_scenario = vals.index(max_val)
chosen[(i, w)] = chosen_scenario
cache[(i, w)] = max_val
return max_val
print(f(3, BUDGET))
result = []
W = BUDGET
for i in reversed(range(len(scenarios))):
chosen_scenario = chosen[(i, W)]
result.append(chosen_scenario)
W -= cost[i][chosen_scenario]
result.reverse()
print(result)
输出:
1038
[2, 3, 2, 0]
最大可能的收入是1038,依次为每种产品选择方案2、3、2和0。