为啥 AddMultiplicationEquality 仅限于 2 个变量?

Posted

技术标签:

【中文标题】为啥 AddMultiplicationEquality 仅限于 2 个变量?【英文标题】:Why is the AddMultiplicationEquality limited to only 2 variables?为什么 AddMultiplicationEquality 仅限于 2 个变量? 【发布时间】:2019-08-26 16:08:33 【问题描述】:

我正在构建一个具有一组复杂约束的班次调度程序,并且为此使用 CP-SAT 求解器。我有一个这样的数组:

    num_vals = 3
    for n in all_employees:
        for d in all_timeslots:
            shifts[(n, d)] = model.NewIntVar(0, num_vals - 1, 'shift_n%id%i' % (n, d))

我试图设置一个约束,其中 5 个 IntVar 值的结果行的乘积始终等于 0,所以我使用这样的东西:

        sq_r = model.NewIntVar(0, 1,'sq_r')
        for wind in range(0,11):
            model.AddMultiplicationEquality(sq_r, [shifts[(n, wind)], shifts[(n, wind+1)], shifts[(n, wind+2)], shifts[(n, wind+3)], shifts[(n, wind+4)]])

但我收到以下错误:

Check failed: vars.size() == 2 (5 vs. 2) General int_prod not supported yet.
*** Check failure stack trace: ***
    @   00007FF98D2B8C45  PyInit__pywrapsat
    @   00007FF98D2B6F82  PyInit__pywrapsat
    @   00007FF98D550E50  PyInit__pywrapsat
    @   00007FF98D54D8FF  PyInit__pywrapsat
....

我已经检查了http://google.github.io/or-tools/python/ortools/sat/python/cp_model.html 上的文档以及此处和 github 上的一些示例,但从未找到任何在变量列表中找到超过 2 个项目的示例,尽管文档显示以下内容:

def AddMultiplicationEquality(self, target, variables)
Adds target == variables[0] * .. * variables[n]

知道可能是什么问题吗?

【问题讨论】:

就像它说的那样,它还没有实现。我猜他们本来打算更通用并将其放入文档中,但一直没有时间去做。 没错,我从来没有找到一个用例,你的也不例外。在您的情况下,prod == 0 等效于一个 var is == 0。您可以为每个等效于 var == 0 的 var 设置一个布尔变量,并在这些布尔变量上添加一个 bool_or。 5个变量的乘法会更有效。见github.com/google/or-tools/blob/stable/ortools/sat/doc/…。 【参考方案1】:
num_vals = 3
for n in all_employees:
    for d in all_timeslots:
        shifts[(n, d)] = model.NewIntVar(0, num_vals - 1, 'shift_n%id%i' % (n, d))
        shifts_is_zero[(n, d)] = model.NewBoolVar('shift_is_zero_n%id%i' % (n, d))
        model.Add(shifts[(n, d)] == 0).OnlyEnforceIf(shifts_is_zero[(n, d)])
        model.Add(shifts[(n, d)] > 0).OnlyEnforceIf(shifts_is_zero[(n, d)].Not())

然后

    for wind in range(0,11):
        model.AddBoolOr([shifts_is_zero[(n, wind)], shifts_is_zero[(n, wind+1)], shifts_is_zero[(n, wind+2)], shifts_is_zero[(n, wind+3)], shifts_is_zero[(n, wind+4)]])

【讨论】:

以上是关于为啥 AddMultiplicationEquality 仅限于 2 个变量?的主要内容,如果未能解决你的问题,请参考以下文章

为啥 DataGridView 上的 DoubleBuffered 属性默认为 false,为啥它受到保护?

为啥需要softmax函数?为啥不简单归一化?

为啥 g++ 需要 libstdc++.a?为啥不是默认值?

为啥或为啥不在 C++ 中使用 memset? [关闭]

为啥临时变量需要更改数组元素以及为啥需要在最后取消设置?

为啥 CAP 定理中的 RDBMS 分区不能容忍,为啥它可用?