Optaplanner добавляет ограничение на максимальное количество смен, допустимых для сотрудника в классе ConstraintProvider - PullRequest
0 голосов
/ 30 апреля 2020

Я пытаюсь добавить ограничение, которое ограничивает количество смен, назначаемых сотрудникам в классе ConstraintProvider, но я хочу знать, есть ли лучший способ определить это, вместо того, чтобы добавлять атрибут в оба моих @PlanningEntity и @PlanningVariable class?

Вот мои атрибуты класса @PlanningEntity:

 @PlanningEntity
    @Entity
    public class Shift {
        @Id
        @GeneratedValue(strategy = GenerationType.AUTO)
        @Column(name = "shiftId")
        private int shiftId;

        @Column(name = "startTime")
        private LocalTime startTime;

        @Column(name = "endTime")
        private LocalTime endTime;

        @Column(name = "day")
        private String day;

        @Column(name = "requiredSkillLevel")
        private int requiredSkillLevel;

        @Column(name = "shiftAmount")
        private int shiftAmount;

        @Transient
        @PlanningVariable(valueRangeProviderRefs = "employee")
        private Employee employee;

Вот мой класс @PlanningVariable:

    @Entity
    public class Employee {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "employeeId")
    private int employeeId;

    @Column(name = "employeeName")
    private String employeeName;

    @Column(name = "skillLevel")
    private int skillLevel;

    @Column(name = "employeeType")
    @Enumerated(EnumType.STRING)
    private EmployeeType employeeType;

    @Column(name = "associatedDepartment")
    @Enumerated(EnumType.STRING)
    private Departments associatedDepartment;

    @Column(name = "weeklyShiftAllowance")
    private int weeklyShiftAllowance;

Мои ограничения следующие:

    public class ScheduleConstraintProvider implements org.optaplanner.core.api.score.stream.ConstraintProvider {
    @Override
    public Constraint[] defineConstraints(ConstraintFactory constraintFactory) {
        return new Constraint[]{
                requiredSkillLevelOfEmployeesForShifts(constraintFactory),
                maximumNumberOfAllowableShiftsForEmployees(constraintFactory)
        };
    }

    private Constraint maximumNumberOfAllowableShiftsForEmployees(ConstraintFactory constraintFactory) {
        return constraintFactory.from(Shift.class)
                .groupBy(Shift::getEmployee, sum(Shift::getShiftAmount))
                .filter((employee, shiftAmount) -> shiftAmount > employee.getWeeklyShiftAllowance())
                .penalize("Weekly Shift Allowance for each Employee",
                        HardSoftScore.ONE_HARD,
                        (employee, shiftAmount) -> shiftAmount - employee.getWeeklyShiftAllowance());
    }

    private Constraint requiredSkillLevelOfEmployeesForShifts(ConstraintFactory constraintFactory) {
        return constraintFactory.from(Shift.class)
                .groupBy(Shift::getEmployee, sum(Shift::getRequiredSkillLevel))
                .filter((employee, requiredSkillLevel) -> requiredSkillLevel > employee.getSkillLevel())
                .penalize("Required Skill Level for a Shift",
                HardSoftScore.ONE_HARD,
                (employee, requiredSkillLevel) -> requiredSkillLevel - employee.getSkillLevel());
    }


}

Вместо того, чтобы иметь shiftAmount в моем классе Shift, могу ли я добавить что-то, что рассматривает каждый Shift как счет за 1 смену?

1 Ответ

1 голос
/ 04 мая 2020

Да

Вместо:

return constraintFactory.from(Shift.class)
                .groupBy(Shift::getEmployee, sum(Shift::getShiftAmount))

do

return constraintFactory.from(Shift.class)
                .groupBy(Shift::getEmployee, count())

(Если вы хотите длинный, используйте countLong().)

...