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) 个问题事实到第二个时间表中。