У меня проблема с равномерным распределением смен в моем решателе optaplanner. Моя модель очень похожа на пример списка сотрудников optaplanner, представленный на github:
@PlanningSolution
class Roster {
@ProblemFactCollectionProperty
private List<User> users;
@PlanningEntityCollectionProperty
List<ShiftAssignment> shifts;
}
@PlanningEntity
class Shift {
@PlanningVariable(valueRangeProviderRefs = "usersRange")
private User user;
@NotNull
private OffsetDateTime startDateTime;
@NotNull
private OffsetDateTime endDateTime;
}
Перед решением я распространяю даты начала и окончания ShiftAssignment, оставляя User null.
Проблема возникает, когда я пытаюсь добавить такое ограничение (вместе с тремя другими, которые не нарушаются в одиночку):
from(ShiftAssignment.class)
.filter(shift -> shift.getUser() != null)
.groupBy(Shift::getUser, count())
.filter((user, count) -> count < 10)
.penalize("...")
Этот фрагмент кода нарушает жесткие ограничения, но я действительно не знаю почему - это довольно простое ограничение. Конечно, в PlanningEntityCollection достаточно места для всех необходимых смен для всех пользователей. Может быть, это не самый оптимальный способ достичь этой цели и стоит использовать что-то вроде двойной группировки? Возможно ли это даже с потоком ограничений? Буду рад любой помощи