[英]Employee rostering with Optaplanner. Hard constraint is broken but hard score is not deducted
[英]OptaPlanner Custom Employee Rostering - Issues with WeeklyHoursLimit in the Constraint Provider
我一直在关注员工排班示例来创建自定义员工排班服务。 我正在尝试实施每周工作时间限制。 但是,我无法达到每位员工每周最多工作 40 小时的预期限制。 我尝试复制 OptaPlanner 员工排班解决方案。 这是我想出的,但无论我尝试什么输入,解决方案都不会返回匹配项。
Constraint weeklyHoursUpperLimit(ConstraintFactory constraintFactory) {
return constraintFactory.from(Employee.class)
.join(Schedule.class, equal(Function.identity(), Schedule::getEmployee))
.groupBy((employee, schedule) -> employee,
((employee, schedule) -> ZonedDateTime.parse(schedule.getTimeslot().getStart()).toLocalDate()
.with(TemporalAdjusters.previousOrSame(DayOfWeek.SUNDAY))),
sumDuration((employee, schedule) -> Duration.between(ZonedDateTime.parse(schedule.getTimeslot().getStart()),
ZonedDateTime.parse(schedule.getTimeslot().getEnd()))))
.filter((practitioner, day, time) -> time.toHoursPart() > 40)
.penalize("Practitioners cannot work more than 40 hours per week", HardMediumSoftScore.ONE_HARD);
解决方案是一个包含 Employee 和相应时间段的 Schedule 类型列表,它似乎与期望的行为不匹配。
使用以下输入:
{
"employees": [
{
"id": "0458d419-da18-4d86-82de-31a2272f018a"
}
],
"timeslots": [
{
"start": "2021-05-24T00:00:00-04:00",
"end": "2021-05-24T12:00:00-04:00",
"slotId": 1
},
{
"start": "2021-05-24T12:00:00-04:00",
"end": "2021-05-25T00:00:00-04:00",
"slotId": 7
},
{
"start": "2021-05-25T12:00:00-04:00",
"end": "2021-05-26T00:00:00-04:00",
"slotId": 4
},
{
"start": "2021-05-27T12:00:00-04:00",
"end": "2021-05-28T00:00:00-04:00",
"slotId": 5
}
]
}
ScoreExplanation 表示:约束(从业者每周工作不能超过 40 小时)有 0 个匹配项。
应该说什么:约束(从业者每周工作不能超过 40 小时)有 1 个匹配项。
有了这个输入,唯一可能的解决方案必须匹配这个约束。 检测到其他约束并对其进行处罚,所以我想知道为什么这个约束从不返回任何匹配项。
我怀疑问题出在过滤器中: .filter((practitioner, day, time) -> time.toHoursPart() > 40)
Duration#toHoursPart()在将总小时数除以一天中的小时数后返回余数,介于 0 和 23 之间。过滤器可能应该使用Duration#toHours()代替。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.