OptaPlanner中PlanningVariable被赋范围外null值的问题咨询
问题本质原因
- @PlanningVariable默认允许null值
OptaPlanner 7.x版本中,@PlanningVariable注解的nullable属性默认值为true,该配置优先级高于值范围提供器的内容:即使你定义的indexRange值范围没有null,求解器仍会生成将index赋值为null的合法移动,用于表示变量未分配的中间状态。 - 监听器触发场景包含移动撤销操作
你在afterVariableChanged中观测到的null值,大概率是求解器的移动撤销操作触发的:比如求解器先尝试执行将index赋值为1的移动,触发监听器;如果该移动评分不如当前最优解,求解器会撤销该移动,将index改回之前的null值,此时会再次触发监听器,这就是你观测到同个solution实例下先后出现1和null的原因。
解决方案
如果你的业务场景不允许index为null,直接修改@PlanningVariable配置,显式关闭nullable即可:
@PlanningVariable(valueRangeProviderRefs = "indexRange", nullable = false) private Index index;
需要注意:关闭nullable后,你需要保证输入的问题实例中所有Task的index属性都已经被初始化,或者配置构造启发式算法(Construction Heuristic)完成变量的初始化,否则求解器启动时会抛出变量未初始化的异常。
如果你允许中间状态存在null,只需要在UpdatingVariableListener的逻辑中增加null值判断即可,避免空指针异常:
@Override public void afterVariableChanged(ScoreDirector scoreDirector, Task task) { if (task.getIndex() == null) { // 给d设置null或者默认值,适配空状态 scoreDirector.beforeVariableChanged(task, "d"); task.setD(null); scoreDirector.afterVariableChanged(task, "d"); return; } // 原有d的计算逻辑 }
内容的提问来源于stack exchange,提问作者brewphone
相关产品推荐
相关产品推荐

