我使用 PyChoco。 我有三个 0 和 1 的向量,分别名为 O1、O2、O3,我想编写约束:
O3 = (01 + O2) %2
我做过的最好的:
O1 = model.intvars(2,0,1)
O2 = model.intvars(2,0,1)
O3 = model.intvars(2,0,2)
for k in range(2) :
model.arithm(O1[k], '+', O2[k], '=', O3[k])
但是 O3 的组成部分是 O,1 或 2,因为我没有成功添加 %2。
要添加 %2,您需要在模型中添加“mod”约束。为此,您必须消除约束。展平是一种非常常见的操作,必须在建模期间完成,以便以解算器接受的方式设置约束。
在您的情况下,这意味着您必须添加一个新的辅助变量来表示表达式 O1[k] + O2[k],即 O1[k], '+', O2[k] = AUX1。
然后另一个辅助变量将表示表达式 AUX1%2 (即 (O1[k] + O2[k]) % 2):AUX1 % 2 = AUX2
然后,您将使用算术约束中的最后一个辅助变量(AUX2)。
但是,我建议使用建模语言,您可以根据需要发布约束,并且特定求解器的扁平化负担由建模语言承担。
Python 中的一个示例是 CPMpy,它支持 choco 求解器,以及更多求解器,例如 ortools CP-SAT。
以下是如何使用 pychoco 在 cpmpy 中执行此操作:
import cpmpy as cp
O1 = cp.intvar(0,1,shape=2)
O2 = cp.intvar(0,1,shape=2)
O3 = cp.intvar(0,2,shape=2)
model = cp.Model()
model += (O1 + O2) % 2 == O3
# The above is the same as using the following for loop as cpmpy variables are based in numpy
#for k in range(2) :
# model += (O1[k] + O2[k]) % 2 == O3[k]
model.solve("choco")