基于TimeFold.ai的车间调度改造问题及JSON数据接入咨询
问题1:同一15分钟时间槽多订单分配的修复方案
核心原因
原学校排课示例的约束仅针对操作员(原教师)和物料(原科目组)的冲突,未添加机器资源的排他性约束——即同一机器在同一时间槽内只能处理一个订单时段。
修复步骤
确保订单实体关联机器
检查Orders类是否包含Machine类型字段(对应原排课的Room),若没有则添加并生成对应getter/setter:private Machine machine; public Machine getMachine() { return machine; } public void setMachine(Machine machine) { this.machine = machine; }添加机器时间槽排他硬约束
在ConstraintProvider类中新增硬约束,禁止同一机器在同一时间槽分配多个订单时段:@Override public Constraint[] defineConstraints(ConstraintFactory constraintFactory) { return new Constraint[] { // 保留原有约束 ... // 新增机器-时间槽排他约束 machineTimeSlotConflict(constraintFactory) }; } private Constraint machineTimeSlotConflict(ConstraintFactory constraintFactory) { // 匹配同一机器、同一时间槽的两个不同订单 return constraintFactory.from(Orders.class) .join(Orders.class, Joiners.equal(Orders::getMachine), Joiners.equal(Orders::getTimeSlot), Joiners.lessThan(Orders::getId)) // 避免重复匹配 .penalize("Machine time slot conflict", HardSoftScore.ONE_HARD); }该硬约束会直接阻止违反规则的分配方案。
问题2:用JSON文件传递订单数据替代DemoResource类
实现步骤
创建数据DTO类
编写与实体类(Orders、Machine、Operator、TimeSlot)对应的DTO,例如OrderDto:public class OrderDto { private Long id; private Long operatorId; private Long materialId; private Long timeSlotId; private Long machineId; // 其他字段及getter/setter }同理创建
MachineDto、OperatorDto、TimeSlotDto,以及包含所有DTO列表的顶层类ProductionDataDto。编写JSON数据文件
在项目src/main/resources下创建production-data.json,示例结构:{ "orders": [ {"id": 1, "operatorId": 1, "materialId": 1, "timeSlotId": null, "machineId": null} ], "machines": [ {"id": 1, "name": "Machine-1"} ], "operators": [ {"id": 1, "name": "Operator-1"} ], "timeSlots": [ {"id": 1, "startTime": "2024-05-20T08:00:00", "durationMinutes": 15} ] }编写数据加载工具类
使用Jackson库读取JSON文件,将DTO转换为实体类并构建PlanningSolution实例:@Component public class ProductionDataLoader { private final ObjectMapper objectMapper = new ObjectMapper(); public ProductionSolution loadData() throws IOException { File jsonFile = new File(Objects.requireNonNull(getClass().getResource("/production-data.json")).getFile()); ProductionDataDto dataDto = objectMapper.readValue(jsonFile, ProductionDataDto.class); // 将DTO转换为实体 List<Machine> machines = dataDto.getMachines().stream() .map(dto -> new Machine(dto.getId(), dto.getName())) .collect(Collectors.toList()); List<Operator> operators = dataDto.getOperators().stream() .map(dto -> new Operator(dto.getId(), dto.getName())) .collect(Collectors.toList()); List<TimeSlot> timeSlots = dataDto.getTimeSlots().stream() .map(dto -> new TimeSlot(dto.getId(), dto.getStartTime(), dto.getDurationMinutes())) .collect(Collectors.toList()); List<Orders> orders = dataDto.getOrders().stream() .map(dto -> { Orders order = new Orders(dto.getId()); order.setOperator(findById(operators, dto.getOperatorId())); order.setMaterial(findById(materials, dto.getMaterialId())); // 初始时timeSlot和machine为null,由TimeFold分配 return order; }) .collect(Collectors.toList()); // 构建PlanningSolution ProductionSolution solution = new ProductionSolution(); solution.setId(1L); solution.setMachines(machines); solution.setOperators(operators); solution.setTimeSlots(timeSlots); solution.setOrders(orders); return solution; } private <T extends Identifiable<Long>> T findById(List<T> list, Long id) { return list.stream().filter(item -> item.getId().equals(id)).findFirst().orElseThrow(); } }替换DemoResource的数据源
修改原DemoResource类,注入ProductionDataLoader并调用加载方法,替代硬编码的示例数据:@RestController @RequestMapping("/production") public class ProductionResource { private final ProductionDataLoader dataLoader; private final SolverManager<ProductionSolution, Long> solverManager; public ProductionResource(ProductionDataLoader dataLoader, SolverManager<ProductionSolution, Long> solverManager) { this.dataLoader = dataLoader; this.solverManager = solverManager; } @PostMapping("/solve") public ResponseEntity<ProductionSolution> solve() throws IOException { ProductionSolution problem = dataLoader.loadData(); SolverJob<ProductionSolution, Long> job = solverManager.solve(1L, problem); try { ProductionSolution solution = job.getFinalBestSolution(); return ResponseEntity.ok(solution); } catch (InterruptedException | ExecutionException e) { return ResponseEntity.internalServerError().build(); } } }
内容的提问来源于stack exchange,提问作者EdoZp12
相关产品推荐
相关产品推荐

