Timefold讲师课程负载均衡问题:unfairness始终为0的排查
课程-讲师公平分配问题
我需要实现课程到讲师的公平分配,均衡实体为Lecturer,负载值为分配给讲师的课程总时长。调用penalizeBigDecimal时,求解器输出显示:即使所有课程都分配给Faizal或Ahmad,unfairness值仍为0。
核心问题
- 为何
LoadBalance::unfairness()始终返回0?是否需要自定义不公平度计算函数? - 如何确保所有讲师都出现在
LoadBalance::loads()中?若需自定义公平函数(如基于讲师平均时长计算),需要所有讲师的数据来计算平均值。
我尝试在.groupBy()后链式调用.complement(),但它要求传入Class<LoadBalance<Lecturer>>类型参数,不知道如何正确传递。
补充说明
将某一课程时长改为70后,求解器返回非零unfairness值:
List<Course> courses = List.of( new Course(String.valueOf(courseId++), "Fizik 1", 70), new Course(String.valueOf(courseId++), "Chem 1", 60) ); List<LecturerCourseAssignment> assignments = List.of( new LecturerCourseAssignment(courses.get(0)), new LecturerCourseAssignment(courses.get(1)) );
我认为unfairness为0是因为Faizal未出现在LoadBalance::loads()中。但添加2个时长为60的课程分配后,仍得到不平衡的解决方案:
List<Course> courses = List.of( new Course(String.valueOf(courseId++), "Fizik 1", 60), new Course(String.valueOf(courseId++), "Chem 1", 60), new Course(String.valueOf(courseId++), "Math 1", 60), new Course(String.valueOf(courseId++), "Programming 1", 60) ); List<LecturerCourseAssignment> assignments = List.of( new LecturerCourseAssignment(courses.get(0)), new LecturerCourseAssignment(courses.get(1)), new LecturerCourseAssignment(courses.get(2)), new LecturerCourseAssignment(courses.get(3)) );
相关代码
PlanningSolution类
@PlanningSolution public class LecturerCourseBalancing { @ProblemFactCollectionProperty @ValueRangeProvider List<Lecturer> lecturers; @PlanningEntityCollectionProperty List<LecturerCourseAssignment> courses; @PlanningScore HardSoftBigDecimalScore score; public LecturerCourseBalancing() {} public LecturerCourseBalancing(List<Lecturer> lecturers, List<LecturerCourseAssignment> courses) { this.lecturers = lecturers; this.courses = courses; } public List<Lecturer> getLecturers() { return lecturers; } public List<LecturerCourseAssignment> getCourses() { return courses; } public HardSoftBigDecimalScore getScore() { return score; } }
LecturerCourseAssignment(规划实体)
@PlanningEntity public class LecturerCourseAssignment { @PlanningVariable Lecturer lecturer; Course course; public LecturerCourseAssignment() { } public LecturerCourseAssignment(Course course) { this.course = course; } public void setLecturer(Lecturer lecturer) { this.lecturer = lecturer; } public Lecturer getLecturer() { return lecturer; } public Course getCourse() { return course; } @Override public String toString() { return "LecturerCourseAssignment [lecturer=" + lecturer + ", course=" + course + "]"; } }
Lecturer.java(问题事实)
public class Lecturer { @PlanningId String id; String name; public Lecturer(String id, String name) { this.id = id; this.name = name; } public String getId() { return id; } public String getName() { return name; } @Override public String toString() { return "Lecturer [id=" + id + ", name=" + name + "]"; } }
Course.java
public class Course { @PlanningId String id; String name; int duration; public Course() {} public Course(String id, String name, int duration) { this.id = id; this.name = name; this.duration = duration; } public String getId() { return id; } public int getDuration() { return duration; } public String getName() { return name; } @Override public String toString() { return "Course [id=" + id + ", name=" + name + ", duration=" + duration + "]"; } }
Constraint Provider
public class LecturerCourseBalancingConstraintProvider implements ConstraintProvider { @Override public Constraint @NonNull [] defineConstraints(@NonNull ConstraintFactory constraintFactory) { return new Constraint[] { fairLecturerCourseAssignment(constraintFactory), }; } Constraint fairLecturerCourseAssignment(ConstraintFactory constraintFactory) { return constraintFactory.forEach(LecturerCourseAssignment.class) .groupBy(ConstraintCollectors.loadBalance(lca -> lca.getLecturer(), lca -> lca.getCourse().getDuration())) .penalizeBigDecimal(HardSoftBigDecimalScore.ONE_SOFT, (loadBalance) -> { System.out.println(loadBalance.loads()); System.out.println(loadBalance.unfairness()); return loadBalance.unfairness(); }) .asConstraint("fairLecturerCourseAssignment"); } }
内容的提问来源于stack exchange,提问作者Aiman Daniel
相关产品推荐
相关产品推荐

