【问题标题】:Choosing items only once subject to slot constraints只选择一次受槽约束的项目
【发布时间】:2019-02-07 16:43:59
【问题描述】:

我有一组许多 (10000+) 项,我必须从中准确选择 k 项。我只能选择每个项目一次。

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

item = ('item code', cost, profit, slot_1, slot_2, ...., slot_N) 举个例子

vase = ['000001', 1000, 10000, 1, 0, ..., 0]

plate = ['000002', 10, 5, 0, 1, ..., 0]

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

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

我的利润和成本也是清单:

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

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

我表示一个项目是否可以在 slot_j 中作为列表列表:

slots = []

for j in NUM_SLOTS:
    slot[j, :] = [x[3+j] for x in items]

我的问题是具有相同代码的项目可以出现在多个插槽中,但无论插槽如何,都只能选择一次。

即。 vase = ['000001', 1000, 10000, 1, 0, ..., 1]

我很困惑如何添加一个项目在多个插槽中可用时只能选择一次的约束。

每个插槽只能选择一项。

整个程序如下供参考。

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)

### Only choose one item per slot
for i in range(1, num_slots):
    slot = slots[:, i]
    solver.Add(solver.Sum([x[j] * slot[j] for j in range(MAX_ITEMS)]) == 1)

solver.Maximize(solver.Sum([profits[i] * x[i] for i in 
range(total_chosen)]))
sol = solver.Solve()

【问题讨论】:

  • 这听起来像Multi-Dimensional Knapsack Problem,其中成本是您的第一个维度(如果成本是有界的,这并不完全清楚),每个插槽是另一个维度,最大容量为 1,每个项目该维度的权重为 0 或 1。
  • 仔细检查后,该问题甚至没有说明每个插槽是否可以选择多个项目。我发现这有点不言自明,也许您因此而忘记明确提及这一点,但是请您澄清一下吗?
  • 每个插槽只能选择一项

标签: python or-tools


【解决方案1】:

我通过为每个唯一代码添加一个虚拟对象来解决这个问题:

valid = pd.DataFrame(data=[x for x in l ], columns=['code', 'slot', 'cost', 'score'])

code_dummies = pd.get_dummies(valid['code'].unique())

valid = pd.concat([valid, code_dummies], axis=1)

然后添加以下约束:

codes = valid['code'].unique()
for i in range(len(codes)):
    code = valid[codes[i]]
    solver.Add(solver.Sum([x[j] * code[j] for j in range(num_recipes)]) <= 1)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-17
    • 1970-01-01
    • 2013-07-08
    • 2018-10-25
    • 2016-01-18
    相关资源
    最近更新 更多