OptaPlanner恢复时间表生成输出错误解问题求助
OptaPlanner恢复求解后解的约束大量不满足问题
问题详情
我用Java Spring Boot结合OptaPlanner开发了一个包含近20条约束的时间表生成系统。初始生成时一切正常,OptaPlanner日志显示的分数与所得解完全匹配。但从停止处恢复生成时,尽管求解流程从断点继续,最终得到的解却存在大量约束不满足的情况。
项目架构与流程
项目分为两个微服务:
- 微服务A:负责与UI交互,维护数据库
- 微服务B:接收启动/恢复生成请求,从微服务A获取数据,使用OptaPlanner生成时间表
流程:UI发送启动、恢复、停止、获取时间表请求 → 微服务A处理请求 → 通过WebClient调用微服务B的接口触发生成 → 微服务B先从微服务A获取数据,再执行OptaPlanner求解
微服务B关键代码
启动/恢复求解接口
@PostMapping("startSolver") public ResponseEntity<?> startSolver(@PathVariable String organizationId) { try { SolverConfig solverConfig = SolverConfig.createFromXmlResource("solver/timeTableSolverConfig.xml"); SolverFactory<TimeTable> solverFactory = new DefaultSolverFactory<>(solverConfig); this.solverManager = SolverManager.create(solverFactory); this.solverManager.solveAndListen(TimeTableService.SINGLETON_TIME_TABLE_ID, id -> timeTableService.findById(id, UUID.fromString(organizationId)), timeTable -> timeTableService.updateModifiedLessons(timeTable, organizationId)); return new ResponseEntity<>("Solving has successfully started", HttpStatus.OK); } catch(OptaPlannerException exception) { System.out.println("OptaPlanner exception - " + exception.getMessage()); return utils.generateResponse(exception.getMessage(), HttpStatus.CONFLICT); } }
从微服务A获取求解数据方法
public TimeTable findById(Long id, UUID organizationId) { SolverDataDTO solverDataDTO = webClient.get() .uri("http://localhost:8080/smart-planner/org/{organizationId}/optaplanner-solver/getSolverData", organizationId) .retrieve() .onStatus(HttpStatus::isError, error -> { LOGGER.error(extractExceptionMessage("findById.fetchFails", "findById()")); return Mono.error(new OptaPlannerException( extractExceptionMessage("findById.fetchFails", ""))); }) .bodyToMono(SolverDataDTO.class) .block(); TimeTable timeTable = new TimeTable(); // 将solverDataDTO中的数据填充到TimeTable的所有列表中 ... return timeTable; }
保存求解结果到微服务A方法
public void updateModifiedLessons(TimeTable timeTable, String organizationId) { List<ScheduleSlot> slots = new ArrayList<>(timeTable.getScheduleSlotList()); List<SolverScheduleSlotDTO> solverScheduleSlotDTOs = scheduleSlotConverter.convertModelsToSolverDTOs(slots); String executionMessage = webClient.post() .uri("http://localhost:8080/smart-planner/org/{organizationId}/optaplanner-solver/saveTimeTable", organizationId) .header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE) .body(Mono.just(solverScheduleSlotDTOs), SolverScheduleSlotDTO.class) .retrieve() .onStatus(HttpStatus::isError, error -> { LOGGER.error(extractExceptionMessage("saveSlots.savingFails", "updateModifiedLessons()")); return Mono.error(new OptaPlannerException( extractExceptionMessage("saveSlots.savingFails", ""))); }) .bodyToMono(String.class) .block(); }
内容的提问来源于stack exchange,提问作者kitty
相关产品推荐
相关产品推荐

