如何让OptaPlanner不触发重复得分的新解决方案通知?
解决方案:避免OptaPlanner重复触发相同得分的最优解通知
针对你遇到的多线程(同随机种子)重复推送相同得分最优解的问题,给出几个实用方案:
主线程过滤重复通知(最适合新手快速落地)
直接在主线程的解决方案监听器里加一层判断:- 维护一个变量记录当前已拿到的最高得分
- 每次收到“新解决方案”通知时:
- 若新方案得分高于记录的最高得分:更新最高得分,同时重置无改进计时器,处理最优解
- 若得分相同:直接跳过,不触发任何后续逻辑
这种方式不用改OptaPlanner核心配置,完全在业务代码层解决问题。
调整多线程随机种子策略
你现在给所有线程用相同随机种子,导致搜索路径高度重合,才会重复找到相同最优解。给每个线程分配独立随机种子,能让各线程搜索路径差异化,减少重复通知,还能提升搜索效率。
代码示例:SolverConfig solverConfig = SolverConfig.createFromXmlResource("yourSolverConfig.xml"); solverConfig.setThreadCount(8); // 让OptaPlanner自动为每个线程生成不同随机种子(设为null即可) solverConfig.setRandomSeed(null);自定义SolutionAcceptor从内部控制
如果想从OptaPlanner层面拦截相同得分的方案,可以自定义SolutionAcceptor,只有当新方案得分严格优于当前最优时,才接受并触发通知。
示例代码:public class StrictBetterAcceptor implements SolutionAcceptor<YourSolutionType> { @Override public void accept(SolverScope<YourSolutionType> solverScope, YourSolutionType newSolution) { YourSolutionType bestSolution = solverScope.getBestSolution(); Score newScore = newSolution.getScore(); Score bestScore = bestSolution != null ? bestSolution.getScore() : null; // 仅接受得分严格更高的方案 if (bestScore == null || newScore.compareTo(bestScore) > 0) { solverScope.setBestSolution(newSolution); solverScope.getSolverEventSupport().fireBestSolutionChanged(newSolution); } } }然后在Solver配置文件中替换默认实现:
<solver> <solutionAcceptorClass>com.yourpackage.StrictBetterAcceptor</solutionAcceptorClass> </solver>
另外,你提到的“主线程自行跟踪结果+设置无改进计时器终止线程”的思路完全可行。具体可以这么做:每次收到有效(得分更高)的最优解时重置计时器,一旦计时器超时,直接调用solver.terminateEarly()终止所有求解线程,精准控制求解时长。
内容的提问来源于stack exchange,提问作者Matthew Winter
相关产品推荐
相关产品推荐

