java - Optaplanner 为 ConstraintProvider 类中的员工允许的最大轮班数量添加约束
问题描述
我正在尝试添加一个约束,以限制在 ConstraintProvider 类中分配给员工的班次数量,但我想知道是否有更好的方法来定义它,而不是必须在我的 @PlanningEntity 和 @PlanningVariable 类中添加一个属性?
这是我的@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());
}
}
除了在我的 Shift 类中添加 shiftAmount 之外,我还可以添加一些将每个 Shift 视为 1 个班次分配的内容吗?
解决方案
是的
代替:
return constraintFactory.from(Shift.class)
.groupBy(Shift::getEmployee, sum(Shift::getShiftAmount))
做
return constraintFactory.from(Shift.class)
.groupBy(Shift::getEmployee, count())
(如果你想要一个长的,使用countLong()
。)
推荐阅读
- android - 用户在表中没有看到正确的值
- laravel - Laravel - 在不同的数据库实例上急切加载过滤相关模型
- javascript - 用于选择下一个数组元素的循环
- c# - 单击列表框项目并在标签中显示文本文件文本
- azure - Azure VMSS Linux 操作系统升级
- java - 命令通过命令行工作,但在使用 ProcessBuilder 时不行
- haskell - 修复的固定点 :: Eq a => (a -> a) -> a -> a
- amazon-web-services - AWS Beanstalk:没有一个实例正在发送数据,并且不能 ssh 到 ec2
- json - 基于java8的具有多个JsonObject转换为映射的Json数组
- javascript - Angularjs 自定义可再发行库