为了账号安全,请及时绑定邮箱和手机立即绑定

如何表示约束(A && B)|| (C&&D) || (E && F) ||

如何表示约束(A && B)|| (C&&D) || (E && F) ||

互换的青春 2022-06-14 16:10:12
我是 or-tools 的新手,我正在尝试表示约束:(!A && !B) || (!C && !D) || (!E && !F) || ...我尝试了以下方法(在我的情况下,A 是 shift_0LM0,B 是 shift_0LT0,C 是 shift_0MM0,D 是 shift_0MT0,...),将 !A && !B 表示为 A + B == 0,即。!(A || B):    for week in range(4):        for employee in range(5):            model.AddBoolOr([                shift[f'{week}{weekday}M{employee}'] + shift[f'{week}{weekday}T{employee}'] == 0                for weekday in 'LMXJVSD'            ])但我得到了错误:TypeError: NotSupported: model.GetOrMakeBooleanIndex((shift_0LM0 + shift_0LT0) == 0有没有一种简单的方法来表达这个约束?
查看完整描述

1 回答

?
料青山看我应如是

TA贡献1772条经验 获得超8个赞

正如 Laurent 所说, AddBoolOr 需要布尔文字,因此您必须创建中间变量:


from ortools.sat.python import cp_model


model = cp_model.CpModel()

a, b, c, d = [model.NewBoolVar(x) for x in 'abcd']


not_a_not_b = model.NewBoolVar('!A && !B')

model.Add(a+b == 0).OnlyEnforceIf(not_a_not_b)


not_c_not_d = model.NewBoolVar('!C && !D')

model.Add(c+d == 0).OnlyEnforceIf(not_c_not_d)


model.AddBoolOr([not_a_not_b, not_c_not_d])


solver = cp_model.CpSolver()

solver.Solve(model)


for x in [a, b, c, d]:

    print(solver.Value(x))

编辑:对于 (A && B) || (C && D) 只是a+b == 0变成a+b == 2


如果您想在搜索所有解决方案时避免重复的解决方案,您必须添加其他含义:


model.Add(a+b != 0).OnlyEnforceIf(not_a_not_b.Not())


查看完整回答
反对 回复 2022-06-14
  • 1 回答
  • 0 关注
  • 150 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信