假设我有一份生成大学时间表的申请,并且我有一个限制,即某些教师只在特定日期的某些时段进行教学。如何在 Timefold 中实现这种类型的约束?在 Spring Boot/Java 的调度算法中添加此类情况的最佳实践是什么?
我在 Timefold 的 GitHub Repo 上看到了以下场景的示例,可能与我需要的类似:老师更喜欢按顺序教授课程,不喜欢课程之间的间隙。这个约束的代码如下所示:
Constraint teacherTimeEfficiency(ConstraintFactory constraintFactory) {
// A teacher prefers to teach sequential lessons and dislikes gaps between lessons.
return constraintFactory
.forEachUniquePair(Lesson.class,
Joiners.equal(Lesson::getTeacher),
Joiners.equal((lesson) -> lesson.getTimeslot().getDayOfWeek()))
.filter((lesson1, lesson2) -> {
Duration between = Duration.between(lesson1.getTimeslot().getEndTime(),
lesson2.getTimeslot().getStartTime());
return !between.isNegative() && between.compareTo(Duration.ofMinutes(30)) <= 0;
})
.reward(HardSoftScore.ONE_SOFT)
.justifyWith((lesson1, lesson2, score) -> new TeacherTimeEfficiencyJustification(lesson1.getTeacher(), lesson1, lesson2))
.asConstraint("Teacher time efficiency");
}
您知道首选的确切
Timeslots
吗?如果是这样,我会像这样建模Teacher
:
// preferredTimeslots is nullable
public record Teacher(String name, List<Timeslot> preferredTimeslots) {}
那么约束就是
Constraint maximizePreferredTimeslotAssignments(ConstraintFactory constraintFactory) {
return constraintFactory.forEach(Lesson.class)
.join(Teacher.class, Joiners.equal(Lesson::getTeacher, Function.identity()))
.filter((lesson, teacher) -> teacher.preferredTimeslots() != null && !teacher.preferredTimeslots().contains(lesson.getTimeslot()))
.penalize(HardSoftScore.ONE_SOFT)
.asConstraint("Teacher was assigned unpreferred timeslot");
}
这将惩罚
Teacher
的所有非首选时隙分配(前提是 Teacher
有首选时隙)。如果 Teacher
在周一没有首选时间段,并且您不想对该老师的所有周一作业进行处罚,则您需要将 List<Timeslot>
更改为 Map<DayOfWeek, List<Timeslot>>
(在过滤器中进行相应的更改):
(lesson, teacher) -> teacher.preferredTimeslots().get(lesson.getTimeslot().getDayOfWeek()) != null && !teacher.preferredTimeslots().get(lesson.getTimeslot().getDayOfWeek()).contains(lesson.getTimeslot())