Optaplanner——比较同一求解过程中的多个解
Optaplanner - compare multiple solutions in the same solving process
在生成解决方案时,我想对多个学校classes 时间表施加一些限制。例如,我想检查同一位老师在两个时间表上是否没有两个时间段(在课程中)。所以,我想比较两个不同时间表中的两个时间段(两节课)。
不知道怎么办。
我正在使用 ConstraintProvider class :
public class TimeTableConstraintsProvider implements ConstraintProvider {
@Override
public Constraint[] defineConstraints(ConstraintFactory constraintFactory) {
return new Constraint[] {
timeSlotConflictPenalty(constraintFactory),
};
}
public Constraint timeSlotConflictPenalty(ConstraintFactory constraintFactory) {
return constraintFactory
.from(Lesson.class)
.join(Lesson.class)
.filter(Lesson::isOverlapping)
.penalize("time slot conflict", HardSoftScore.ONE_HARD);
}
}
我有这个规划解决方案:
@PlanningSolution
public class TimeTable {
private String id;
@PlanningEntityCollectionProperty
private List<Lesson> lessons;
@ValueRangeProvider(id = "timeSlotRange")
private List<TimeSlot> timeSlots;
@ProblemFactCollectionProperty
private List<SchoolRoom> schoolRooms;
@ProblemFactCollectionProperty
private List<Course> courses;
@ProblemFactCollectionProperty
private List<Teacher> teachers;
@ProblemFactCollectionProperty
private List<SchoolClass> schoolClasses;
@PlanningScore
private HardSoftScore score;
private SolverStatus solverStatus;
//...
}
这是课程实体:
@PlanningEntity
public class Lesson {
@PlanningId
private Long id;
private SchoolRoom schoolRoom;
private Subject subject;
private Teacher teacher;
@PlanningVariable(valueRangeProviderRefs = "timeSlotRange")
private TimeSlot timeSlot;
private SchoolClass schoolClass;
}
以及求解器方法的一部分
schoolClasses.forEach(schoolClass -> {
final TimeTable timeTable = new TimeTable(clientId,
schoolClass, schoolClasses, schoolRooms, subjects, teachers, lessons,
lessons.stream().map(Lesson::getTimeSlot).collect(Collectors.toList()));
final SolverJob<TimeTable, String> solverJob =
solverManager.solveAndListen(schoolClassId, id -> timeTable,
this::saveTimeTable);
});
“我想检查同一个老师在两个时间表上是否没有两个时间段(在课上)。”
要么这是一个规划问题,那么一个大时间表(合并这 2 个时间表)。
或者您正在进行“多阶段规划”(请参阅文档):在这种情况下,一个解决方案会限制下一个解决方案。所以在第一个时间表解决后,它会生成 TeacherUnavailable(String teacher, Timeslot timeslot)
个问题事实到第二个时间表中。
在生成解决方案时,我想对多个学校classes 时间表施加一些限制。例如,我想检查同一位老师在两个时间表上是否没有两个时间段(在课程中)。所以,我想比较两个不同时间表中的两个时间段(两节课)。 不知道怎么办。
我正在使用 ConstraintProvider class :
public class TimeTableConstraintsProvider implements ConstraintProvider {
@Override
public Constraint[] defineConstraints(ConstraintFactory constraintFactory) {
return new Constraint[] {
timeSlotConflictPenalty(constraintFactory),
};
}
public Constraint timeSlotConflictPenalty(ConstraintFactory constraintFactory) {
return constraintFactory
.from(Lesson.class)
.join(Lesson.class)
.filter(Lesson::isOverlapping)
.penalize("time slot conflict", HardSoftScore.ONE_HARD);
}
}
我有这个规划解决方案:
@PlanningSolution
public class TimeTable {
private String id;
@PlanningEntityCollectionProperty
private List<Lesson> lessons;
@ValueRangeProvider(id = "timeSlotRange")
private List<TimeSlot> timeSlots;
@ProblemFactCollectionProperty
private List<SchoolRoom> schoolRooms;
@ProblemFactCollectionProperty
private List<Course> courses;
@ProblemFactCollectionProperty
private List<Teacher> teachers;
@ProblemFactCollectionProperty
private List<SchoolClass> schoolClasses;
@PlanningScore
private HardSoftScore score;
private SolverStatus solverStatus;
//...
}
这是课程实体:
@PlanningEntity
public class Lesson {
@PlanningId
private Long id;
private SchoolRoom schoolRoom;
private Subject subject;
private Teacher teacher;
@PlanningVariable(valueRangeProviderRefs = "timeSlotRange")
private TimeSlot timeSlot;
private SchoolClass schoolClass;
}
以及求解器方法的一部分
schoolClasses.forEach(schoolClass -> {
final TimeTable timeTable = new TimeTable(clientId,
schoolClass, schoolClasses, schoolRooms, subjects, teachers, lessons,
lessons.stream().map(Lesson::getTimeSlot).collect(Collectors.toList()));
final SolverJob<TimeTable, String> solverJob =
solverManager.solveAndListen(schoolClassId, id -> timeTable,
this::saveTimeTable);
});
“我想检查同一个老师在两个时间表上是否没有两个时间段(在课上)。”
要么这是一个规划问题,那么一个大时间表(合并这 2 个时间表)。
或者您正在进行“多阶段规划”(请参阅文档):在这种情况下,一个解决方案会限制下一个解决方案。所以在第一个时间表解决后,它会生成
TeacherUnavailable(String teacher, Timeslot timeslot)
个问题事实到第二个时间表中。