将 or 语句添加到 OR-Tools 约束CP-SAT 求解器

问题描述

所以我正在尝试在 OR 工具中构建一个类似于 employee scheduling 示例的调度工具。但是,就我而言,有十个班次要工作,我想通过确保前两个班次关闭或后两个班次关闭来防止人们每天工作 10 小时。

我想做这样的事情,但它一直说解决方案是不可行的。

all_nurses = range(5)
all_shifts = range(10)
all_days = range(20)

for n in all_nurses:
    for d in all_days:
        model.add(sum(shifts[(n,d,s)] for s in [0,1]) == 0 or sum(shifts[(n,s)] for s in [8,9]) == 0)

它真的不可行还是这段代码没有做我认为它在做的事情?


感谢 Laurent 帮我找到答案! 为了将来参考,在代码中它看起来像这样:

for n in all_nurses:
    for d in all_days:
        # Implement the contraint
        b = model.NewBoolVar(f'constr_{n}_{d}')
        model.add(sum(shifts[(n,1]) == 0).OnlyEnforceIf(b)
        model.add(sum(shifts[(n,1]) > 0).OnlyEnforceIf(b.Not())

        # Apply the contraint
        model.add(sum(shifts[(n,9]) == 0).OnlyEnforceIf(b.Not())

解决方法

请阅读https://github.com/google/or-tools/blob/stable/ortools/sat/doc/channeling.md

简而言之,or,and,min,max python 关键字没有正确解释。 在您的情况下, sum() == 0 将在对象上,因此在解析 python 代码时始终评估为 True。

您需要创建所有中间布尔变量,并在这些变量上添加 bool_or 约束。