or-tools 如何在这种情况下使用 OnlyEnforceIf

or-tools how to use OnlyEnforceIf in this case

示例:

boolVar = 
[[2,0,0,2],
 [0,0,0,0],
 [0,1,0,0],
 [0,0,1,0]]

对于每个子数组,总和可以大于3或0

我试过使用 OnlyEnforceIf,但是 OnlyEnforceIf 将 boolvar 作为参数,我该怎么做?

for i in range(n):
  model.Add(sum(result[i]) > 3).OnlyEnforceIf(sum(result[i]) > validMinSum)
  model.Add(sum(result[i]) == 0).OnlyEnforceIf(sum(result[i]) == 0)

我得到的错误是AttributeError: 'BoundedLinearExpression' object has no attribute 'Index'

详细说明@Stradivari 的评论和他发布的 link:您需要构造一个布尔变量,该变量强制等效于您想要的表达式。例如:

// Implement b == (x >= 5).
model.Add(x >= 5).OnlyEnforceIf(b);
model.Add(x < 5).OnlyEnforceIf(b.Not());

或者就你的问题而言:

# ... assuming result is already defined as IntVar[][] jagged array
sum_greater_than_min = model.NewBoolVar("Sum > validMinSum");
model.Add(LinearExpression.Sum(result[i]) > 3).OnlyEnforceIf(sum_greater_than_min);
model.Add(LinearExpression.Sum(result[i]) <= 3).OnlyEnforceIf(sum_greater_than_min.Not);
sum_equal_zero = model.NewBoolVar("Sum==0");
model.Add(LinearExpression.Sum(result[i]) == 0).OnlyEnforceIf(sum_equal_zero);
model.Add(LinearExpression.Sum(result[i]) != 0).OnlyEnforceIf(sum_equal_zero.Not);
# Now enforce that one of the booleans must be true
a = model.NewBoolVar("");
model.AddMinEquality(a, [sum_greater_than_min, sum_equal_zero])); 
model.Add(a == 1);

根据@Stradivari 的评论进行编辑以仅使用一个 BoolVar 进行简化(并更正了上面的错字):

# ... assuming result is already defined as IntVar[][] jagged array
sum_greater_than_min = model.NewBoolVar("Sum > validMinSum");
model.Add(LinearExpression.Sum(result[i]) > 3).OnlyEnforceIf(sum_greater_than_min);
model.Add(LinearExpression.Sum(result[i]) == 0).OnlyEnforceIf(sum_greater_than_min.Not);

如果 sum_greater_than_min 为假,则约束 sum == 0 被强制执行。如果为真,则强制 sum > 3。