You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让Optaplanner仅接受全正分数解?销售排班约束问题咨询

问题场景与需求
  • 业务场景:使用Optaplanner实现跨地点的销售人员-预约排班调度,销售人员需往返不同地点赴约。
  • 已实现约束:
    1. 销售人员工作时间约束
    2. 同一时间一名销售人员最多承接一个预约
  • 问题:单独启用任一约束时排班结果正常,但同时启用后出现约束违规的分配结果。推测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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 13:31:00