Optaplanner中@PlanningEntity内@ValueRangeProvider的使用咨询
OptaPlanner中基于员工类型过滤会议分配员工的解决方案
核心问题解答
是否需要同时在PlanningSolution和PlanningEntity中配置@ValueRangeProvider?
不需要。当PlanningEntity中定义了针对特定PlanningVariable的范围提供者时,OptaPlanner会优先使用该实体级别的范围,而非PlanningSolution中的全局范围。如果全局范围无特殊需求,甚至可以去掉PlanningSolution中employeeList上的@ValueRangeProvider注解。如何在Meeting中获取MySolution的原始员工列表?
通过在Meeting实体中添加@PlanningSolutionProperty注解的Solution引用,OptaPlanner会自动将当前求解的Solution实例注入到该字段中,无需手动关联。
修改后的代码示例
MySolution类
@PlanningSolution public class MySolution { ... // 仅保留问题事实注解,去掉全局范围提供者(若使用实体级范围) @ProblemFactCollectionProperty private List<Employee> employeeList; @PlanningEntityCollectionProperty private List<Meeting> meetingList; ... // 添加employeeList的getter方法,供Meeting过滤使用 public List<Employee> getEmployeeList() { return employeeList; } }
Meeting类
@PlanningEntity public class Meeting{ ... // OptaPlanner自动注入当前Solution实例 @PlanningSolutionProperty private MySolution mySolution; // 指定使用实体级的范围提供者 @PlanningVariable(nullable = true, valueRangeRef = "filteredEmployeeList") private Employee employee; // 会议所需的员工类型(根据实际业务定义) private EmployeeType requiredEmployeeType; ... // 实体级范围提供者:过滤出符合会议类型要求的员工 @ValueRangeProvider(id = "filteredEmployeeList") public List<Employee> getFilteredEmployeeList() { return mySolution.getEmployeeList().stream() .filter(emp -> emp.getType().equals(requiredEmployeeType)) .collect(Collectors.toList()); } // 必须添加相关属性的getter/setter public MySolution getMySolution() { return mySolution; } public void setMySolution(MySolution mySolution) { this.mySolution = mySolution; } public EmployeeType getRequiredEmployeeType() { return requiredEmployeeType; } }
额外说明
- 若所有会议的员工过滤逻辑一致,也可在PlanningSolution的
@ValueRangeProvider中统一过滤,但如果不同会议需匹配不同员工类型,必须使用实体级的范围提供者实现动态过滤。 - 无需手动为每个Meeting设置
mySolution实例,OptaPlanner会在求解过程中自动完成注入。
内容的提问来源于stack exchange,提问作者Christian
相关产品推荐
相关产品推荐

