Optaplanner建模:动态调整@PlanningEntityCollectionProperty集合大小实现动态时隙调度
你提到的「预先提供合理范围的候选时隙集合+新增约束最小化使用时隙数」是适配Optaplanner现有模型的最优实现方案,Optaplanner不支持规划过程中动态新增/删除问题事实或规划实体,因此无法在运行时凭空生成新的时隙,只能通过预生成冗余候选池+约束过滤的方式实现需求。
1. 预生成候选时隙池
先计算你业务场景下所需时隙的理论最大值:
理论时隙上限 = 所有项目总待调度预算 / 单时隙最小可分配容量 + 10%~20%冗余
将该数量的时隙、对应时隙容量配置全部预先加入Schedule类的timeslots、timeslotBudgets集合中,同时为每个项目和每个候选时隙初始化对应的BudgetByProjectAndTimeslot规划实体。
2. 调整约束优先级配置
按从高到低的优先级配置约束,保证核心需求按顺序满足:
硬约束(优先级最高,不满足则解无效)
- 项目总预算完全分配:每个项目在所有时隙的分配预算总和,必须等于该项目的总待调度预算,不满足扣硬分
- 时隙容量不超配:每个时隙所有项目的分配预算总和,不得超过该时隙的最大容量,不满足扣硬分
软约束(优先级次之,优化解质量)
- 时隙利用率最优化:最小化每个已使用时隙的实际分配容量与100%利用率的偏差,和你原有优化目标保持一致
- 时隙数量最小化:每有一个时隙存在预算分配(即该时隙分配总和>0),就扣除固定软分,分数权重需低于利用率偏差的权重,保证先满足利用率要求,再尽量减少时隙使用数量
代码示例(约束流写法参考)
// 硬约束:项目总预算必须全部分配 fun projectBudgetFullyAllocated(constraintFactory: ConstraintFactory): Constraint = constraintFactory.forEach(BudgetByProjectAndTimeslot::class.java) .groupBy({ it.project }, sum { it.timeslotBudgetAmount }) .filter { project, allocated -> allocated != project.totalRequiredBudget } .penalize(HardSoftScore.ONE_HARD) .asConstraint("Project budget not fully allocated") // 软约束:最小化使用的时隙数量 fun minimizeUsedTimeslots(constraintFactory: ConstraintFactory): Constraint = constraintFactory.forEach(BudgetByProjectAndTimeslot::class.java) .groupBy({ it.timeslot }, sum { it.timeslotBudgetAmount }) .filter { _, allocated -> allocated > 0 } .penalize(HardSoftScore.ofSoft(1)) // 权重可根据业务调整 .asConstraint("Minimize used timeslots")
注意事项
- 候选时隙池不需要设置过大,只要比理论上限多10%~20%即可,过大的池会提升求解复杂度,拖慢求解速度
- 时隙数量最小化的软约束权重需要调试,避免优先级过高导致优化器为了减少时隙数量,牺牲过多的时隙利用率
内容的提问来源于stack exchange,提问作者greyhairredbear
相关产品推荐
相关产品推荐

