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

如何扩展道路维护示例以支持多Crew分配至同一Job?

问题描述

基于道路维护示例扩展作业(Job)与班组(Crew)的关联关系,支持将多个Crew分配至同一Job(用于加快进度、提升优先级)。尝试将Job.crew从单例改为List<Crew>,将@PlanningVariable替换为@PlanningListVariable,并初始化非空List后,出现报错:基础规划变量和列表规划变量不能在同一实体类中使用。

解决方案

OptaPlanner不允许同一个规划实体类同时存在普通@PlanningVariable和@PlanningListVariable,可以通过以下两种方式解决:

方案1:移除Job类中的其他普通规划变量(仅保留列表规划变量)

如果你的Job类中原本只有crew这一个规划变量,检查是否存在其他被@PlanningVariable注解标记的字段,将它们全部移除或改为非规划变量(作为问题事实的固定属性)。之后确保Job类仅保留@PlanningListVariable标记的List<Crew>字段:

@PlanningEntity
public class Job {
    // 其他固定属性(非规划变量)
    private String jobId;
    private Duration duration;

    // 列表规划变量:支持分配多个班组
    @PlanningListVariable(valueRangeProviderRefs = "crewRange")
    private List<Crew> crewList = new ArrayList<>();

    // getter、setter、构造方法
}

这种方式适合Job仅需多班组分配这一项规划需求的场景。

方案2:引入中间分配实体(更通用的多分配场景)

如果Job类中存在其他必须保留的普通规划变量(比如作业开始时间startTime),推荐通过新增中间实体来实现多班组分配:

  1. 调整Job为问题事实:移除Job类上的@PlanningEntity注解,将其作为固定的问题数据(不再是规划实体)。
  2. 创建JobCrewAssignment规划实体:该实体代表“班组分配到作业”的关联关系,每个实例对应一个班组和一个作业:
@PlanningEntity
public class JobCrewAssignment {
    private Long assignmentId;
    // 关联的作业(问题事实,非规划变量)
    private Job job;
    // 规划变量:分配的班组
    @PlanningVariable(valueRangeProviderRefs = "crewRange")
    private Crew crew;

    // getter、setter、构造方法
}
  1. 更新规划解决方案类:将原有的Job规划实体集合替换为JobCrewAssignment集合,同时保留所有问题事实(Job列表、Crew列表):
@PlanningSolution
public class RoadMaintenanceSolution {
    @ValueRangeProvider(id = "crewRange")
    private List<Crew> crewList;
    // 问题事实:所有待处理的作业
    private List<Job> jobList;
    // 规划实体:所有班组-作业的分配关系
    @PlanningEntityCollectionProperty
    private List<JobCrewAssignment> assignmentList;

    // 分数计算器、getter、setter、构造方法
}

这种方式的优势是灵活支持复杂约束(比如限制同一班组在同一时间不能分配到多个作业、控制单个作业的最大班组数量等),也不会影响Job类原有的其他属性。

补充说明

如果选择方案2,需要在分数约束中添加逻辑:

  • 根据业务需求设置单个作业的最大班组分配数量
  • 避免班组的时间冲突(如果作业有时间维度的话)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 22:52:14