You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于TimeFold.ai的车间调度改造问题及JSON数据接入咨询

问题1:同一15分钟时间槽多订单分配的修复方案

核心原因

原学校排课示例的约束仅针对操作员(原教师)和物料(原科目组)的冲突,未添加机器资源的排他性约束——即同一机器在同一时间槽内只能处理一个订单时段。

修复步骤

  1. 确保订单实体关联机器
    检查Orders类是否包含Machine类型字段(对应原排课的Room),若没有则添加并生成对应getter/setter:

    private Machine machine;
    
    public Machine getMachine() {
        return machine;
    }
    
    public void setMachine(Machine machine) {
        this.machine = machine;
    }
    
  2. 添加机器时间槽排他硬约束
    在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类

实现步骤

  1. 创建数据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。

  2. 编写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}
      ]
    }
    
  3. 编写数据加载工具类
    使用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();
        }
    }
    
  4. 替换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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 12:56:21