使用重复项约束优化



我有一组许多(10000+(项,我必须从中准确地选择k项。受排序约束,我只能多次选择每个项目:如果我在位置1选择一个项目,我要到位置21才能选择。我的物品既有利润,也有成本。

每个项目都表示为一个元组:

item = ('item name', cost, profit)

作为的一个例子

vase = ['Ming Vase', 1000, 10000]
plate = ['China Plate', 10, 5]

并且项目的总集合是列表列表:

items = [item1, item2, ..., itemN].

我的利润和成本也在列表中:

profits = [x[2] for x in items]
costs = [x[1] for x in items]

对于所选的每个项目,它都需要有一个最小值,并且该项目不能在接下来的19个项目中重复使用。我想根据这个限制选择k个最便宜、价值最高的商品,但我很难制定它。

我在使用谷歌或工具制定这个问题时遇到了麻烦。以下只是在没有任何额外约束的情况下获得最佳k(在本例中为100(

from ortools.linear_solver import pywraplp
solver = pywraplp.Solver('SolveAssignmentProblemMIP',
pywraplp.Solver.CBC_MIXED_INTEGER_PROGRAMMING)
x = {}
for i in range(MAX_ITEMS):
x[i] = solver.BoolVar('x[%s]' % (i))
#Define the constraints 
total_chosen = 100
solver.Add(solver.Sum([x[i] for i in range(MAX_ITEMS)]) == total_chosen)
max_cost = 5.0
for i in range(num_recipes):
solver.Add(x[i] * cost[i] <= max_cost)
solver.Maximize(solver.Sum([profits[i] * x[i] for i in range(total_chosen)]))
sol = solver.Solve()

我可以通过以下方式获得我选择的项目集:

for i in range(MAX_ITEMS):
if x[i].solution_value() > 0:
print(item[i].item_name)

在制定约束条件和目标方面的任何帮助都将非常有用。谢谢

solver.Add(x[i] * cost[i] <= max_cost)

这种限制意味着我们根本不想购买昂贵的商品。因此,我们可以在优化之前排除具有cost[i] > max_cost的项目。

Sum([profits[i] * x[i])

如果没有其他约束,则该目标要求获得最佳项目total_chosen次。但我们不能经常重复项目。因此,我们需要20个成本低于max_cost的最佳项目,并将其重复total_chosen/20次。

import numpy
MAX_ITEMS = 10000
cost = numpy.random.randint(1, 100, MAX_ITEMS)
profits = numpy.random.randint(1, 100, MAX_ITEMS)
total_chosen = 100
repeat = 20 
max_cost = 5.0
cheap = [i for i in range(MAX_ITEMS) if costs[i] <= max_cost]
chosen = sorted(cheap, key=lambda i: profits[i], reverse=True)[:repeat]
for _ in range(total_chosen/repeat):
for i in chosen:
print(i, costs[i], profits[i])

使用OR工具,它将看起来像

import numpy
from ortools.linear_solver import pywraplp
solver = pywraplp.Solver('SolveAssignmentProblemMIP',
pywraplp.Solver.CBC_MIXED_INTEGER_PROGRAMMING)
MAX_ITEMS = 10000
costs = numpy.random.randint(1,100,MAX_ITEMS)
profits = numpy.random.randint(1,100,MAX_ITEMS)
total_chosen = 100
repeat = 20
max_cost = 5.0
x = {}
for i in range(MAX_ITEMS):
x[i] = solver.BoolVar('x[%s]' % (i))
solver.Add(solver.Sum([x[i] for i in range(MAX_ITEMS)]) == repeat)
for i in range(MAX_ITEMS):
solver.Add(x[i] * costs[i] <= max_cost)
solver.Maximize(solver.Sum([profits[i] * x[i] for i in range(MAX_ITEMS)]))
sol = solver.Solve()
for i in range(MAX_ITEMS):
if x[i].solution_value() > 0:
print(i, profits[i], costs[i])

一个想法是,如果您为前20个对象创建了一个最佳解决方案,您能重复该模式直到序列结束吗?

如果是,请按价值对您的项目进行排序,即20个最佳,然后重复该顺序。

最新更新