我正在尝试扩展 Timefold 'Hello World' java 示例。我已经添加了我自己的课程、班级和教师数据,现在我想添加一个额外的约束,即某些教师仅在特定日期工作。
我试过这个:
Constraint restDayConstraint(ConstraintFactory constraintFactory) {
// teachers don't teach on their rest day
return constraintFactory
.forEachUniquePair(Lesson.class, Teacher.class,
Joiners.equal(Lesson::getTimeslot),
Joiners.equal(Teacher::getTeacher))
.filter((lesson1, teacher) -> lesson1.getTimeslot().getDayOfWeek() != teacher.getRestDay())
.penalize(HardSoftScore.ONE_HARD)
.justifyWith(
(lesson1, teacher, score) -> new TeacherConflictJustification(lesson1.getTeacher(), lesson1, teacher))
.asConstraint("Teacher conflict");
}
并使用以下代码创建了 Teacher.java 文件:
package org.acme.schooltimetabling.domain;
import ai.timefold.solver.core.api.domain.entity.PlanningEntity;
import ai.timefold.solver.core.api.domain.lookup.PlanningId;
import ai.timefold.solver.core.api.domain.variable.PlanningVariable;
@PlanningEntity
public class Teacher {
@PlanningId
private Long id;
private String subject;
private String restDay;
@PlanningVariable
private Timeslot timeslot;
@PlanningVariable
private Room room;
// No-arg constructor required for Timefold
public Teacher() {
}
public Teacher(long id, String subject, String restDay) {
this.id = id;
this.subject = subject;
this.restDay = restDay;
}
@Override
public String toString() {
return subject + "(" + id + ")";
}
// ************************************************************************
// Getters and setters
// ************************************************************************
public Long getId() {
return id;
}
public String getRestDay() {
return restDay;
}
public String getSubject() {
return subject;
}
}
但是我收到以下错误:
The method forEachUniquePair(Class<A>, BiJoiner<A,A>, BiJoiner<A,A>) in the type ConstraintFactory is not applicable for the arguments (Class<Lesson>, BiJoiner<Lesson,Lesson>, BiJoiner<Teacher,Teacher>)
如何强制执行某些教师仅在特定日期工作的限制?
我认为该错误是由于您尝试在 2 个不同的实体(教师、课程)上执行 forEachUniquePair() 方法而导致的,而该方法是为单个规划实体(课程或教师)设计的。 https://javadoc.io/doc/ai.timefold.solver/timefold-solver-core-impl/latest/ai/timefold/solver/core/api/score/stream/ConstraintFactory.html#forEachUniquePair(java.lang .Class,ai.timefold.solver.core.api.score.stream.bi.BiJoiner,ai.timefold.solver.core.api.score.stream.bi.BiJoiner) 我不知道你为什么选择有两个规划实体。也许你可以告诉我更多关于你想要实现的目标。
如果您想更好地了解规划实体、规划变量和问题事实之间的区别,可以参考此文档:https://timefold.ai/docs/timefold-solver/latest/using-timefold-solver/modeling-规划问题#problemFact
我建议您按照以下示例对域进行建模:https://github.com/TimefoldAI/timefold-quickstarts/tree/stable/technology/java-spring-boot/src/main/java/org/acme /schooltimetableling/domain.
您可以像这样对课程和教师课程进行建模:
@PlanningEntity
public class Lesson {
@PlanningId
private Long id;
private String subject;
private Teacher teacher;
private String studentGroup;
@JsonIdentityReference
@PlanningVariable
private Timeslot timeslot;
@JsonIdentityReference
@PlanningVariable
private Room room;
//constructors and getters and setters
public class Teacher {
private Long id;
private String subject;
private List<DayOfWeek> restDay;
//contructors and getters and setters
然后我将按如下方式对约束进行建模:
Constraint restDayConstraint(ConstraintFactory constraintFactory) {
// teachers don't teach on their rest day
return constraintFactory
.forEachUniquePair(Lesson.class,
Joiners.equal(Lesson::getTimeslot),
Joiners.equal((lesson) -> lesson.getTeacher()))
.filter((lesson1, teacher) ->
// check if the teacher's restDays contains the day of the lesson
teacher.getRestDay().contains(lesson1.getTimeslot().getDayOfWeek()))
.penalize(HardSoftScore.ONE_HARD)
.justifyWith(
(lesson1, teacher, score) -> new TeacherConflictJustification(lesson1.getTeacher(), lesson1, teacher))
.asConstraint("Teacher conflict");
}
这就是我解决问题的方法。如果有帮助请告诉我。