求助:为后续作业宽度不同的作业调度添加软分数惩罚
作业调度宽度切换约束实现建议
针对你作业调度中宽度切换的软惩罚需求,你当前的代码缺少关联相邻作业并过滤宽度差异的逻辑,无法正确触发惩罚。以下是修正后的实现:
private Constraint customConstraint(ConstraintFactory constraintFactory) { return constraintFactory.forEach(Job.class) // 关联当前作业和它的下一个作业(按调度顺序) .join(Job.class, Joiners.nextElement()) // 过滤出前后作业宽度不同的情况 .filter((currentJob, nextJob) -> !currentJob.getWidth().equals(nextJob.getWidth())) // 对每一次宽度切换施加1个软惩罚 .penalize(HardSoftScore.ONE_SOFT) .asConstraint("Width change penalty"); }
关键逻辑说明:
Joiners.nextElement():OptaPlanner提供的关联器,用于按规划顺序找到当前实体的下一个实体,这是实现相邻作业检查的核心。- 过滤条件
!currentJob.getWidth().equals(nextJob.getWidth()):精准定位需要惩罚的宽度切换场景,避免无差别惩罚。 - 惩罚力度可根据需求调整,比如用
HardSoftScore.ofSoft(5)来加大单次切换的惩罚权重。
类比教师换教室场景的实现
对应Hello World快速入门示例中教师更换教室的需求,逻辑完全一致:找到同一教师的相邻课程,若教室不同则施加软惩罚,代码示例如下:
private Constraint teacherRoomChangePenalty(ConstraintFactory constraintFactory) { return constraintFactory.forEach(Lesson.class) .join(Lesson.class, Joiners.equal(Lesson::getTeacher), // 关联同一教师的课程 Joiners.nextElement()) // 找到该教师的下一节课程 .filter((currentLesson, nextLesson) -> !currentLesson.getRoom().equals(nextLesson.getRoom())) .penalize(HardSoftScore.ONE_SOFT) .asConstraint("Teacher room change penalty"); }
内容的提问来源于stack exchange,提问作者MattWolc24
相关产品推荐
相关产品推荐

