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。
示例:
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。