Optaplanner新手求助:解决方案中出现重复规划实体问题
嘿,作为OptaPlanner新手,你的思路方向是对的,但咱们得一步步拆解你遇到的两个问题:
一、链式变量的建模思路是否正确?
完全正确!用时间链式模式把VirtualMachine作为锚点来构建任务分配模型,非常适配你这种“资源→任务序列”的调度场景,尤其是后续要添加开始/结束时间这类影子变量时,链式结构能完美支持依赖计算。
不过有个关键细节要补:你要求“所有机器必须被使用”,这个得通过硬约束来强制实现。比如写一个约束规则,检查每个VirtualMachine的任务链是否非空,否则直接判定为不可行解——不然求解器可能会为了优化其他目标(比如总执行时长)而闲置部分机器。
二、关于重复
MarkerNesting实例的异常 你看到的“哈希值不同但业务ID相同”的情况,不是代码bug,而是OptaPlanner的解决方案克隆机制导致的正常行为,但你的输出逻辑没处理好,才显得异常:
- OptaPlanner在搜索最优解的过程中,会频繁克隆整个解决方案(
Solution)。每次克隆都会创建实体(比如MarkerNesting)的新对象实例——这些实例的业务ID完全一致,但对象引用不同(所以哈希值不一样),本质是同一个业务实体的不同“快照”。 - 你输出里的重复,大概率是打印时把不同克隆快照里的同一个实体混在一起了,比如旧的解决方案实例没被正确回收,或者输出逻辑没基于业务ID去重。
给你几个解决建议:
- 给
MarkerNesting实体正确重写equals()和hashCode()方法,**完全基于业务ID(而非对象引用)**实现。这样即使是不同克隆的实例,只要ID相同,就会被判定为相等,避免输出时看起来重复。 - 在打印解决方案时,遍历每个VM的任务链时,基于业务ID去重(比如用
Set存储任务,或者直接判断ID是否已出现)。 - 确保你的实体类添加了
@PlanningId注解到业务ID字段——OptaPlanner依赖这个注解识别唯一的业务实体,克隆和约束计算都需要它。
另外,你测试4台机器+4个任务却出现了任务链,说明约束还没到位:比如没添加“每个任务只能分配一次”的硬约束,或者没限制每个VM的任务链长度为1。记得把这些约束补上,才能得到预期的“每台机器一个任务”的结果。
内容的提问来源于stack exchange,提问作者cdelmas
相关产品推荐
相关产品推荐

