Example:
boolVar =
[[2,0,0,2],
[0,0,0,0],
[0,1,0,0],
[0,0,1,0]]
For every sub-array, the sum could be greater than 3 or 0
I have tried using OnlyEnforceIf
, but OnlyEnforceIf takes an boolvar as a parameter, how can I do this?
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)
The error i got is AttributeError: 'BoundedLinearExpression' object has no attribute 'Index'
CodePudding user response:
Elaborating on @Stradivari 's comment and the link he posted: You need to construct a boolean variable that is enforced to be equivalent to the expression you want. For example:
// Implement b == (x >= 5).
model.Add(x >= 5).OnlyEnforceIf(b);
model.Add(x < 5).OnlyEnforceIf(b.Not());
Or in terms of your question (untested, I don't have a Python installation):
# ... 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);
Edit based on @Stradivari's comment to simplify using only one BoolVar (and corrected a typo above):
# ... 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);
If sum_greater_than_min is false, then the constraint sum == 0 is enforced. If it is true, then sum > 3 is enforced.