如何在 OR 工具中使用 AddBoolXOr

问题描述

我尝试了解 OR 工具。我想以模 2 求解这个方程组:

x1 + x2 + x3 + 0  = 0
x1 + x2 + 0  + x4 = 1
x1 + 0  + x3 + x4 = 1
0  + x2 + x3 + x4 = 1

这等同于模 2:

x1 ^ x2 ^ x3 = 0
x1 ^ x2 ^ x4 = 1
x1 ^ x3 ^ x4 = 1
x2 ^ x3 ^ x4 = 1

使用按位异或(见 here)。

所以我尝试了以下代码

from ortools.sat.python import cp_model

# Creates the model.
model = cp_model.CpModel()

# Creates the variables.
x1 = model.NewBoolVar('x1')
x2 = model.NewBoolVar('x2')
x3 = model.NewBoolVar('x3')
x4 = model.NewBoolVar('x4')

# Creates the constraints.
model.AddBoolXOr(x1 ^ x2 ^ x3 == 0)
model.AddBoolXOr(x1 ^ x2 ^ x4 == 1)
model.AddBoolXOr(x1 ^ x3 ^ x4 == 1)
model.AddBoolXOr(x2 ^ x3 ^ x4 == 1)

# Creates a solver and solves the model.
solver = cp_model.cpsolver()
status = solver.solve(model)

if status == cp_model.OPTIMAL:
    print('x1 = %i' % solver.Value(x1))
    print('x2 = %i' % solver.Value(x2))
    print('x3 = %i' % solver.Value(x3))
    print('x4 = %i' % solver.Value(x4))

但我明白了:

'不支持对线性表达式调用异或,' NotImplementedError: 不支持对线性表达式调用 xor,请使用 CpModel.AddBoolXor

如果我使用 AddBoolXor 而不是 AddBoolXOr 我得到:

AttributeError: 'CpModel' 对象没有属性 'AddBoolXor'

解决方法

AddBoolXor 接受一个布尔文字数组。

model.AddBoolXOr([x1,x2.Not(),x3])

AddBoolXor(xi) 的语义是 sum(xi) % 2 == 1

所以,就你而言

# Creates the constraints.
model.AddBoolXOr([x1,x2,x3,True])
model.AddBoolXOr([x1,x4])
model.AddBoolXOr([x1,x4])
model.AddBoolXOr([x2,x4])