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

OptaPlanner使用@PlanningListVariable时多规划变量启动报错

OptaPlanner多规划变量场景启动报错修复

问题背景

使用OptaPlanner实现时间表自动生成功能,需求为单个活动(规划实体)分配多名协作人员(规划变量),判断支持List类型作为规划变量即可满足需求,找到@PlanningListVariable注解但未掌握具体使用方法,无公开参考案例,编写的规划实体代码如下:

@PlanningEntity
@Entity
@Table(name = "activity")
public class Activity implements Serializable {

    private static final long serialVersionUID = 1L;

    @PlanningId
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id")
    private Long id;

    @Column(name = "activity_label")
    private String activityLabel;

//    @PlanningVariable(valueRangeProviderRefs = "locationRange")
    @PlanningListVariable(valueRangeProviderRefs = "locationRange")
    @JsonIgnoreProperties(value = { "resource", "typeOfLocation" }, allowSetters = true)
    @ManyToMany
    private List<Location> location;

    @PlanningListVariable(valueRangeProviderRefs = "collaboratorRange")
    @ManyToMany
    @JsonIgnoreProperties(value = { "resource", "typeOfCollaborator" }, allowSetters = true)
    private List<Collaborator> collaborator;

    @PlanningVariable(valueRangeProviderRefs = "equipmentRange")
    @ManyToOne
    @JsonIgnoreProperties(value = { "resource", "typeOfEquipment" }, allowSetters = true)
    private Equipment equipment;

    ...
}

报错现象

代码编写完成后启动应用抛出异常,核心错误日志如下:

Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.optaplanner.core.api.solver.SolverManager]: Factory method 'solverManager' threw exception; nested exception is java.lang.IllegalArgumentException: The config (ValueSelectorConfig(null)) has no configured variableName for entityClass (class com.planning.sp.domain.Activity) and because there are multiple variableNames ([collaborator, equipment, location, period]), it cannot be deduced automatically.

异常核心逻辑:ValueSelectorConfig未针对实体类com.planning.sp.domain.Activity配置variableName,该实体存在collaborator、equipment、location、period多个规划变量,框架无法自动推导对应变量名称,最终导致SolverManager实例化失败、应用启动报错。

根因与修复方案

  • 根因1:同个规划实体下同时混用单值规划变量(@PlanningVariable修饰,如equipment、period)和列表规划变量(@PlanningListVariable修饰,如location、collaborator)时,OptaPlanner默认的自动求解配置无法自动推断每个值选择器对应的变量,必须显式手动配置,不能依赖框架自动推导。
  • 根因2:@PlanningListVariable是OptaPlanner为多值分配场景设计的专用注解,默认的移动生成器仅适配单值规划变量,列表变量需要搭配专用的列表移动生成器,未配置时也会触发配置推导失败的问题。

具体修复操作:

  1. 版本校验:将OptaPlanner升级至8.20及以上稳定版本,低于该版本的@PlanningListVariable为实验性功能,存在大量Spring Boot自动配置兼容问题。
  2. 实体初始化:给所有@PlanningListVariable修饰的字段初始化为空的可变集合(如new ArrayList<>()),不能为null,也不要提前预置业务初始值,避免求解器初始化阶段报错。
  3. 显式配置求解规则:不要依赖默认自动配置,在求解器配置文件(Spring Boot项目可放在solverConfig.xml,或通过配置类声明)中为每个规划变量显式指定值选择器,列表变量必须使用专用的列表移动选择器,参考配置如下:
<solver>
  <!-- 域访问、终止条件等基础配置保持原有逻辑即可 -->
  <constructionHeuristic>
    <!-- 逐个声明所有单值、列表变量的放置规则 -->
    <queuedValuePlacer>
      <valueSelector variableName="period"/>
    </queuedValuePlacer>
    <queuedValuePlacer>
      <valueSelector variableName="equipment"/>
    </queuedValuePlacer>
    <queuedValuePlacer>
      <valueSelector variableName="location"/>
    </queuedValuePlacer>
    <queuedValuePlacer>
      <valueSelector variableName="collaborator"/>
    </queuedValuePlacer>
  </constructionHeuristic>
  <localSearch>
    <unionMoveSelector>
      <!-- 单值变量用普通changeMoveSelector -->
      <changeMoveSelector>
        <valueSelector variableName="period"/>
      </changeMoveSelector>
      <changeMoveSelector>
        <valueSelector variableName="equipment"/>
      </changeMoveSelector>
      <!-- 列表变量必须使用专用的listChangeMoveSelector、listSwapMoveSelector -->
      <listChangeMoveSelector>
        <valueSelector variableName="location"/>
      </listChangeMoveSelector>
      <listChangeMoveSelector>
        <valueSelector variableName="collaborator"/>
      </listChangeMoveSelector>
      <listSwapMoveSelector>
        <valueSelector variableName="location"/>
      </listSwapMoveSelector>
      <listSwapMoveSelector>
        <valueSelector variableName="collaborator"/>
      </listSwapMoveSelector>
    </unionMoveSelector>
  </localSearch>
</solver>
  1. 配置加载:如果是Spring Boot项目,在application.yml中指定求解器配置路径,确保自定义配置被正确加载:
optaplanner:
  solver:
    solver-config-xml: classpath:solverConfig.xml

内容的提问来源于stack exchange,提问作者Harold-debug

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 03:18:33