package org.example;
import org.example.domain.*;
import org.example.enums.CourseType;
import org.example.provider.ScheduleConstraintProvider;
import org.optaplanner.core.api.solver.Solver;
import org.optaplanner.core.api.solver.SolverFactory;
import org.optaplanner.core.config.solver.SolverConfig;
import org.optaplanner.core.config.solver.termination.TerminationConfig;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.LongStream;
public class SchedulingApp {
public static void main(String[] args) {
// 1. 创建测试数据
ScheduleSolution problem = createTestData();
// 设置核心类
// 2. 配置求解器(完全适配8.44.0.Final)
SolverConfig solverConfig = new SolverConfig();
// 修正:显式传数组解决setEntityClasses爆红
solverConfig.setEntityClassList(List.of(Schedule.class));
// 关联约束提供类(确保ScheduleConstraintProvider实现了ConstraintProvider接口)
solverConfig.getScoreDirectorFactoryConfig()
.setConstraintProviderClass(ScheduleConstraintProvider.class);
// 设置解决方案类
solverConfig.setSolutionClass(ScheduleSolution.class);
// 设置终止条件(30秒后停止求解)
TerminationConfig terminationConfig = new TerminationConfig();
terminationConfig.setSecondsSpentLimit(30L);
solverConfig.setTerminationConfig(terminationConfig);
// 3. 构建并运行求解器(OptaPlanner会自动选择最优算法,包含遗传算法)
SolverFactory<ScheduleSolution> solverFactory = SolverFactory.create(solverConfig);
Solver<ScheduleSolution> solver = solverFactory.buildSolver();
ScheduleSolution solution = solver.solve(problem);
// 4. 输出结果
System.out.println("===== 排课结果(优化后) =====");
System.out.println("得分汇总:" + solution.getScoreSummary());
System.out.println("==============================");
// 按时间段排序输出
solution.getScheduleList().stream()
.sorted((s1, s2) -> {
int dayCompare = Integer.compare(s1.getTimeSlot().getDayOfWeek(), s2.getTimeSlot().getDayOfWeek());
return dayCompare != 0 ? dayCompare : s1.getTimeSlot().getStartTime().compareTo(s2.getTimeSlot().getStartTime());
})
.forEach(System.out::println);
}
// 构建测试数据(修正i.intValue()问题)
private static ScheduleSolution createTestData() {
// 1. 时间段:周一到周五,每天4个时段(无周末)
List<TimeSlot> timeSlotList = new ArrayList<>();
for (int day = 1; day <= 5; day++) {
timeSlotList.add(new TimeSlot((long) (day * 10 + 1), day, "08:00", "09:40", false));
timeSlotList.add(new TimeSlot((long) (day * 10 + 2), day, "10:00", "11:40", false));
timeSlotList.add(new TimeSlot((long) (day * 10 + 3), day, "14:00", "15:40", false));
timeSlotList.add(new TimeSlot((long) (day * 10 + 4), day, "16:00", "17:40", false));
}
// 2. 教室:2个(容量50/100)
List<Classroom> classroomList = new ArrayList<>();
classroomList.add(new Classroom(1L, "教学楼A101", 50));
classroomList.add(new Classroom(2L, "教学楼B201", 100));
// 3. 教师:3位
List<Teacher> teacherList = new ArrayList<>();
teacherList.add(new Teacher(1L, "张老师"));
teacherList.add(new Teacher(2L, "李老师"));
teacherList.add(new Teacher(3L, "王老师"));
// 4. 班级:2个
List<ClassGroup> classGroupList = new ArrayList<>();
classGroupList.add(new ClassGroup(1L, "计算机2023级1班", 45));
classGroupList.add(new ClassGroup(2L, "软件工程2023级1班", 90));
// 5. 课程:6门(不同优先级)
List<Course> courseList = new ArrayList<>();
courseList.add(new Course(1L, "Java编程", CourseType.PROFESSIONAL_CORE, 1L, 1L));
courseList.add(new Course(2L, "数据结构", CourseType.PROFESSIONAL_COMPULSORY, 1L, 1L));
courseList.add(new Course(3L, "高等数学", CourseType.PUBLIC_COMPULSORY, 2L, 1L));
courseList.add(new Course(4L, "人工智能导论", CourseType.PROFESSIONAL_RESTRICTED_ELECTIVE, 3L, 2L));
courseList.add(new Course(5L, "大学英语", CourseType.PUBLIC_RESTRICTED_ELECTIVE, 2L, 2L));
courseList.add(new Course(6L, "Python入门", CourseType.PROFESSIONAL_ELECTIVE, 3L, 1L));
// 6. 初始排课计划(修正i.intValue()问题:改用boxed()装箱为Long)
List<Schedule> scheduleList = new ArrayList<>();
// 修正点:LongStream.boxed() 转为 Stream<Long>,i变为Long包装类,可调用intValue()
LongStream.range(0, courseList.size()).boxed().forEach(i -> {
Course course = courseList.get(i.intValue());
Teacher teacher = teacherList.stream().filter(t -> t.getId().equals(course.getTeacherId())).findFirst().get();
ClassGroup classGroup = classGroupList.stream().filter(cg -> cg.getId().equals(course.getClassGroupId())).findFirst().get();
scheduleList.add(new Schedule(i + 1, course, teacher, classGroup, null, null));
});
return new ScheduleSolution(timeSlotList, classroomList, teacherList, classGroupList, courseList, scheduleList, null);
}
}
修复
"C:\Program Files\Java\jdk-17\bin\java.exe" "-javaagent:D:\localsoft\IntelliJ IDEA 2025.2.1\lib\idea_rt.jar=40153" -Dfile.encoding=UTF-8 -classpath G:\code\opta_class\target\classes;C:\Users\Administrator\.m2\repository\org\optaplanner\optaplanner-core\8.44.0.Final\optaplanner-core-8.44.0.Final.jar;C:\Users\Administrator\.m2\repository\org\optaplanner\optaplanner-core-impl\8.44.0.Final\optaplanner-core-impl-8.44.0.Final.jar;C:\Users\Administrator\.m2\repository\org\apache\commons\commons-math3\3.6.1\commons-math3-3.6.1.jar;C:\Users\Administrator\.m2\repository\io\micrometer\micrometer-core\1.10.2\micrometer-core-1.10.2.jar;C:\Users\Administrator\.m2\repository\io\micrometer\micrometer-commons\1.10.2\micrometer-commons-1.10.2.jar;C:\Users\Administrator\.m2\repository\io\micrometer\micrometer-observation\1.10.2\micrometer-observation-1.10.2.jar;C:\Users\Administrator\.m2\repository\org\hdrhistogram\HdrHistogram\2.1.12\HdrHistogram-2.1.12.jar;C:\Users\Administrator\.m2\repository\org\latencyutils\LatencyUtils\2.0.3\LatencyUtils-2.0.3.jar;C:\Users\Administrator\.m2\repository\jakarta\xml\bind\jakarta.xml.bind-api\2.3.3\jakarta.xml.bind-api-2.3.3.jar;C:\Users\Administrator\.m2\repository\jakarta\activation\jakarta.activation-api\1.2.2\jakarta.activation-api-1.2.2.jar;C:\Users\Administrator\.m2\repository\org\glassfish\jaxb\jaxb-runtime\2.3.3-b02\jaxb-runtime-2.3.3-b02.jar;C:\Users\Administrator\.m2\repository\org\glassfish\jaxb\txw2\2.3.3-b02\txw2-2.3.3-b02.jar;C:\Users\Administrator\.m2\repository\com\sun\istack\istack-commons-runtime\3.0.10\istack-commons-runtime-3.0.10.jar;C:\Users\Administrator\.m2\repository\com\sun\activation\jakarta.activation\1.2.1\jakarta.activation-1.2.1.jar;C:\Users\Administrator\.m2\repository\org\optaplanner\optaplanner-constraint-streams-drools\8.44.0.Final\optaplanner-constraint-streams-drools-8.44.0.Final.jar;C:\Users\Administrator\.m2\repository\org\optaplanner\optaplanner-constraint-streams-common\8.44.0.Final\optaplanner-constraint-streams-common-8.44.0.Final.jar;C:\Users\Administrator\.m2\repository\org\drools\drools-engine\8.44.0.Final\drools-engine-8.44.0.Final.jar;C:\Users\Administrator\.m2\repository\org\kie\kie-api\8.44.0.Final\kie-api-8.44.0.Final.jar;C:\Users\Administrator\.m2\repository\org\kie\kie-internal\8.44.0.Final\kie-internal-8.44.0.Final.jar;C:\Users\Administrator\.m2\repository\org\drools\drools-core\8.44.0.Final\drools-core-8.44.0.Final.jar;C:\Users\Administrator\.m2\repository\org\kie\kie-util-xml\8.44.0.Final\kie-util-xml-8.44.0.Final.jar;C:\Users\Administrator\.m2\repository\org\drools\drools-wiring-api\8.44.0.Final\drools-wiring-api-8.44.0.Final.jar;C:\Users\Administrator\.m2\repository\org\drools\drools-base\8.44.0.Final\drools-base-8.44.0.Final.jar;C:\Users\Administrator\.m2\repository\org\drools\drools-wiring-static\8.44.0.Final\drools-wiring-static-8.44.0.Final.jar;C:\Users\Administrator\.m2\repository\org\drools\drools-io\8.44.0.Final\drools-io-8.44.0.Final.jar;C:\Users\Administrator\.m2\repository\commons-codec\commons-codec\1.15\commons-codec-1.15.jar;C:\Users\Administrator\.m2\repository\org\drools\drools-wiring-dynamic\8.44.0.Final\drools-wiring-dynamic-8.44.0.Final.jar;C:\Users\Administrator\.m2\repository\org\drools\drools-kiesession\8.44.0.Final\drools-kiesession-8.44.0.Final.jar;C:\Users\Administrator\.m2\repository\org\drools\drools-tms\8.44.0.Final\drools-tms-8.44.0.Final.jar;C:\Users\Administrator\.m2\repository\org\drools\drools-compiler\8.44.0.Final\drools-compiler-8.44.0.Final.jar;C:\Users\Administrator\.m2\repository\org\drools\drools-drl-parser\8.44.0.Final\drools-drl-parser-8.44.0.Final.jar;C:\Users\Administrator\.m2\repository\org\drools\drools-drl-extensions\8.44.0.Final\drools-drl-extensions-8.44.0.Final.jar;C:\Users\Administrator\.m2\repository\org\drools\drools-drl-ast\8.44.0.Final\drools-drl-ast-8.44.0.Final.jar;C:\Users\Administrator\.m2\repository\org\kie\kie-memory-compiler\8.44.0.Final\kie-memory-compiler-8.44.0.Final.jar;C:\Users\Administrator\.m2\repository\org\drools\drools-ecj\8.44.0.Final\drools-ecj-8.44.0.Final.jar;C:\Users\Administrator\.m2\repository\org\eclipse\jdt\ecj\3.33.0\ecj-3.33.0.jar;C:\Users\Administrator\.m2\repository\org\kie\kie-util-maven-support\8.44.0.Final\kie-util-maven-support-8.44.0.Final.jar;C:\Users\Administrator\.m2\repository\org\antlr\antlr-runtime\3.5.2\antlr-runtime-3.5.2.jar;C:\Users\Administrator\.m2\repository\org\drools\drools-model-compiler\8.44.0.Final\drools-model-compiler-8.44.0.Final.jar;C:\Users\Administrator\.m2\repository\org\drools\drools-canonical-model\8.44.0.Final\drools-canonical-model-8.44.0.Final.jar;C:\Users\Administrator\.m2\repository\org\drools\drools-model-codegen\8.44.0.Final\drools-model-codegen-8.44.0.Final.jar;C:\Users\Administrator\.m2\repository\org\drools\drools-util\8.44.0.Final\drools-util-8.44.0.Final.jar;C:\Users\Administrator\.m2\repository\org\drools\drools-codegen-common\8.44.0.Final\drools-codegen-common-8.44.0.Final.jar;C:\Users\Administrator\.m2\repository\com\github\javaparser\javaparser-core\3.24.2\javaparser-core-3.24.2.jar;C:\Users\Administrator\.m2\repository\org\drools\drools-mvel-parser\8.44.0.Final\drools-mvel-parser-8.44.0.Final.jar;C:\Users\Administrator\.m2\repository\org\drools\drools-mvel-compiler\8.44.0.Final\drools-mvel-compiler-8.44.0.Final.jar;C:\Users\Administrator\.m2\repository\org\drools\drools-commands\8.44.0.Final\drools-commands-8.44.0.Final.jar;C:\Users\Administrator\.m2\repository\org\drools\drools-alphanetwork-compiler\8.44.0.Final\drools-alphanetwork-compiler-8.44.0.Final.jar;C:\Users\Administrator\.m2\repository\org\optaplanner\optaplanner-constraint-drl\8.44.0.Final\optaplanner-constraint-drl-8.44.0.Final.jar;C:\Users\Administrator\.m2\repository\org\optaplanner\optaplanner-constraint-streams-bavet\8.44.0.Final\optaplanner-constraint-streams-bavet-8.44.0.Final.jar;C:\Users\Administrator\.m2\repository\org\slf4j\slf4j-simple\2.0.7\slf4j-simple-2.0.7.jar;C:\Users\Administrator\.m2\repository\org\slf4j\slf4j-api\2.0.7\slf4j-api-2.0.7.jar org.example.SchedulingApp
Exception in thread "main" java.lang.NullPointerException: Cannot invoke "org.optaplanner.core.config.score.director.ScoreDirectorFactoryConfig.setConstraintProviderClass(java.lang.Class)" because the return value of "org.optaplanner.core.config.solver.SolverConfig.getScoreDirectorFactoryConfig()" is null
at org.example.SchedulingApp.main(SchedulingApp.java:28)
进程已结束,退出代码为 1