Java 如何将规划变量的列表中的交叉点属性定义为Optaplanner约束?

Java 如何将规划变量的列表中的交叉点属性定义为Optaplanner约束?,java,optaplanner,Java,Optaplanner,我开始学习Optaplanner,并希望通过使用扩展他们的时间表问题示例-现在我希望有多个学生组应该参加特定课程-我将这些学生组保存在我的计划变量中,作为列出学生组事实(见下文) 我将讲座分配到时段和教室,时段基本上是一天/小时的独特组合。(请参见下面的“我的规划实体”讲师规划”) 现在,我将在ConstraintProvider中制定以下约束: private Constraint studentGroupConflict(ConstraintFactory constraintFac

我开始学习Optaplanner,并希望通过使用扩展他们的时间表问题示例-现在我希望有多个学生组应该参加特定课程-我将这些学生组保存在我的计划变量中,作为
列出学生组事实
(见下文)

我将讲座分配到时段和教室,时段基本上是一天/小时的独特组合。(请参见下面的“我的规划实体”
讲师规划”

现在,我将在ConstraintProvider中制定以下约束:

    private Constraint studentGroupConflict(ConstraintFactory constraintFactory) {
    return constraintFactory.from(LecturePlanning.class)
            .join(LecturePlanning.class,
                    Joiners.equal(LecturePlanning::getLectureSlot),
                    Joiners.equal(LecturePlanning::getAssignedStudentGroups),
                    Joiners.greaterThan(LecturePlanning::getLectureID))
            .penalize("Student Group Conflict", HardSoftScore.ONE_HARD);
    }
它应该比较我的
讲师计划
-如果将一个讲座分配给一个会导致
学生组
(我的
分配的学生组
-列表)的时段,那么对象(基本上是讲座)将需要在同一时段访问两个课程

如果
AssignedStudentGroups
列表中存在交集,这当然会失败,但它们并不相等-遗憾的是,我没有找到解决这个问题的方法,我也没有看到教程中提到的任何东西-有人能帮我解决这个问题吗

规划实体:

    @PlanningEntity
    public class LecturePlanning {
    
        private int lectureID;
        private String lectureName;
        private int requiredRoomType;
        private int numberOfRoomsParallel;
        private boolean onlyTutors;
        private List<LecturerFact> lecturerFacts;
        private List<StudentGroupFact> assignedStudentGroups;
    
        @PlanningVariable(valueRangeProviderRefs = "lectureSlotRange")
        private LectureSlotFact lectureSlot;
    
        @PlanningVariable(valueRangeProviderRefs = "roomRange")
        private RoomFact room;

        //..

      }


The Constraint Provider class (currently full impl. - includes the snippet at the beginning of this post):

public class ScheduleConstraintProvider implements ConstraintProvider {

    @Override
    public Constraint[] defineConstraints(ConstraintFactory constraintFactory) {
        return new Constraint[] {
                roomConflict(constraintFactory),
                teacherConflict(constraintFactory),
                studentGroupConflict(constraintFactory)
        };
    }

    private Constraint roomConflict(ConstraintFactory constraintFactory) {
        return constraintFactory.from(LecturePlanning.class)
                .join(LecturePlanning.class,
                        Joiners.equal(LecturePlanning::getLectureSlot),
                        Joiners.equal(LecturePlanning::getRoom),
                        Joiners.greaterThan(LecturePlanning::getLectureID))
                .penalize("Room Conflict", HardSoftScore.ONE_HARD);
    }

    private Constraint teacherConflict(ConstraintFactory constraintFactory) {
        return constraintFactory.from(LecturePlanning.class)
                .join(LecturePlanning.class,
                        Joiners.equal(LecturePlanning::getLectureSlot),
                        Joiners.equal(LecturePlanning::getLecturerFacts),
                        Joiners.greaterThan(LecturePlanning::getLectureID))
                .penalize("Lecturer Conflict", HardSoftScore.ONE_HARD);
    }

    private Constraint studentGroupConflict(ConstraintFactory constraintFactory) {
        return constraintFactory.from(LecturePlanning.class)
                .join(LecturePlanning.class,
                        Joiners.equal(LecturePlanning::getLectureSlot),
                        Joiners.equal(LecturePlanning::getAssignedStudentGroups),
                        Joiners.greaterThan(LecturePlanning::getLectureID))
                .penalize("Student Group Conflict", HardSoftScore.ONE_HARD);
    }
}
@PlanningEntity
公共课堂讲师计划{
私营企业;
私有字符串名称;
私人室内型;
私人房间国际号码;
专用布尔运算器;
私人名单;
分配给学生组的私人名单;
@规划变量(valueRangeProviderRefs=“讲师系列”)
私人讲师lotfact讲师lot;
@规划变量(valueRangeProviderRefs=“roomRange”)
私人房间;
//..
}
约束提供程序类(当前完整impl.-包括本文开头的代码段):
公共类ScheduleConstraintProvider实现ConstraintProvider{
@凌驾
公共约束[]定义约束(约束工厂约束工厂){
返回新约束[]{
roomConflict(约束工厂),
教师冲突(约束工厂),
学生组冲突(constraintFactory)
};
}
私有约束roomConflict(ConstraintFactory ConstraintFactory){
返回constraintFactory.from(讲师计划.class)
.加入(讲师计划课程),
Joiners.equal(讲师计划::Get讲师批次),
Joiners.equal(讲师计划::getRoom),
Joiners.greaterThan(讲师计划::Get讲师ID))
.处罚(“房间冲突”,硬软分数,硬一分);
}
私有约束教师冲突(ConstraintFactory ConstraintFactory){
返回constraintFactory.from(讲师计划.class)
.加入(讲师计划课程),
Joiners.equal(讲师计划::Get讲师批次),
Joiners.equal(讲师计划::Get讲师行为),
Joiners.greaterThan(讲师计划::Get讲师ID))
.处罚(“讲师冲突”,硬软分数,硬一分);
}
私有约束studentGroupConflict(ConstraintFactory ConstraintFactory){
返回constraintFactory.from(讲师计划.class)
.加入(讲师计划课程),
Joiners.equal(讲师计划::Get讲师批次),
Joiners.equal(讲师计划::GetAssignedStudentGroup),
Joiners.greaterThan(讲师计划::Get讲师ID))
.处罚(“学生群体冲突”,硬软分数,硬一分);
}
}

Hi,请看一下的“其他函数”(例如,
连接件。相交的
是未知的,而不是
连接件。相等的
),但可用的
大或
小。无论如何,我在理解文档中可能存在的使用这些函数的任何要求方面遇到了困难。您应该能够使用
连接器实现这一点。筛选((讲师1,讲师2)->!相交(讲师1,讲师2)
,其中
interest()
是一个您自己实现的函数。需要注意的是:这不会很好地执行,因为在每一对上检查这些集合都会造成伤害。我建议您想出一种方法来缓存这些信息。我不确定上面的包含/分离/相交joiner建议来自何处,因为我们尚未实现这些连接目前还没有任何紧急计划。