我正在使用 CP-SAT 求解器通过 python 进行优化。
我有一定数量的 IntVar,它们的名称代表事件。我希望每个变量之间的延迟最小,而事件中没有任何特定的顺序。我已经尝试了很多事情,但我最接近的解决方案是使用这样的布尔变量(我尝试过使用abs(),但似乎库不接受它):
dictio_bool[k] = model.NewBoolVar('') #dictio_bool 是一个存储布尔变量的字典 dictio_bool[k + 1] = model.NewBoolVar('')
model.Add(date[event1] > delay + date[event2]).OnlyEnforceIf(dictio_bool[k]) #date 是存储 intvars 的字典
模型.添加(日期[事件1] < delay + date[event2]).OnlyEnforceIf(dictio_bool[k + 1])
model.AddBoolXOr([dictio_bool[k], dictio_bool[k + 1]])
但是,当我使用它时,代码总是决定将第一个布尔值设置为 False,将第二个布尔值设置为 True。我还有很多其他有效的约束。抱歉,我可能有点困惑,但是你知道如何让代码根据其他约束选择 bool 的状态,而不是总是 0 然后 1 吗?
更准确地说,如何为某些 intvars 设置不同的值,并且它们之间的数量最小且没有特定的顺序?
对于abs,你需要编写(我使用CP-SAT 9.9 python API)
model.add_abs_equality(target_expr, expr)
当所有表达式的形式均为 a * var + b(a, b 整数)时。所以 x, x - 5, 3 * x 都是有效的。
此外,要编写析取运算,只需使用单个布尔变量即可。
model.add(x < y + delay).only_enforce_if(b)
model.add(y < x + delay).only_enforce_if(~b)
使用 bool_xor 将强制所有文字交替 (true, false, true, false...) 或 (false, true, false, true, ...)