【问题标题】:Order constraints in optimisation优化中的顺序约束
【发布时间】:2018-11-06 16:07:10
【问题描述】:

我有一组 (10000+) 个项目,我必须从中选择 20 个项目。我只能选择每个项目一次。我的项目有利润和成本,以及几个布尔属性(例如颜色)。我需要按特定顺序输出结果:特别是我需要第一项和第三项为蓝色,第二项和第四项为红色。

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

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

举个例子

vase = ['Ming Vase', 1000, 10000, 0, 1]

plate = ['China Plate', 10, 5, 1, 0]

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

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

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

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

对于每个选择的项目,它需要有一个最小值,并且至少 5 个项目的属性 (is_blue) 标志必须设置为 1。

我想选择价值最高的 20 个最便宜的项目,其中 5 个的 is_blue 标志设置为 1,第一个和第三个项目是蓝色的(等等)。

我无法使用 google OR 工具来制定这个。

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 = 20
solver.Add(solver.Sum([x[i] for i in range(MAX_ITEMS)]) == total_chosen)

blues = [x[3] for x in items]
solver.Add(solver.Sum([blues[i] * x[i] for i in . 

范围(MAX_ITEMS)]) >= 5)

max_cost = 5.0

for i in range(MAX_ITEMS):
    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)

这很好用 - 它选择了 20 个项目,这些项目在成本限制的情况下最大化利润,但我坚持如何将其扩展到选择项目,以保证第一个是蓝色等。

在制定约束和目标方面的任何帮助都会非常有帮助。谢谢!

【问题讨论】:

  • 你为什么关心第一个是蓝色的?您将至少有 5 个蓝色项目,因此只需将您的解决方案重新排序,第 1 和第 3 个项目为蓝色

标签: python-3.x optimization or-tools mixed-integer-programming


【解决方案1】:

不要使用 BoolVar 来表示所选项目,而是考虑制作一个包含 20 个 IntVar 且域为 0..MAX_ITEMS 的列表。从那里做这样的事情应该很容易:

solver.Add(chosens[0].IndexOf(all_items)[3] == 1)
solver.Add(chosens[2].IndexOf(all_items)[3] == 1)

chosens[i].IndexOf(all_items) 仅表示 all_items[IndexOfChosen],即:为第 I 个位置选择的任何项目。如果您采用这种方法,请不要忘记 MakeAllDifferent!

【讨论】:

  • @Tom Kealy 还可以考虑使用 cp_sat,因为它更闪亮、更优越,而且在大多数情况下更快。
猜你喜欢
  • 1970-01-01
  • 2012-12-08
  • 2011-07-23
  • 2017-11-13
  • 2014-07-13
  • 1970-01-01
  • 2012-02-17
  • 2020-01-17
  • 2021-12-28
相关资源
最近更新 更多