升级至Optaplanner 8.34.0.Final时出现分数损坏问题求助
OptaPlanner升级后Bavet实现的分数损坏问题排查
问题场景
- 升级至OptaPlanner 9后,解决方案出现异常表现;开启全断言模式后,触发此前未出现的分数损坏警告,经排查该问题首次出现于8.34.0版本
- 问题仅在Bavet约束流实现中复现,切换为DROOLS CS实现则无异常
调整尝试与结果
- 原约束实现:在join操作中使用
Joiners.filtering((name, hole) -> !hole.getPeg().isSquare())做关联过滤,触发分数损坏警告 - 修改后实现:先执行join操作,再调用
filter((name, hole) -> !hole.getPeg().isSquare())做过滤,分数损坏警告消失,但执行效率大幅下降
问题分析
这大概率是Bavet约束流中Joiners.filtering()的实现bug,而非你的用法错误,理由如下:
- 两种写法逻辑完全等价,仅过滤时机不同(join阶段过滤 vs join后过滤),且在DROOLS CS下均正常运行,说明业务逻辑本身无问题
- 分数损坏通常源于约束流增量计算的状态跟踪错误,Bavet在处理join阶段的过滤条件时,可能未正确维护分数计算的一致性,导致移动操作后分数计算出现偏差
- 切换到join后过滤的方式,会生成更多中间关联对,约束计算的时间复杂度上升,因此出现效率下降的情况
建议
- 暂时保留join后过滤的写法作为临时解决方案
- 向OptaPlanner官方提交问题,附上最小复现案例,包括8.34.0版本环境信息、Bavet下的分数损坏日志,以及两种写法的对比代码
内容的提问来源于stack exchange,提问作者dennis hilley
相关产品推荐
相关产品推荐

