OptaPlanner纯Java代码构建求解器咨询(无需XML配置)
完全懂你的需求!OptaPlanner确实支持纯Java代码搭建求解器,完全不用依赖XML配置文件。我就拿经典的N皇后问题举例子,一步步带你实现你想要的那种链式调用式的求解器构建:
纯Java构建OptaPlanner求解器全流程
1. 先搞定领域模型的注解配置
即使不用XML,你的规划实体类和解决方案类还是需要用OptaPlanner的注解标记——这是求解器识别核心规划元素的基础,比如哪些是变量、哪些是实体、哪些是待解问题。
举个简化的N皇后模型示例:
// 规划实体类:皇后 @PlanningEntity public class Queen { private Integer id; private Integer row; // 规划变量:皇后所在列(由求解器填充) @PlanningVariable(valueRangeProviderRefs = "columnRange") private Integer column; // 构造器、getter、setter自行补充 }
// 规划解决方案类:N皇后问题整体 @PlanningSolution public class NQueens { private int n; // 列的取值范围提供器 @ValueRangeProvider(id = "columnRange") public CountableValueRange<Integer> getColumnRange() { return ValueRangeFactory.createIntValueRange(0, n); } // 所有皇后的集合 @PlanningEntityCollectionProperty private List<Queen> queenList; // 问题得分 @PlanningScore private SimpleScore score; // 构造器、getter、setter自行补充 }
2. 核心:用SolverConfig纯代码配置求解器
接下来就是你想要的纯Java链式配置部分,通过SolverConfig类可以替代XML的所有配置项,包括得分计算器、搜索策略、终止条件等。
完整可运行示例代码
public class NQueensPureJavaSolver { public static void main(String[] args) { // 1. 初始化SolverConfig并绑定领域模型 SolverConfig solverConfig = new SolverConfig() .withSolutionClass(NQueens.class) .withEntityClasses(Queen.class); // 2. 配置得分计算器(这里用你提到的EasyScoreCalculator) solverConfig.setScoreDirectorFactoryConfig( new ScoreDirectorFactoryConfig() .withEasyScoreCalculatorClass(NQueensEasyScoreCalculator.class) // 如果想用Drools规则得分,可替换为withScoreDrlString直接传入规则代码,无需drl文件 ); // 3. 配置终止条件:比如10秒内找到最优解就停止 solverConfig.setTerminationConfig( new TerminationConfig() .withSecondsSpentLimit(10L) .withBestScoreLimit("0hard/0soft") ); // 4. 配置搜索阶段:先构造启发式快速生成可行解,再局部搜索优化 solverConfig.setPhaseList(List.of( new ConstructionHeuristicPhaseConfig() .withConstructionHeuristicType(ConstructionHeuristicType.FIRST_FIT_DECREASING), new LocalSearchPhaseConfig() .withLocalSearchType(LocalSearchType.LATE_ACCEPTANCE) .withAcceptedCountLimit(1000L) )); // 5. 构建求解器并运行 SolverFactory<NQueens> solverFactory = SolverFactory.create(solverConfig); Solver<NQueens> solver = solverFactory.buildSolver(); // 生成初始未解决的8皇后问题 NQueens unsolvedNQueens = createUnsolvedNQueens(8); // 求解 NQueens solvedNQueens = solver.solve(unsolvedNQueens); // 输出结果 System.out.println("求解完成,得分:" + solvedNQueens.getScore()); solvedNQueens.getQueenList().forEach(queen -> System.out.printf("皇后%d:行%d,列%d%n", queen.getId(), queen.getRow(), queen.getColumn()) ); } // 生成初始未填充列的N皇后问题 private static NQueens createUnsolvedNQueens(int n) { NQueens nQueens = new NQueens(); nQueens.setN(n); List<Queen> queenList = new ArrayList<>(); for (int i = 0; i < n; i++) { Queen queen = new Queen(); queen.setId(i); queen.setRow(i); queen.setColumn(null); // 初始列设为null,交给求解器填充 queenList.add(queen); } nQueens.setQueenList(queenList); return nQueens; } }
3. 关键配置点说明
- 得分计算器:除了
EasyScoreCalculator,还可以用IncrementalScoreCalculator(性能更优),或者直接通过withScoreDrlString传入Drools规则代码,完全脱离文件依赖。 - 搜索策略:可以灵活组合多个搜索阶段,比如构造启发式+局部搜索,也可以单独用一种搜索方式,根据问题复杂度调整即可。
- 终止条件:支持时间限制、步数限制、最优得分限制等多种条件,还可以组合使用(比如“找到最优解或运行10分钟就停止”)。
4. 注意事项
- 确保项目引入了OptaPlanner核心依赖(比如Maven的
optaplanner-core包)。 - 注解是不可或缺的——它是求解器识别规划元素的核心依据,和XML配置只是配置方式的不同,核心逻辑是一致的。
内容的提问来源于stack exchange,提问作者baiyyang
相关产品推荐
相关产品推荐

