OptaPlanner 7.48无法通过历史最优解或序列化解恢复求解咨询
OptaPlanner 7.48版本提前终止后重启求解失效问题修复方案
问题根因
- OptaPlanner 7.48版本存在已知的求解器状态清理bug:调用
terminateEarly()后内部的随机数状态、禁忌表、移动选择器遍历进度等上下文不会被同步重置,两次solve()调用间隔越短,越容易命中未清理完成的残留状态,导致局部搜索阶段持续生成无效移动,CPU高负载但无法产出新的最优解。 - 直接传入上一次求解的最佳解、或者序列化后重新加载的解时,如果解的影子变量未完整计算、规划实体的
@PlanningId赋值异常,会导致Construction Heuristics阶段错误跳过部分实体初始化,压缩后续搜索空间,出现无法寻优的问题。
解决方案
- 优先升级到7.59.Final及以上的7.x稳定版本,官方已在后续补丁中修复了终止后状态重置的逻辑,从根源解决该问题。如果暂时无法升级版本,每次调用
terminateEarly()后增加1~2秒的等待时长,再触发第二次solve()调用,等待内部状态异步清理完成。 - 不复用旧的Solver实例,每次重启求解前通过
SolverFactory重新构建新的Solver实例,彻底规避状态残留问题,该方案兼容所有7.x版本,是最稳妥的临时修复方案:
// 每次重启求解都新建Solver实例 Solver<YourSolution> newSolver = solverFactory.buildSolver(); YourSolution restartSolution = oldSolver.getBestSolution(); newSolver.solve(restartSolution);
- 序列化恢复解的场景下,反序列化完成后先调用
ScoreManager做一次分数校正,确认解的状态正常后再传入求解器:
ScoreManager<YourSolution> scoreManager = ScoreManager.create(solverFactory); scoreManager.updateScore(deserializedSolution); // 确认解已完成初始化且分数有效再开始求解 if (deserializedSolution.getScore().isSolutionInitialized()) { newSolver.solve(deserializedSolution); }
- 调整求解器配置,禁用局部搜索阶段的持久化禁忌表,强制每次求解重置搜索状态:
<localSearch> <unionMoveSelector> <cacheType>STEP</cacheType> <selectionOrder>RANDOM</selectionOrder> </unionMoveSelector> <acceptor> <persistentTabu>false</persistentTabu> <tabuSize>1000</tabuSize> </acceptor> <!-- 原有终止配置保持不变 --> </localSearch>
内容的提问来源于stack exchange,提问作者JLL
相关产品推荐
相关产品推荐

