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

Optaplanner规划时错误分配规划实体问题及解决方法

销售人员预约分配的OptaPlanner可行解处理方案

问题背景

业务场景为将销售人员分配至预约列表,需考虑销售人员的行程移动,采用OptaPlanner实现调度功能。现有硬约束可正常检查同一销售人员同一时间最多只能有一个预约,但当不存在可行分配方案时,规划器仍会为预约随机分配销售人员,导致最终方案无法使用。需求明确:若某预约无可用销售人员可分配,则不为该预约分配任何人。

原有冲突约束代码

Constraint repConflict(ConstraintFactory constraintFactory) {
        // 同一销售人员同一时间最多只能有一个预约
        return constraintFactory
                // 选取每一对不同的预约...
                .forEachUniquePair(Appointment.class,
                        Joiners.equal(Appointment::getRepUuid))
                .filter((appt1, appt2) ->{
                    if(appt1.getStartTime().before(appt2.getStartTime()) &&
                            appt1.getEndTime().before(appt2.getStartTime()) &&
                            appt1.getStartTime().before(appt2.getEndTime()) &&
                            appt1.getEndTime().before(appt2.getEndTime())) {
                        return false;
                    }
                    return true;
                })
                // 每出现一对冲突就施加硬惩罚
                .penalize(HardSoftScore.ONE_HARD)
                .asConstraint("SalesRep conflict");
    }

尝试过的无效配置

曾修改SolverFactory配置,设置终止条件为找到可行解,但未解决问题:

SolverFactory<RepRoutingSolution> solverFactory = SolverFactory.create(new SolverConfig()
                .withSolutionClass(RepRoutingSolution.class)
                .withEntityClasses(Appointment.class)
                .withConstraintProviderClass(RepSchedulerConstraintProvider.class)
                .withTerminationConfig(new TerminationConfig()
                        .withBestScoreFeasible(true)
                )
                // 小数据集下仅运行5秒,建议实际场景至少运行5分钟("5m")
                .withTerminationSpentLimit(Duration.ofSeconds(5)));


        // 加载问题数据
        RepRoutingSolution problem = generateDemoData();

        // 求解
        Solver<RepRoutingSolution> solver = solverFactory.buildSolver();
        RepRoutingSolution solution = solver.solve(problem);

        // 可视化结果
        printRepVisits(solution);

有效解决方法:新增奖励约束

新增一个奖励约束后,问题得到解决。该约束对同一销售人员名下无时间冲突的预约组合给予中等奖励,引导规划器优先保留可行的分配关系,对于无法找到可行分配的预约,规划器会自动不分配销售人员:

Constraint repRewardForAppointment(ConstraintFactory constraintFactory) {
        
        return constraintFactory
                // 选取每一对不同的预约...
                .forEachUniquePair(Appointment.class,
                        Joiners.equal(Appointment::getRepUuid))
                .filter((appt1, appt2) -> {
                    if (appt1.getStartTime().before(appt2.getStartTime()) &&
                            appt1.getEndTime().before(appt2.getStartTime()) &&
                            appt1.getStartTime().before(appt2.getEndTime()) &&
                            appt1.getEndTime().before(appt2.getEndTime())) {
                        return true;
                    }
                    return false;
                })
                // 每出现一对无冲突的组合就给予中等奖励
                .reward(HardMediumSoftScore.ONE_MEDIUM)
                .asConstraint("SalesRep reward for Appointments");
    }

内容的提问来源于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 09:35:35