Home > Enterprise >  or-tools how to use OnlyEnforceIf in this case
or-tools how to use OnlyEnforceIf in this case

Time:11-04

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.

  • Related