如果条件与 OR-Tools CP Solver 一起应用约束

Posted

技术标签:

【中文标题】如果条件与 OR-Tools CP Solver 一起应用约束【英文标题】:Apply a constraint if condition with OR-Tools CP Solver 【发布时间】:2018-07-16 08:44:59 【问题描述】:

我正在为 Job-Shop 问题实施一个类似的解决方案,但有一个区别:我不知道必须执行每项任务的机器。解决这个问题也是问题的一部分。事实上,我们可以说,我正在尝试解决护士问题和工作车间问题的结合。

更具体地说,我有一些持续时间为 D 的任务 T,由于其性质 N(比如说前端任务、后端任务等),必须由某些特定员工 E 以特定顺序 O 执行.

我有:

一个 T int 变量数组,可以获取 E 范围内的值(将执行任务的员工)。 一组固定的持续时间间隔变量(在知道其持续时间 D 的情况下安排它们)。 E 序列变量应该是员工将要执行的任务序列(间隔变量)。 任务和员工之间的关系 N 的一些约束。 O 阶的一些其他限制。

解决这个问题的方法是:首先解决分配问题,然后安排任务。我已经做到了。

但是我想将它作为一个独特的解决方案来实施。

我被困在这个:如何创建一个依赖于我之前创建的 int vars 的析取约束?

致需要看代码的人:

for i in range(number_employees):
    disj = solver.DisjunctiveConstraint([interval_var[task_id] if int_var[task_id] == i] ,'i_name')
   [...]

当然,这是行不通的。

如果有任何建议,我将不胜感激。

【问题讨论】:

你尝试过使用AddAllDiferents(intvars)方法吗? 也许你应该看看github.com/google/or-tools/blob/master/examples/cpp/…,即你可以创建几个集合重用相同的任务来获得不同的disjunctiveConstraint集合...... 【参考方案1】:

应该看看 CP-SAT 求解器。 它支持半具体化的约束。

即(在python中):

model.AddNoOverlap([区间列表]).OnlyEnforceIf(boolvar)

model.Add(x == i).OnlyEnforceIf(boolvar)

model.Add(x != i).OnlyEnforceIf(boolvar.Not())

见:https://github.com/google/or-tools/blob/master/ortools/sat/doc/index.md

【讨论】:

【参考方案2】:

Laurent Perron,我修改了no_overlap_sample_sat.py 以遵循您的建议,但它不起作用。我修改的是:

# No Overlap constraint.
boolvar = model.NewBoolVar('boolvar')
i = model.NewIntVar(0, 10, 'i')
x = model.NewIntVar(0, 10, 'x')
model.Add(i - x == 0)
model.AddNoOverlap(
    [task_0, task_1, task_2, weekend_0, weekend_1, weekend_2]).OnlyEnforceIf(boolvar)
model.Add(x == i).OnlyEnforceIf(boolvar)
model.Add(x != i).OnlyEnforceIf(boolvar.Not())

输出是:

求解器以非最佳状态退出:1

您还有什么建议吗?

【讨论】:

以上是关于如果条件与 OR-Tools CP Solver 一起应用约束的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 or-tools 在 bool 数组中制作 K 个不同的元素?

如何在 or-tools 中定义复杂的目标函数?

OR-Tools MIP Solver - 根据 int 定义目标,而不是 IntVar

or-tools python中的变量除法

Or-Tools CP-SAT 求解器导出/导入:加载模型后如何访问变量?

CP-Sat 的 OR-Tools 优化