OptaPlanner 自定义员工名册 - 约束提供者中的 WeeklyHoursLimit 问题
OptaPlanner Custom Employee Rostering - Issues with WeeklyHoursLimit in the Constraint Provider
我一直在按照员工排班示例创建自定义员工排班服务。我正在尝试实施每周工作时间限制。但是,我未能达到每位员工每周最多工作 40 小时的预期限制。我试图复制 OptaPlanner 员工排班解决方案。这是我想出的,但是解决方案 returns 无论我尝试什么输入都不匹配。
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);
解决方案是一个包含员工和相应时间段的 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 个匹配项。
应该说什么:
constraint (Practitioner work cannot work more than 40 hours per week) has 1 matches.
有了这个输入,唯一可能的解决方案必须符合这个限制条件。检测到其他约束并对其进行惩罚,所以我想知道为什么这个约束从不 returns 任何匹配项。
我怀疑问题出在过滤器中:
.filter((practitioner, day, time) -> time.toHoursPart() > 40)
Duration#toHoursPart() returns总小时数除以一天中的小时数后的余数,介于 0 和 23 之间。
过滤器可能应该使用 Duration#toHours() 代替。
我一直在按照员工排班示例创建自定义员工排班服务。我正在尝试实施每周工作时间限制。但是,我未能达到每位员工每周最多工作 40 小时的预期限制。我试图复制 OptaPlanner 员工排班解决方案。这是我想出的,但是解决方案 returns 无论我尝试什么输入都不匹配。
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);
解决方案是一个包含员工和相应时间段的 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 个匹配项。
应该说什么: constraint (Practitioner work cannot work more than 40 hours per week) has 1 matches.
有了这个输入,唯一可能的解决方案必须符合这个限制条件。检测到其他约束并对其进行惩罚,所以我想知道为什么这个约束从不 returns 任何匹配项。
我怀疑问题出在过滤器中:
.filter((practitioner, day, time) -> time.toHoursPart() > 40)
Duration#toHoursPart() returns总小时数除以一天中的小时数后的余数,介于 0 和 23 之间。 过滤器可能应该使用 Duration#toHours() 代替。