I am wondering the syntax for logical constraints in Google OR-Tools. I have a nurse scheduling project I have done in CPLEX that I am translating over to Google OR-Tools. I have come across the documentation for channeling constraints in Google OR-Tools, but I am confused. Can you help me understand how I would implement this CPLEX logical constraint in Google OR-Tools? I have an attempt, but it is not working as intended :(
Context:
working_assignment_vars_long[r,h,i] is a binary decision variable that denotes whether nurse i in role r is working at the 15-minute interval h (i.e. 1:15PM).
lunch_break_assignment_vars_long[r,h,i] is a binary decision variable that denotes whether nurse i in role r is on break at the 15-minute interval h (i.e. 1:15PM).
simple_break_assignment_vars_long[r,h,i] is a binary decision variable that denotes whether nurse i in role r is on break at 15-minute interval h.
Thus, this constraint in CPLEX is saying that if a given nurse is working 31 or less 15-minute intervals, then they should have 0 lunch breaks and 1 simple break.
CPLEX logical constraint:
for r, num_role in role_dict.items():
for i in range(0,num_role):
model.add_if_then(
model.sum(model.working_assignment_vars_long[r,h,i] for h in range(0,144))
<= 31,
(model.sum(model.lunch_break_assignment_vars_long[r,h,i] for h in range(0,144)) ==
0) + (model.sum(model.simple_break_assignment_vars_long[r,h,i] for h in range(0,144)) ==
1) >= 2,
'less_than_8_hr_0_lunch_break_1_simple_break'
)
I have attempted this in OR-Tools with the following code:
for r, num_role in role_dict.items():
for i in range(0,num_role):
b=model.NewBoolVar(‘b’)
model.Add(sum(working.assignment_vars_long[r,h,i] for h in range(0,144)) <= 31).OnlyEnforceIf(b)
model.Add(sum(lunch_break_assignment_vars_long[r,h,i] for h in range(0,144)) == 0).OnlyEnforceIf(b)
model.Add(sum(simple_break_assignment_vars_long[r,h,i] for h in range(0,144)) == 1).OnlyEnforceIf(b)
This is not working as intended though :( as I see nurses working less than 32 15-minute intervals with both no lunch breaks and no simple breaks. Any insight/help is greatly appreciated. I have been stuck on this problem for so long now :(
In the official documentation it is documented how to do an If-Then-Else expression.
You aren't constraining b.Not()
:
model.Add(sum(working.assignment_vars_long[r,h,i] for h in range(0,144)) > 31).OnlyEnforceIf(b.Not())