如何让Optaplanner仅接受全正分数解?销售排班约束问题咨询
问题场景与需求
- 业务场景:使用Optaplanner实现跨地点的销售人员-预约排班调度,销售人员需往返不同地点赴约。
- 已实现约束:
- 销售人员工作时间约束
- 同一时间一名销售人员最多承接一个预约
- 问题:单独启用任一约束时排班结果正常,但同时启用后出现约束违规的分配结果。推测Optaplanner在多受罚解中选择了分数最优方案,即便存在违规。
- 需求:仅接受所有分数维度(hard/medium/soft)均为非负值的解,任何维度出现负分的解直接被拒绝。例如:
- 接受:
(5hard/3medium/2soft)、(1hard/0medium/0soft) - 拒绝:
(6hard/-1medium/0soft)、(100hard/0medium/-1soft)
- 接受:
实现方案
1. 自定义可行性检查器过滤违规解
Optaplanner支持通过SolutionFeasibilityChecker接口自定义解的可行性判定逻辑,直接过滤掉存在负分维度的解。
代码示例(Java)
import org.optaplanner.core.api.score.Score; import org.optaplanner.core.api.solution.feasibility.SolutionFeasibilityChecker; import org.optaplanner.core.api.score.buildin.hardmediumsoft.HardMediumSoftScore; public class AllPositiveScoreFeasibilityChecker implements SolutionFeasibilityChecker<SalesSchedule> { @Override public boolean isFeasible(SalesSchedule solution) { Score score = solution.getScore(); // 适配你使用的分数类型,这里以HardMediumSoftScore为例 if (!(score instanceof HardMediumSoftScore)) { throw new IllegalArgumentException("Unsupported score type: " + score.getClass()); } HardMediumSoftScore hmsScore = (HardMediumSoftScore) score; // 检查所有维度分数是否非负 return hmsScore.getHardScore() >= 0 && hmsScore.getMediumScore() >= 0 && hmsScore.getSoftScore() >= 0; } }
启用检查器
通过Java API配置:
SolverFactory<SalesSchedule> solverFactory = SolverFactory.createFromXmlResource("salesScheduleSolverConfig.xml"); SolverConfig solverConfig = solverFactory.getSolverConfig(); // 绑定自定义可行性检查器 solverConfig.setSolutionFeasibilityCheckerClass(AllPositiveScoreFeasibilityChecker.class); Solver<SalesSchedule> solver = solverFactory.buildSolver();
或者在XML配置文件中添加:
<solver> <!-- 其他配置 --> <solutionFeasibilityCheckerClass>com.yourpackage.AllPositiveScoreFeasibilityChecker</solutionFeasibilityCheckerClass> </solver>
2. 约束逻辑与分数定义配合
确保每个约束的分数计算逻辑严格遵循:合规则加分(或不扣分),违规则对应维度分数为负。这样可行性检查器才能准确识别违规解。
例如,对于工作时间约束:
// 伪代码示例 rule "SalespersonWorkingTimeConstraint" when SalespersonAssignment(..., totalWorkingTime > maxAllowedTime) then scoreHolder.addHardConstraintMatch(kcontext, -1); // 违规时hard维度减分 end
注意事项
- 如果搜索过程中不存在所有维度均为非负的可行解,Optaplanner仍会返回当前搜索到的最优解(可能存在违规)。此时需要评估业务逻辑是否存在可行解,或适当调整约束的宽松程度。
- 若使用其他分数类型(如
HardSoftScore),只需修改可行性检查器中对应的分数维度判断逻辑即可。
内容的提问来源于stack exchange,提问作者user101
相关产品推荐
相关产品推荐

