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

OptaPlanner CH阶段初始化实体时IllegalStateException问题求助

解决方案

1. 提前让所有规划实体被求解器识别

OptaPlanner在启动求解流程前会扫描Solution对象中的所有规划实体集合,要避免在构造启发式(CH)阶段动态添加实体。必须在启动任何CH阶段之前,将RestBreak和DutyGrain的所有实例都添加到Solution对应的实体集合中,确保求解器启动时就能扫描到所有实体,这样影子变量更新时就不会出现“fact was never inserted”的异常。

同时检查影子变量的注解配置:确保@ShadowVariable的sourceEntityClass、sourceVariableName等参数准确指向RestBreak的对应变量,保证RestBreak开始时间变更时,能正确关联到对应的DutyGrain实例。

2. 在约束流中过滤未注册的实体

如果确实无法提前初始化所有实体,可在约束流中添加过滤逻辑,跳过未被求解器识别的实例。利用OptaPlanner提供的isWorkingObject()方法判断实体是否在工作内存中:

constraintFactory.from(DutyGrain.class)
    // 过滤掉未被求解器识别的实体
    .filter(dutyGrain -> constraintFactory.getScoreDirector().isWorkingObject(dutyGrain))
    .filter(DutyGrain::isResting)
    // 针对规划变量的分配操作添加惩罚
    .penalize("Resting DutyGrain cannot be assigned", HardSoftScore.ONE_HARD);

如果需要处理规划变量为null的场景,可补充过滤条件(惩罚所有非空分配操作):

constraintFactory.from(DutyGrain.class)
    .filter(dutyGrain -> constraintFactory.getScoreDirector().isWorkingObject(dutyGrain))
    .filter(DutyGrain::isResting)
    .filter(dutyGrain -> dutyGrain.getYourPlanningVariable() != null)
    .penalize("Assign to resting DutyGrain", HardSoftScore.ONE_HARD);

isWorkingObject()方法会验证实例是否是求解器工作内存中的有效对象,未注册的实体将被过滤,从而避免抛出异常。

关键注意点

  • 尽量避免在CH阶段动态添加实体,这会破坏求解器的初始化流程,导致影子变量同步逻辑出现不可预期的问题。
  • 若必须动态添加实体,需通过ProblemFactChange显式通知求解器更新工作内存,但这种方式复杂度较高,仅建议作为兜底方案。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 08:32:43