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

OptaPlanner多约束配置:同项目不同方案类型约束复用问询

OptaPlanner多约束配置实现方案

问题描述

在同一项目中,OptaPlanner无法依据不同约束配置求解不同问题。若属于同一解决方案但方案类型不同,能否复用同一约束配置?例如在代码中通过不同pickingType约束不同类型的解决方案,或是有更优的实现思路?

用户示例代码

return constraintFactory.forEach(TrolleyStep.class)
            .filter(ele -> ele.getPickingType() == 0) //仅约束pickingType == 0
            .groupBy(trolleyStep -> trolleyStep.getOrderNumber(),
                    countDistinctLong(TrolleyStep::getTrolley))
            .penalizeLong("Minimize order split by trolley",
                    HardSoftLongScore.ONE_SOFT, (order, trolleySpreadCount) -> trolleySpreadCount * 10000);

可行实现思路

1. 基于业务标识的条件约束复用

你当前通过pickingType过滤约束的思路完全可行,适合同一解决方案下多类型场景的复用。可以进一步优化灵活性:

  • 将目标pickingType提升为解决方案类(如TrolleySolution)的属性,而非仅在实体类中判断,这样约束规则能直接适配整个求解方案的类型。
  • 优化后的示例代码:
// 假设TrolleySolution是你的解决方案类,包含targetPickingType属性
return constraintFactory.forEach(TrolleyStep.class)
        .filter(ele -> ele.getPickingType() == solution.getTargetPickingType())
        .groupBy(trolleyStep -> trolleyStep.getOrderNumber(), countDistinctLong(TrolleyStep::getTrolley))
        .penalizeLong("Minimize order split by trolley",
                HardSoftLongScore.ONE_SOFT, (order, trolleySpreadCount) -> trolleySpreadCount * 10000);

2. 拆分约束提供者,动态加载

如果不同方案类型的约束差异较大,建议拆分多个ConstraintProvider实现类,根据方案类型动态选择加载:

  • 为不同类型分别实现约束提供者:比如PickingType0Constraints、PickingType1Constraints
  • 求解时根据方案类型指定对应的约束类:
// 自定义方法,根据类型返回对应的约束提供者类
private Class<? extends ConstraintProvider> getConstraintProvider(int pickingType) {
    return pickingType == 0 ? PickingType0Constraints.class : PickingType1Constraints.class;
}

// 创建Solver时动态指定约束提供者
SolverFactory<TrolleySolution> solverFactory = SolverFactory.create(new SolverConfig()
        .withSolutionClass(TrolleySolution.class)
        .withEntityClasses(TrolleyStep.class)
        .withConstraintProviderClass(getConstraintProvider(solution.getPickingType())));

3. 参数化约束配置

将约束的权重、过滤规则等抽离为可配置参数,避免硬编码,进一步提升复用性:

  • 在解决方案类中添加约束配置参数,比如constraintConfig,包含不同类型的权重值
  • 约束中动态读取配置:
return constraintFactory.forEach(TrolleyStep.class)
        .filter(ele -> ele.getPickingType() == solution.getTargetPickingType())
        .groupBy(trolleyStep -> trolleyStep.getOrderNumber(), countDistinctLong(TrolleyStep::getTrolley))
        .penalizeLong("Minimize order split by trolley",
                HardSoftLongScore.ofSoft(solution.getConstraintConfig().getOrderSplitWeight()),
                (order, trolleySpreadCount) -> trolleySpreadCount);

内容的提问来源于stack exchange,提问作者Joy

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 16:24:31