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

OptaPlanner Shadow Variables理解及栈溢出报错问题求助

问题根因说明

你的栈溢出错误和Shadow Variables本身的运行逻辑无关,是两个代码写法错误共同导致的:

  • Lombok @Data注解触发双向引用递归
    @Data注解会自动生成包含类下所有字段的hashCode()、equals()、toString()方法。你的代码里CloudProcess持有CloudComputer类型的规划变量字段,CloudComputer又持有List<CloudProcess>类型的影子变量字段,形成了双向引用链:

    计算CloudProcess的hashCode → 计算其内部cloudComputer字段的hashCode → 遍历cloudComputer的processList计算每个CloudProcess的hashCode → 回到第一步无限递归
    递归深度超过JVM栈限制就会抛出StackOverflowError,从错误栈里交替出现CloudComputer.hashCode、CloudProcess.hashCode、ArrayList.hashCode就能直接确认这个问题。

  • 实体注解标注错误
    CloudComputer是固定的问题事实(求解过程中不会修改它的属性),你已经在CloudBalance类里把computerList标注为@ProblemFactCollectionProperty,就不应该给CloudComputer类加@PlanningEntity注解,多余的实体注解会干扰OptaPlanner的正常扫描逻辑。
Shadow Variables(影子变量)运行机制

OptaPlanner里的变量分两类:

  • 真正的规划变量:就是加了@PlanningVariable注解的字段,是求解器求解过程中会主动调整、赋值的核心变量,比如你代码里CloudProcess的cloudComputer字段,求解器会不断尝试给每个进程分配不同的机器,最终找到分数最高的分配方案。
  • 影子变量:求解器不会直接给这类字段赋值,它的值会自动和一个或多个规划变量的状态保持同步,作用是简化关联关系的维护,写约束的时候不用每次都全量遍历实体集合做反向查找。

你用的@InverseRelationShadowVariable是最常用的影子变量类型,属于反向关联影子变量:指定sourceVariableName = "cloudComputer"后,只要某个CloudProcess的cloudComputer字段被求解器修改,OptaPlanner会自动同步维护两边的关联关系:

  • 进程被分配给某台机器时,自动把进程加入对应机器的processList
  • 进程从一台机器迁移到另一台时,自动从原机器的processList移除,加入新机器的processList
    整个同步过程不需要你写任何额外的维护代码。
修复方案

按以下步骤调整代码即可解决问题:

  1. 去掉CloudComputer类上的@PlanningEntity注解,它属于问题事实,不需要标注为规划实体。
  2. 处理双向引用的递归问题,不要直接在存在双向关联的规划实体/问题事实类上使用无配置的@Data注解:
    • 给CloudComputer、CloudProcess添加唯一标识id字段,基于id重写hashCode()和equals()方法,不要把双向关联字段纳入计算
    • 如果暂时不添加id,使用Lombok注解排除双向关联字段:
      // CloudProcess类上添加注解,排除双向关联的cloudComputer字段
      @EqualsAndHashCode(exclude = "cloudComputer")
      @ToString(exclude = "cloudComputer")
      
      // CloudComputer类上添加注解,排除双向关联的processList字段
      @EqualsAndHashCode(exclude = "processList")
      @ToString(exclude = "processList")
      

调整后重启求解即可正常运行,影子变量的关联维护逻辑会自动生效。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 19:51:17