Replies: 1 comment 4 replies
-
Typically, a
This is why we introduced the load balancing collector: Constraint fairlyAssignNights(ConstraintFactory constraintFactory) {
return constraintFactory.forEach(Shift.class)
.filter(Shift::isNightShift)
.groupBy(Shift::getEmployee, ConstraintCollectors.count())
// Need this so unassigned employees are also balanced
.complement(Employee.class, employee -> 0)
.groupBy(ConstraintCollectors.loadBalance((employee, count) -> employee, (employee, count) -> count))
.penalizeBigDecimal(HardSoftBigDecimalScore.ONE_SOFT, LoadBalance::unfairness)
.asConstraint("balance night shift assignments");
} A variant of this constraint (without the night shift filter) is included in the employee scheduling quickstart: https://github.com/TimefoldAI/timefold-quickstarts/blob/a8bfbca8695b59944936f3f8b569a25611b75166/java/employee-scheduling/src/main/java/org/acme/employeescheduling/solver/EmployeeSchedulingConstraintProvider.java#L113-L121
The example in https://docs.timefold.ai/timefold-solver/latest/design-patterns/design-patterns is for point 5: "If there is an orange many-to-many relationship, replace it with a one-to-many and a many-to-one relationship to a new intermediate class." The "Shift" in that example is just a date/location pair. So Shift in the Employee Scheduling quickstart = ShiftAssignment (employee) + Shift (date + location) in that example. FWIW, the references to ShiftAssignment should probably be removed from the docs and replaced with a different example. |
Beta Was this translation helpful? Give feedback.
-
Hi,
First of all, I'm very happy that TimeFold engine is open source and has received a lot of love from the maintainers.
That said, after playing around with an employee scheduling problem, I ran into quite a few issues when dealing with real employee scheduling task. I had hard time understanding how to design rules such as:
etc...
There are something like 10 more rules like this, some more obscure.
It was quite tedious to find solutions for this kind of constraint design problems. With trial and error I finally managed to make something that works good enough.
My biggest struggle was actually with under assignment. I would never know the exact number of shifts there has to be each week in advance. I would know the number of mandatory shifts where someone has to be, but not the number of optional shifts that also have to be assigned evenly, and in fair way, so that someone is not always working in morning shifts, while other person always has evening shifts.
I see that the enterprise edition has most likely solutions for all these problems, but as an open source user one to figure those out by themselves. Which is fine and understandable. However, I think personally that if the quick-start solution was improved to support dealing with this kind of problems, it would make planning software more accessible and increase the market size for the enterprise offering.
For example, reading the documentation, I found out that docs suggest a separate planning entity, ShiftAssignment:
https://docs.timefold.ai/timefold-solver/latest/design-patterns/design-patterns
However, the employee scheduling quick start has the Shift as a planning entity, as seen here:
https://github.com/TimefoldAI/timefold-quickstarts/blob/stable/java/employee-scheduling/src/main/java/org/acme/employeescheduling/domain/Shift.java
Furthermore, the quick-start does not also define the contract/shift constraints. I don't really know now if I should redesign the solution, as it is sort of good enough now for running in local and replacing the excel. However, I would really like to make it correct.
This was quite a long story now, but my questions are probably:
Best regards,
Tapio
Beta Was this translation helpful? Give feedback.
All reactions