Commit 01953779 authored by Tong Li's avatar Tong Li

遗传算法

parent f45d7214
...@@ -114,6 +114,16 @@ public class ResourceGanttController { ...@@ -114,6 +114,16 @@ public class ResourceGanttController {
return scheduleChromosomes; return scheduleChromosomes;
} }
@GetMapping("/getScene2")
@Operation(summary = "获取所有场景ID", description = "获取所有场景ID")
public List<Chromosome> getScene2() {
// 调用 PlanResultService 获取 ScheduleChromosome 列表
List<Chromosome> scheduleChromosomes = planResultService.execute2("EAA26D85B5824B40A17554297B4EA32B");
// 提取所有场景ID
return scheduleChromosomes;
}
/** /**
* 将 ScheduleChromosome 转换为 ResourceGanttVO 列表 * 将 ScheduleChromosome 转换为 ResourceGanttVO 列表
* @param scheduleChromosome 调度结果 * @param scheduleChromosome 调度结果
...@@ -181,7 +191,7 @@ public class ResourceGanttController { ...@@ -181,7 +191,7 @@ public class ResourceGanttController {
taskVO.setHeaderName("工艺"+gene.getProductId()); // 默认值 taskVO.setHeaderName("工艺"+gene.getProductId()); // 默认值
taskVO.setSeq(gene.getSequenceId()); // 使用工序ID taskVO.setSeq(gene.getSequenceId()); // 使用工序ID
taskVO.setSeqName( "工序名称"+gene.getSequenceId()); taskVO.setSeqName( "工序名称"+gene.getSequenceId());
taskVO.setProcessingTime(gene.getProcessingTime()*60); taskVO.setProcessingTime((int)gene.getProcessingTime()*60);
taskVO.setAbsoluteStart(scheduleChromosome.getBaseTime().plusMinutes(gene.getStartTime())); taskVO.setAbsoluteStart(scheduleChromosome.getBaseTime().plusMinutes(gene.getStartTime()));
taskVO.setAbsoluteEnd(scheduleChromosome.getBaseTime().plusMinutes(gene.getEndTime())); taskVO.setAbsoluteEnd(scheduleChromosome.getBaseTime().plusMinutes(gene.getEndTime()));
taskVOList.add(taskVO); taskVOList.add(taskVO);
......
...@@ -2,6 +2,7 @@ package com.aps.entity.Algorithm; ...@@ -2,6 +2,7 @@ package com.aps.entity.Algorithm;
import lombok.Data; import lombok.Data;
import java.math.BigDecimal;
import java.util.List; import java.util.List;
/** /**
...@@ -13,13 +14,13 @@ public class GAScheduleResult { ...@@ -13,13 +14,13 @@ public class GAScheduleResult {
private int GroupId; private int GroupId;
private int ProductId; private int ProductId;
private int OperationId; private int OperationId;
private int MachineId; private long MachineId;
private int StartTime; // 相对开始时间(分钟) private int StartTime; // 相对开始时间(分钟)
private int EndTime; // 相对结束时间(分钟) private int EndTime; // 相对结束时间(分钟)
private int Quantity; // 批次大小(订单可拆分) private double Quantity; // 批次大小(订单可拆分)
private List<ScheduleResultDetail> GeneDetails; // 时间详情 private List<ScheduleResultDetail> GeneDetails; // 时间详情
private int OneTime; // 单件工时 private double OneTime; // 单件工时
private int ProcessingTime; // 绝对处理时间(分钟) private double ProcessingTime; // 绝对处理时间(分钟)
private int ChangeoverTime; private int ChangeoverTime;
public int getFlowTime() { public int getFlowTime() {
......
...@@ -2,6 +2,8 @@ package com.aps.entity.Algorithm; ...@@ -2,6 +2,8 @@ package com.aps.entity.Algorithm;
import lombok.Data; import lombok.Data;
import java.math.BigDecimal;
/** /**
* 作者:佟礼 * 作者:佟礼
* 时间:2025-11-25 * 时间:2025-11-25
...@@ -21,9 +23,9 @@ public class OpMachine { ...@@ -21,9 +23,9 @@ public class OpMachine {
/** /**
* 设备ID * 设备ID
*/ */
private int machineId; private Long machineId;
/** /**
* 单件工时 * 单件工时
*/ */
private int processingTime; // 加工时间 private double processingTime; // 加工时间
} }
...@@ -42,7 +42,7 @@ public class ProductGanttVO { ...@@ -42,7 +42,7 @@ public class ProductGanttVO {
private LocalDateTime endDate; private LocalDateTime endDate;
@Schema(description = "车间ID") @Schema(description = "车间ID")
private Integer shopId; private Long shopId;
@Schema(description = "车间名称") @Schema(description = "车间名称")
private String shopName; private String shopName;
......
...@@ -15,7 +15,7 @@ import java.util.List; ...@@ -15,7 +15,7 @@ import java.util.List;
public class ResourceGanttVO { public class ResourceGanttVO {
@Schema(description = "设备ID") @Schema(description = "设备ID")
private Integer id; private long id;
@Schema(description = "设备名称") @Schema(description = "设备名称")
private String name; private String name;
...@@ -30,7 +30,7 @@ public class ResourceGanttVO { ...@@ -30,7 +30,7 @@ public class ResourceGanttVO {
private Integer split; private Integer split;
@Schema(description = "部门ID") @Schema(description = "部门ID")
private Integer departmentId; private long departmentId;
@Schema(description = "部门名称") @Schema(description = "部门名称")
private String departmentName; private String departmentName;
...@@ -39,7 +39,7 @@ public class ResourceGanttVO { ...@@ -39,7 +39,7 @@ public class ResourceGanttVO {
private String shopName; private String shopName;
@Schema(description = "车间ID") @Schema(description = "车间ID")
private Integer shopId; private long shopId;
@Schema(description = "设备编码") @Schema(description = "设备编码")
private String code; private String code;
......
...@@ -74,10 +74,10 @@ public class TaskVO { ...@@ -74,10 +74,10 @@ public class TaskVO {
private Integer duration; private Integer duration;
@Schema(description = "设备ID") @Schema(description = "设备ID")
private Integer equipId; private long equipId;
@Schema(description = "车间ID") @Schema(description = "车间ID")
private Integer shopId; private long shopId;
@Schema(description = "车间名称") @Schema(description = "车间名称")
private String shopName; private String shopName;
......
...@@ -10,7 +10,7 @@ import java.time.LocalDateTime; ...@@ -10,7 +10,7 @@ import java.time.LocalDateTime;
public class GenVO { public class GenVO {
private String orderId; // 工单ID private String orderId; // 工单ID
private Integer operationId; // 工序ID private Integer operationId; // 工序ID
private Integer equipId; // 设备ID private Long equipId; // 设备ID
@JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss") @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime startTime; // 实际开始时间 private LocalDateTime startTime; // 实际开始时间
@JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss") @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
......
...@@ -8,7 +8,7 @@ import java.util.List; ...@@ -8,7 +8,7 @@ import java.util.List;
@Data @Data
public class MachineVO { public class MachineVO {
@Schema(description = "设备内部ID") @Schema(description = "设备内部ID")
private Integer id; private long id;
@Schema(description = "设备编码") @Schema(description = "设备编码")
private String equipId; private String equipId;
......
...@@ -23,10 +23,16 @@ public class Entry { ...@@ -23,10 +23,16 @@ public class Entry {
* 所属组ID 需要按照前后顺序生产的工单给一组 * 所属组ID 需要按照前后顺序生产的工单给一组
*/ */
public int GroupId ; public int GroupId ;
/** /**
* 基因编号 * 所属组ID 需要按照前后顺序生产的工单给一组
*/
public String OrderId ;
/**
* 工单ID
*/ */
public int OperationID ; public String ExecId ;
/** /**
* 离散参数 * 离散参数
*/ */
...@@ -38,7 +44,7 @@ public class Entry { ...@@ -38,7 +44,7 @@ public class Entry {
/** /**
* 基因编号 * 基因编号
*/ */
public int Quantity; public Double Quantity;
/** /**
* 工序顺序 * 工序顺序
*/ */
......
...@@ -13,12 +13,12 @@ public class Gene { ...@@ -13,12 +13,12 @@ public class Gene {
private int productId; private int productId;
private int operationId; private int operationId;
private String operationName; // 添加工序名称 private String operationName; // 添加工序名称
private int machineId; private Long machineId;
private int startTime; // 相对开始时间(分钟) private int startTime; // 相对开始时间(分钟)
private int endTime; // 相对结束时间(分钟) private int endTime; // 相对结束时间(分钟)
private int batchSize; // 批次大小(订单可拆分) private int batchSize; // 批次大小(订单可拆分)
private List<GeneDetail> geneDetails; // 时间详情 private List<GeneDetail> geneDetails; // 时间详情
private int processingTime; // 绝对处理时间(分钟) private double processingTime; // 绝对处理时间(分钟)
private int Id; private int Id;
private int sequenceId; private int sequenceId;
private int setupTime; // 换型时 private int setupTime; // 换型时
......
...@@ -9,14 +9,16 @@ import java.util.function.Consumer; ...@@ -9,14 +9,16 @@ import java.util.function.Consumer;
@Data @Data
public class Machine { public class Machine {
private int id; private long id;
private String name; private String name;
private int earliestTime=0; private int earliestTime=0;
private int totalTaskTime=0; private double totalTaskTime=0;
private List<Shift> shifts; private List<Shift> shifts;
private List<MaintenanceWindow> maintenanceWindows; private List<MaintenanceWindow> maintenanceWindows;
private List<TimeSegment> availability; private List<TimeSegment> availability;
private List<Holiday> holidays;
// 事件回调 // 事件回调
private Consumer<Void> shiftsChanged; private Consumer<Void> shiftsChanged;
private Consumer<Void> maintenanceWindowsChanged; private Consumer<Void> maintenanceWindowsChanged;
......
...@@ -2,13 +2,15 @@ package com.aps.entity.basic; ...@@ -2,13 +2,15 @@ package com.aps.entity.basic;
import lombok.Data; import lombok.Data;
import java.math.BigDecimal;
/** /**
* 设备选项 * 设备选项
*/ */
@Data @Data
public class MachineOption { public class MachineOption {
private int machineId; private Long machineId;
private int processingTime; // 加工时间 (秒) private double processingTime; // 加工时间 (秒)
private int setupTime; // 换型时间(如果与前一个产品不同) private int setupTime; // 换型时间(如果与前一个产品不同)
private int teardownTime; // 收尾时间(后处理时间) private int teardownTime; // 收尾时间(后处理时间)
private int contantTime; // 常数时间 private int contantTime; // 常数时间
......
...@@ -6,7 +6,7 @@ import java.util.List; ...@@ -6,7 +6,7 @@ import java.util.List;
import java.util.Objects; import java.util.Objects;
public class MachineTimeline { public class MachineTimeline {
private int machineId; private Long machineId;
private List<TimeSegment> segments; private List<TimeSegment> segments;
private LocalDateTime validFrom; private LocalDateTime validFrom;
private LocalDateTime validTo; private LocalDateTime validTo;
...@@ -18,11 +18,11 @@ public class MachineTimeline { ...@@ -18,11 +18,11 @@ public class MachineTimeline {
} }
// Getters and Setters // Getters and Setters
public int getMachineId() { public Long getMachineId() {
return machineId; return machineId;
} }
public void setMachineId(int machineId) { public void setMachineId(Long machineId) {
this.machineId = machineId; this.machineId = machineId;
} }
......
...@@ -12,8 +12,8 @@ import java.time.OffsetDateTime; ...@@ -12,8 +12,8 @@ import java.time.OffsetDateTime;
public class Order { public class Order {
private int id; private int id;
private int productId; private int productId;
private int quantity = 100; // 100个 private double quantity = 100; // 100个
private int sYQuantity; private double sYQuantity;
private OffsetDateTime dueDate; private OffsetDateTime dueDate;
private LocalDateTime orderCompletion; private LocalDateTime orderCompletion;
......
...@@ -13,13 +13,15 @@ public class Shift { ...@@ -13,13 +13,15 @@ public class Shift {
private LocalTime endTime; private LocalTime endTime;
private Set<Integer> days; // 改为Integer类型,便于JSON反序列化 private Set<Integer> days; // 改为Integer类型,便于JSON反序列化
private LocalDateTime shiftDate; private LocalDateTime shiftDate;
private LocalDateTime startDate;
private LocalDateTime endDate;
private boolean isTemporaryShift; private boolean isTemporaryShift;
private int priority; private int priority;
private Integer status;//0:正常班次 1:临时班次 2:维修 private Integer status;//0:正常班次 1:临时班次 2:维修
// 添加设备ID和名称字段 // 添加设备ID和名称字段
private Integer machineId; private Long machineId;
private String machineName; private String machineName;
public Shift() {} public Shift() {}
...@@ -83,11 +85,11 @@ public class Shift { ...@@ -83,11 +85,11 @@ public class Shift {
this.status = status; this.status = status;
} }
public Integer getMachineId() { public Long getMachineId() {
return machineId; return machineId;
} }
public void setMachineId(Integer machineId) { public void setMachineId(Long machineId) {
this.machineId = machineId; this.machineId = machineId;
} }
......
...@@ -11,7 +11,7 @@ public class ShiftVO { ...@@ -11,7 +11,7 @@ public class ShiftVO {
private int id; private long id;
private String name; private String name;
private List<Shift> shifts; private List<Shift> shifts;
private List<MaintenanceWindow> maintenanceWindows; private List<MaintenanceWindow> maintenanceWindows;
......
...@@ -5,6 +5,7 @@ import com.aps.entity.Algorithm.*; ...@@ -5,6 +5,7 @@ import com.aps.entity.Algorithm.*;
import com.aps.entity.basic.*; import com.aps.entity.basic.*;
import com.aps.service.plan.MachineSchedulerService; import com.aps.service.plan.MachineSchedulerService;
import java.math.BigDecimal;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit; import java.time.temporal.ChronoUnit;
import java.util.*; import java.util.*;
...@@ -141,7 +142,7 @@ public class GeneticDecoder { ...@@ -141,7 +142,7 @@ public class GeneticDecoder {
.keySet().stream() .keySet().stream()
.collect(Collectors.toMap(k -> k, k -> 0)); .collect(Collectors.toMap(k -> k, k -> 0));
Map<Integer, String> machineState = chromosome.getMachines().stream() Map<Long, String> machineState = chromosome.getMachines().stream()
.collect(Collectors.toMap(Machine::getId, m -> "")); .collect(Collectors.toMap(Machine::getId, m -> ""));
List<Entry> allScheduledOps = new ArrayList<>(); List<Entry> allScheduledOps = new ArrayList<>();
...@@ -166,8 +167,8 @@ public class GeneticDecoder { ...@@ -166,8 +167,8 @@ public class GeneticDecoder {
.filter(m -> m.getGroupId() == groupId&&m.getSequence()==opSequence) .filter(m -> m.getGroupId() == groupId&&m.getSequence()==opSequence)
.findFirst() .findFirst()
.orElse(null); .orElse(null);
int machineId = machineInfo.getMachineId(); Long machineId = machineInfo.getMachineId();
int processTime = machineInfo.getProcessingTime(); double processTime = machineInfo.getProcessingTime();
Machine targetMachine = chromosome.getMachines().stream() Machine targetMachine = chromosome.getMachines().stream()
.filter(m -> m.getId() == machineId) .filter(m -> m.getId() == machineId)
.findFirst() .findFirst()
...@@ -215,10 +216,10 @@ public class GeneticDecoder { ...@@ -215,10 +216,10 @@ public class GeneticDecoder {
private int processWithSingleMachine(Entry operation, Machine machine, int processingTime, private int processWithSingleMachine(Entry operation, Machine machine, double processingTime,
int prevtime, Chromosome chromosome) { int prevtime, Chromosome chromosome) {
int processingTimeTotal = processingTime * operation.getQuantity();
int processingTimeTotal =(int)(processingTime * operation.getQuantity());
MachineCalculator machineCalculator=new MachineCalculator(baseTime,machines,machineScheduler); MachineCalculator machineCalculator=new MachineCalculator(baseTime,machines,machineScheduler);
List<ScheduleResultDetail> geneDetails = machineCalculator.getNextAvailableTime(machine, prevtime, -1, List<ScheduleResultDetail> geneDetails = machineCalculator.getNextAvailableTime(machine, prevtime, -1,
processingTimeTotal, chromosome.getResult(), false, true, true); processingTimeTotal, chromosome.getResult(), false, true, true);
...@@ -326,7 +327,7 @@ public class GeneticDecoder { ...@@ -326,7 +327,7 @@ public class GeneticDecoder {
// 计算机器负载均衡指标 // 计算机器负载均衡指标
private double calculateMachineLoadBalance(Chromosome chromosome) { private double calculateMachineLoadBalance(Chromosome chromosome) {
Map<Integer, Double> machineUtilization = new HashMap<>(); Map<Long, Double> machineUtilization = new HashMap<>();
int maxEndTime = chromosome.getResult().stream() int maxEndTime = chromosome.getResult().stream()
.mapToInt(GAScheduleResult::getEndTime) .mapToInt(GAScheduleResult::getEndTime)
.max() .max()
......
...@@ -168,7 +168,7 @@ public class GeneticOperations { ...@@ -168,7 +168,7 @@ public class GeneticOperations {
// 筛选其他机器并找到加工时间最短的 // 筛选其他机器并找到加工时间最短的
MachineOption minLoadMachine = optionalMachines.stream() MachineOption minLoadMachine = optionalMachines.stream()
.filter(m -> m.getMachineId() != currentMachine.getMachineId()) .filter(m -> m.getMachineId() != currentMachine.getMachineId())
.min(Comparator.comparingInt(m -> m.getProcessingTime())) .min(Comparator.comparingDouble(m -> m.getProcessingTime()))
.orElse(currentMachine); // 如果没有其他机器,保持当前 .orElse(currentMachine); // 如果没有其他机器,保持当前
machineSeq = optionalMachines.indexOf(minLoadMachine) + 1; machineSeq = optionalMachines.indexOf(minLoadMachine) + 1;
......
...@@ -79,12 +79,12 @@ int populationSize=param.getPopulationSize(); ...@@ -79,12 +79,12 @@ int populationSize=param.getPopulationSize();
private Chromosome generateGSChromosome(Chromosome chromosome,List<GlobalOperationInfo> globalOpList) { private Chromosome generateGSChromosome(Chromosome chromosome,List<GlobalOperationInfo> globalOpList) {
Map<Integer, Integer> machineLoad = new HashMap<>(); Map<Long, Double> machineLoad = new HashMap<>();
// int[] machineLoad = new int[machineCount + 1]; // 设备负载(1-based,设备ID从1开始) // int[] machineLoad = new int[machineCount + 1]; // 设备负载(1-based,设备ID从1开始)
List<Integer> ms = new ArrayList<>(); // MachineSelection(顺序=GlobalOpId顺序) List<Integer> ms = new ArrayList<>(); // MachineSelection(顺序=GlobalOpId顺序)
List<Integer> os = new ArrayList<>(); // OperationSequencing List<Integer> os = new ArrayList<>(); // OperationSequencing
List<Integer> osp = new ArrayList<>(); // 相同优先级OperationSequencing List<Integer> osp = new ArrayList<>(); // 相同优先级OperationSequencing
int prevPriority = -1; double prevPriority =(double) -1;
Random rnd = new Random(); Random rnd = new Random();
// 步骤1:按GlobalOpId顺序为每道工序选择机器 // 步骤1:按GlobalOpId顺序为每道工序选择机器
...@@ -106,7 +106,7 @@ int populationSize=param.getPopulationSize(); ...@@ -106,7 +106,7 @@ int populationSize=param.getPopulationSize();
List<MachineOption> optionalMachines = op.getMachineOptions(); List<MachineOption> optionalMachines = op.getMachineOptions();
MachineOption minLoadMachine = optionalMachines.stream() MachineOption minLoadMachine = optionalMachines.stream()
.min(Comparator.comparingInt(m ->machineLoad.getOrDefault(m.getMachineId(), 0) + m.getProcessingTime())) .min(Comparator.comparingDouble(m ->machineLoad.getOrDefault(m.getMachineId(), (double)0) + m.getProcessingTime()))
.orElseThrow(() -> new NoSuchElementException("MachineOption not found for machine: " )); .orElseThrow(() -> new NoSuchElementException("MachineOption not found for machine: " ));
...@@ -120,7 +120,7 @@ int populationSize=param.getPopulationSize(); ...@@ -120,7 +120,7 @@ int populationSize=param.getPopulationSize();
// 更新设备负载 // 更新设备负载
machineLoad.put(minLoadMachine.getMachineId(), machineLoad.put(minLoadMachine.getMachineId(),
machineLoad.getOrDefault(minLoadMachine.getMachineId(), 0) + minLoadMachine.getProcessingTime()); machineLoad.getOrDefault(minLoadMachine.getMachineId(), (double)0) + minLoadMachine.getProcessingTime());
osp.add(groupId); osp.add(groupId);
} }
...@@ -148,7 +148,7 @@ int populationSize=param.getPopulationSize(); ...@@ -148,7 +148,7 @@ int populationSize=param.getPopulationSize();
List<Integer> os = new ArrayList<>(); List<Integer> os = new ArrayList<>();
Random rnd = new Random(); Random rnd = new Random();
int currentOrderId = -1; int currentOrderId = -1;
Map<Integer, Integer> machineLoad = new HashMap<>(); Map<Long, Double> machineLoad = new HashMap<>();
List<Integer> osp = new ArrayList<>(); List<Integer> osp = new ArrayList<>();
int prevPriority = -1; int prevPriority = -1;
...@@ -176,7 +176,7 @@ int populationSize=param.getPopulationSize(); ...@@ -176,7 +176,7 @@ int populationSize=param.getPopulationSize();
MachineOption minLoadMachine = optionalMachines.stream() MachineOption minLoadMachine = optionalMachines.stream()
.min(Comparator.comparingInt(m -> machineLoad.getOrDefault(m.getMachineId(), 0) + m.getProcessingTime())) .min(Comparator.comparingDouble(m -> machineLoad.getOrDefault(m.getMachineId(), (double)0) + m.getProcessingTime()))
.orElseThrow(() -> new NoSuchElementException("MachineOption not found for machine: " )); .orElseThrow(() -> new NoSuchElementException("MachineOption not found for machine: " ));
...@@ -188,9 +188,10 @@ int populationSize=param.getPopulationSize(); ...@@ -188,9 +188,10 @@ int populationSize=param.getPopulationSize();
int machineSeq = index.orElse(0) + 1; int machineSeq = index.orElse(0) + 1;
ms.add(machineSeq); ms.add(machineSeq);
double maLoad= machineLoad.getOrDefault(minLoadMachine.getMachineId(),(double)0);
// 更新设备负载 // 更新设备负载
machineLoad.put(minLoadMachine.getMachineId(), machineLoad.put(minLoadMachine.getMachineId(),
machineLoad.getOrDefault(minLoadMachine.getMachineId(), 0) + minLoadMachine.getProcessingTime()); maLoad+ minLoadMachine.getProcessingTime());
osp.add(groupId); osp.add(groupId);
} }
......
...@@ -7,6 +7,7 @@ import com.aps.entity.basic.*; ...@@ -7,6 +7,7 @@ import com.aps.entity.basic.*;
import com.aps.service.plan.MachineSchedulerService; import com.aps.service.plan.MachineSchedulerService;
import com.baomidou.mybatisplus.core.toolkit.StringUtils; import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import java.math.BigDecimal;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter; import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit; import java.time.temporal.ChronoUnit;
......
...@@ -74,7 +74,7 @@ public class AlgorithmScheduler6 { ...@@ -74,7 +74,7 @@ public class AlgorithmScheduler6 {
.orElseThrow(() -> new NoSuchElementException("Product not found: " + order.getProductId())); .orElseThrow(() -> new NoSuchElementException("Product not found: " + order.getProductId()));
int prevtime = 0; int prevtime = 0;
int remainingQuantity = order.getQuantity(); int remainingQuantity =(int) order.getQuantity();
// 订单拆分逻辑 - 增强随机性 // 订单拆分逻辑 - 增强随机性
while (remainingQuantity > 0) { while (remainingQuantity > 0) {
...@@ -109,7 +109,7 @@ public class AlgorithmScheduler6 { ...@@ -109,7 +109,7 @@ public class AlgorithmScheduler6 {
// 多设备选择逻辑 - 增强随机性 // 多设备选择逻辑 - 增强随机性
if (operation.getMachineOptions().size() > 1) { if (operation.getMachineOptions().size() > 1) {
Set<Integer> machineIds = operation.getMachineOptions().stream() Set<Long> machineIds = operation.getMachineOptions().stream()
.map(MachineOption::getMachineId) .map(MachineOption::getMachineId)
.collect(Collectors.toSet()); .collect(Collectors.toSet());
...@@ -133,7 +133,7 @@ public class AlgorithmScheduler6 { ...@@ -133,7 +133,7 @@ public class AlgorithmScheduler6 {
machine = chromosome.getMachines().stream() machine = chromosome.getMachines().stream()
.filter(t -> machineIds.contains(t.getId())) .filter(t -> machineIds.contains(t.getId()))
.sorted(Comparator.comparingInt(Machine::getEarliestTime) .sorted(Comparator.comparingInt(Machine::getEarliestTime)
.thenComparingInt(Machine::getTotalTaskTime) .thenComparingDouble(Machine::getTotalTaskTime)
.thenComparing(t -> _random.nextDouble())) .thenComparing(t -> _random.nextDouble()))
.findFirst() .findFirst()
.orElseThrow(() -> new NoSuchElementException("No available machine for operation: " + operation.getId())); .orElseThrow(() -> new NoSuchElementException("No available machine for operation: " + operation.getId()));
...@@ -153,7 +153,7 @@ public class AlgorithmScheduler6 { ...@@ -153,7 +153,7 @@ public class AlgorithmScheduler6 {
.orElseThrow(() -> new NoSuchElementException("Machine not found: " + finalMachineOption.getMachineId())); .orElseThrow(() -> new NoSuchElementException("Machine not found: " + finalMachineOption.getMachineId()));
} }
int processingTime = machineOption.getProcessingTime() * batchSize; double processingTime = machineOption.getProcessingTime() * batchSize;
int preTime = machineOption.getPreTime(); // 前处理时间(常数时间,与批次大小无关) int preTime = machineOption.getPreTime(); // 前处理时间(常数时间,与批次大小无关)
int setupTime = 0; // 换型时间默认为0,仅在产品变化时计算 int setupTime = 0; // 换型时间默认为0,仅在产品变化时计算
int teardownTime = machineOption.getTeardownTime(); // 后处理时间(常数时间,与批次大小无关) int teardownTime = machineOption.getTeardownTime(); // 后处理时间(常数时间,与批次大小无关)
...@@ -391,10 +391,10 @@ public class AlgorithmScheduler6 { ...@@ -391,10 +391,10 @@ public class AlgorithmScheduler6 {
// ========================== CalculateTotalSetupTime(参数与C#一致) ========================== // ========================== CalculateTotalSetupTime(参数与C#一致) ==========================
private double CalculateTotalSetupTime(ScheduleChromosome chromosome) { private double CalculateTotalSetupTime(ScheduleChromosome chromosome) {
double totalSetupTime = 0.0; double totalSetupTime = 0.0;
Map<Integer, List<Gene>> machineGroups = chromosome.getGenes().stream() Map<Long, List<Gene>> machineGroups = chromosome.getGenes().stream()
.collect(Collectors.groupingBy(Gene::getMachineId)); .collect(Collectors.groupingBy(Gene::getMachineId));
for (Map.Entry<Integer, List<Gene>> machineGroup : machineGroups.entrySet()) { for (Map.Entry<Long, List<Gene>> machineGroup : machineGroups.entrySet()) {
List<Gene> sortedGenes = machineGroup.getValue().stream() List<Gene> sortedGenes = machineGroup.getValue().stream()
.sorted(Comparator.comparingInt(Gene::getStartTime)) .sorted(Comparator.comparingInt(Gene::getStartTime))
.collect(Collectors.toList()); .collect(Collectors.toList());
...@@ -433,7 +433,7 @@ public class AlgorithmScheduler6 { ...@@ -433,7 +433,7 @@ public class AlgorithmScheduler6 {
// ========================== CalculateMachineLoadBalance(参数与C#一致) ========================== // ========================== CalculateMachineLoadBalance(参数与C#一致) ==========================
private double CalculateMachineLoadBalance(ScheduleChromosome chromosome) { private double CalculateMachineLoadBalance(ScheduleChromosome chromosome) {
Map<Integer, Double> machineUtilization = new HashMap<>(); Map<Long, Double> machineUtilization = new HashMap<>();
int maxEndTime = chromosome.getGenes().stream() int maxEndTime = chromosome.getGenes().stream()
.mapToInt(Gene::getEndTime) .mapToInt(Gene::getEndTime)
.max() .max()
...@@ -566,7 +566,7 @@ public class AlgorithmScheduler6 { ...@@ -566,7 +566,7 @@ public class AlgorithmScheduler6 {
// ========================== GetNextAvailableTime(参数与C#一致) ========================== // ========================== GetNextAvailableTime(参数与C#一致) ==========================
private List<GeneDetail> GetNextAvailableTime( private List<GeneDetail> GetNextAvailableTime(
Machine machine, int proposedStartTime, int prevtime, Machine machine, int proposedStartTime, int prevtime,
int processingTime, List<Gene> existingTasks, double processingTime, List<Gene> existingTasks,
boolean IsInterrupt, boolean istask boolean IsInterrupt, boolean istask
) { ) {
LocalDateTime startTime = baseTime.plusMinutes(proposedStartTime); LocalDateTime startTime = baseTime.plusMinutes(proposedStartTime);
...@@ -579,7 +579,7 @@ public class AlgorithmScheduler6 { ...@@ -579,7 +579,7 @@ public class AlgorithmScheduler6 {
// ========================== FindEarliestStart(参数与C#一致) ========================== // ========================== FindEarliestStart(参数与C#一致) ==========================
private List<GeneDetail> FindEarliestStart( private List<GeneDetail> FindEarliestStart(
Machine machine, int processingTime, LocalDateTime currentTime, Machine machine, double processingTime, LocalDateTime currentTime,
String prevtime, List<Gene> existingTasks, boolean checkprevtime String prevtime, List<Gene> existingTasks, boolean checkprevtime
) { ) {
// 获取设备已有任务 // 获取设备已有任务
...@@ -599,7 +599,7 @@ public class AlgorithmScheduler6 { ...@@ -599,7 +599,7 @@ public class AlgorithmScheduler6 {
LocalDateTime startCandidate = slot.getStart().isAfter(prevTimeDateTime != null ? prevTimeDateTime : currentTime) LocalDateTime startCandidate = slot.getStart().isAfter(prevTimeDateTime != null ? prevTimeDateTime : currentTime)
? slot.getStart() ? slot.getStart()
: (prevTimeDateTime != null ? prevTimeDateTime : currentTime); : (prevTimeDateTime != null ? prevTimeDateTime : currentTime);
LocalDateTime endCandidate = startCandidate.plusMinutes(processingTime); LocalDateTime endCandidate = startCandidate.plusSeconds((long) processingTime);
// 检查是否容纳 // 检查是否容纳
if (endCandidate.isAfter(slot.getEnd())) { if (endCandidate.isAfter(slot.getEnd())) {
...@@ -621,10 +621,10 @@ public class AlgorithmScheduler6 { ...@@ -621,10 +621,10 @@ public class AlgorithmScheduler6 {
// ========================== CaldEarliestStart(参数与C#一致) ========================== // ========================== CaldEarliestStart(参数与C#一致) ==========================
private List<GeneDetail> CaldEarliestStart( private List<GeneDetail> CaldEarliestStart(
Machine machine, int processingTime, LocalDateTime currentTime, Machine machine, double processingTime, LocalDateTime currentTime,
String prevtime, List<Gene> machineTasks, boolean checkprevtime String prevtime, List<Gene> machineTasks, boolean checkprevtime
) { ) {
int remainingTime = processingTime; int remainingTime =(int) processingTime;
LocalDateTime st = StringUtils.isEmpty(prevtime) ? currentTime : LocalDateTime.parse(prevtime); LocalDateTime st = StringUtils.isEmpty(prevtime) ? currentTime : LocalDateTime.parse(prevtime);
LocalDateTime prevEnd = LocalDateTime.of(2000, 1, 1, 0, 0, 0); LocalDateTime prevEnd = LocalDateTime.of(2000, 1, 1, 0, 0, 0);
List<GeneDetail> times = new ArrayList<>(); List<GeneDetail> times = new ArrayList<>();
...@@ -652,7 +652,7 @@ public class AlgorithmScheduler6 { ...@@ -652,7 +652,7 @@ public class AlgorithmScheduler6 {
// 重置状态 // 重置状态
currentTime = shiftStart; currentTime = shiftStart;
st = shiftStart; st = shiftStart;
remainingTime = processingTime; remainingTime = (int)processingTime;
prevEnd = LocalDateTime.of(2000, 1, 1, 0, 0, 0); prevEnd = LocalDateTime.of(2000, 1, 1, 0, 0, 0);
oldTimes.addAll(deepCopyGeneDetailList(times)); oldTimes.addAll(deepCopyGeneDetailList(times));
times.clear(); times.clear();
...@@ -668,7 +668,7 @@ public class AlgorithmScheduler6 { ...@@ -668,7 +668,7 @@ public class AlgorithmScheduler6 {
if (hasMaintenance) { if (hasMaintenance) {
currentTime = shiftStart; currentTime = shiftStart;
st = shiftStart; st = shiftStart;
remainingTime = processingTime; remainingTime =(int) processingTime;
prevEnd = LocalDateTime.of(2000, 1, 1, 0, 0, 0); prevEnd = LocalDateTime.of(2000, 1, 1, 0, 0, 0);
times.clear(); times.clear();
continue; continue;
...@@ -680,18 +680,18 @@ public class AlgorithmScheduler6 { ...@@ -680,18 +680,18 @@ public class AlgorithmScheduler6 {
prevEnd = shiftEnd; prevEnd = shiftEnd;
// 计算有效时间 // 计算有效时间
LocalDateTime effectiveStart = st.isAfter(shiftStart) ? st : shiftStart; LocalDateTime effectiveStart = st.isAfter(shiftStart) ? st : shiftStart;
long availableMinutes = ChronoUnit.MINUTES.between(effectiveStart, shiftEnd); long availableMinutes = ChronoUnit.SECONDS.between(effectiveStart, shiftEnd);
// 处理当前班次 // 处理当前班次
int processable = Math.min(remainingTime, (int) availableMinutes); int processable = Math.min(remainingTime, (int) availableMinutes);
remainingTime -= processable; remainingTime -= processable;
currentTime = effectiveStart.plusMinutes(processable); currentTime = effectiveStart.plusSeconds(processable);
// 添加时间详情 // 添加时间详情
GeneDetail time = new GeneDetail(); GeneDetail time = new GeneDetail();
time.setKey(shift.getKey()); time.setKey(shift.getKey());
time.setStartTime((int) ChronoUnit.MINUTES.between(baseTime, effectiveStart)); time.setStartTime((int) ChronoUnit.SECONDS.between(baseTime, effectiveStart));
time.setEndTime((int) ChronoUnit.MINUTES.between(baseTime, currentTime)); time.setEndTime((int) ChronoUnit.SECONDS.between(baseTime, currentTime));
times.add(time); times.add(time);
RemoveMachineAvailable(machine, time); RemoveMachineAvailable(machine, time);
} }
...@@ -848,7 +848,7 @@ public class AlgorithmScheduler6 { ...@@ -848,7 +848,7 @@ public class AlgorithmScheduler6 {
// ========================== ConvertTime(参数与C#一致) ========================== // ========================== ConvertTime(参数与C#一致) ==========================
private String ConvertTime(int minute) { private String ConvertTime(int minute) {
return baseTime.plusMinutes(minute).format(java.time.format.DateTimeFormatter.ofPattern("MM-dd HH:mm")); return baseTime.plusSeconds(minute).format(java.time.format.DateTimeFormatter.ofPattern("MM-dd HH:mm"));
} }
......
...@@ -6,6 +6,7 @@ import com.aps.common.util.FileHelper; ...@@ -6,6 +6,7 @@ import com.aps.common.util.FileHelper;
import com.aps.entity.basic.ScheduleChromosome; import com.aps.entity.basic.ScheduleChromosome;
import com.aps.entity.basic.*; import com.aps.entity.basic.*;
import java.math.BigDecimal;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit; import java.time.temporal.ChronoUnit;
import java.util.*; import java.util.*;
...@@ -74,11 +75,11 @@ public class AlgorithmScheduler7 { ...@@ -74,11 +75,11 @@ public class AlgorithmScheduler7 {
.orElseThrow(() -> new NoSuchElementException("Product not found: " + order.getProductId())); .orElseThrow(() -> new NoSuchElementException("Product not found: " + order.getProductId()));
int prevtime = 0; int prevtime = 0;
int remainingQuantity = order.getQuantity(); int remainingQuantity =(int) order.getQuantity();
// 订单拆分逻辑 - 增强随机性 // 订单拆分逻辑 - 增强随机性
while (remainingQuantity > 0) { while (remainingQuantity > 0) {
int batchSize; Integer batchSize;
if (order.isCanSplit() && remainingQuantity > 1) { if (order.isCanSplit() && remainingQuantity > 1) {
// 修改:增强批次拆分的随机性 // 修改:增强批次拆分的随机性
int maxSplit = Math.min(remainingQuantity, Math.max(1, remainingQuantity / 2)); int maxSplit = Math.min(remainingQuantity, Math.max(1, remainingQuantity / 2));
...@@ -109,7 +110,7 @@ public class AlgorithmScheduler7 { ...@@ -109,7 +110,7 @@ public class AlgorithmScheduler7 {
// 多设备选择逻辑 - 增强随机性 // 多设备选择逻辑 - 增强随机性
if (operation.getMachineOptions().size() > 1) { if (operation.getMachineOptions().size() > 1) {
Set<Integer> machineIds = operation.getMachineOptions().stream() Set<Long> machineIds = operation.getMachineOptions().stream()
.map(MachineOption::getMachineId) .map(MachineOption::getMachineId)
.collect(Collectors.toSet()); .collect(Collectors.toSet());
...@@ -133,7 +134,7 @@ public class AlgorithmScheduler7 { ...@@ -133,7 +134,7 @@ public class AlgorithmScheduler7 {
machine = chromosome.getMachines().stream() machine = chromosome.getMachines().stream()
.filter(t -> machineIds.contains(t.getId())) .filter(t -> machineIds.contains(t.getId()))
.sorted(Comparator.comparingInt(Machine::getEarliestTime) .sorted(Comparator.comparingInt(Machine::getEarliestTime)
.thenComparingInt(Machine::getTotalTaskTime) .thenComparingDouble(Machine::getTotalTaskTime)
.thenComparing(t -> _random.nextDouble())) .thenComparing(t -> _random.nextDouble()))
.findFirst() .findFirst()
.orElseThrow(() -> new NoSuchElementException("No available machine for operation: " + operation.getId())); .orElseThrow(() -> new NoSuchElementException("No available machine for operation: " + operation.getId()));
...@@ -153,9 +154,12 @@ public class AlgorithmScheduler7 { ...@@ -153,9 +154,12 @@ public class AlgorithmScheduler7 {
.orElseThrow(() -> new NoSuchElementException("Machine not found: " + finalMachineOption.getMachineId())); .orElseThrow(() -> new NoSuchElementException("Machine not found: " + finalMachineOption.getMachineId()));
} }
// ==================== 修正的时间计算逻辑开始 ==================== // ==================== 修正的时间计算逻辑开始 ====================
int processingTime = machineOption.getProcessingTime() * batchSize;
int processingTime =(int)(machineOption.getProcessingTime()*batchSize);
if (machineOption.getContantTime() > 0) { if (machineOption.getContantTime() > 0) {
processingTime = machineOption.getContantTime(); processingTime =machineOption.getContantTime() ;
} }
int preTime = machineOption.getPreTime(); int preTime = machineOption.getPreTime();
int teardownTime = machineOption.getTeardownTime(); int teardownTime = machineOption.getTeardownTime();
...@@ -164,6 +168,7 @@ public class AlgorithmScheduler7 { ...@@ -164,6 +168,7 @@ public class AlgorithmScheduler7 {
int effectivePrepTime = Math.max(machineOption.getPreTime(), calculateSetupTime(chromosome.getGenes(), order, machine, machineOption)); int effectivePrepTime = Math.max(machineOption.getPreTime(), calculateSetupTime(chromosome.getGenes(), order, machine, machineOption));
// 检查是否是设备上的第一个产品 // 检查是否是设备上的第一个产品
boolean isFirstProductOnMachine = chromosome.getGenes().stream() boolean isFirstProductOnMachine = chromosome.getGenes().stream()
.filter(g -> g.getMachineId() == machine.getId()) .filter(g -> g.getMachineId() == machine.getId())
...@@ -176,7 +181,7 @@ public class AlgorithmScheduler7 { ...@@ -176,7 +181,7 @@ public class AlgorithmScheduler7 {
); );
// 关键修改2:总处理时间 = 有效准备时间(最大值) + 加工时间 + 后处理时间 // 关键修改2:总处理时间 = 有效准备时间(最大值) + 加工时间 + 后处理时间
int totalProcessingDuration = effectivePrepTime + processingTime + teardownTime; int totalProcessingDuration =effectivePrepTime+processingTime+teardownTime;
// 关键修改3:调整提议的开始时间,基于有效准备时间提前 // 关键修改3:调整提议的开始时间,基于有效准备时间提前
int proposedStartTimeWithPreTime = adjustedPrevTime; int proposedStartTimeWithPreTime = adjustedPrevTime;
...@@ -325,7 +330,7 @@ public class AlgorithmScheduler7 { ...@@ -325,7 +330,7 @@ public class AlgorithmScheduler7 {
*/ */
private int calculateAdjustedStartTime(List<Gene> existingGenes, int orderId, private int calculateAdjustedStartTime(List<Gene> existingGenes, int orderId,
int operationId, int preTime, int prevTime, int operationId, int preTime, int prevTime,
int machineId, boolean isFirstProductOnMachine) { Long machineId, boolean isFirstProductOnMachine) {
if (preTime <= 0 || operationId == 1) { if (preTime <= 0 || operationId == 1) {
return prevTime; // 第一道工序或没有前处理时间,不提前 return prevTime; // 第一道工序或没有前处理时间,不提前
} }
...@@ -532,10 +537,10 @@ public class AlgorithmScheduler7 { ...@@ -532,10 +537,10 @@ public class AlgorithmScheduler7 {
double totalSetupTime = 0.0; double totalSetupTime = 0.0;
double totalTeardownTime = 0.0; double totalTeardownTime = 0.0;
double totalPreTime = 0.0; double totalPreTime = 0.0;
Map<Integer, List<Gene>> machineGroups = chromosome.getGenes().stream() Map<Long, List<Gene>> machineGroups = chromosome.getGenes().stream()
.collect(Collectors.groupingBy(Gene::getMachineId)); .collect(Collectors.groupingBy(Gene::getMachineId));
for (Map.Entry<Integer, List<Gene>> machineGroup : machineGroups.entrySet()) { for (Map.Entry<Long, List<Gene>> machineGroup : machineGroups.entrySet()) {
List<Gene> sortedGenes = machineGroup.getValue().stream() List<Gene> sortedGenes = machineGroup.getValue().stream()
.sorted(Comparator.comparingInt(Gene::getStartTime)) .sorted(Comparator.comparingInt(Gene::getStartTime))
.collect(Collectors.toList()); .collect(Collectors.toList());
...@@ -578,7 +583,7 @@ public class AlgorithmScheduler7 { ...@@ -578,7 +583,7 @@ public class AlgorithmScheduler7 {
} }
private double CalculateMachineLoadBalance(ScheduleChromosome chromosome) { private double CalculateMachineLoadBalance(ScheduleChromosome chromosome) {
Map<Integer, Double> machineUtilization = new HashMap<>(); Map<Long, Double> machineUtilization = new HashMap<>();
int maxEndTime = chromosome.getGenes().stream() int maxEndTime = chromosome.getGenes().stream()
.mapToInt(Gene::getEndTime) .mapToInt(Gene::getEndTime)
.max() .max()
...@@ -715,7 +720,7 @@ public class AlgorithmScheduler7 { ...@@ -715,7 +720,7 @@ public class AlgorithmScheduler7 {
LocalDateTime startCandidate = slot.getStart().isAfter(prevTimeDateTime != null ? prevTimeDateTime : currentTime) LocalDateTime startCandidate = slot.getStart().isAfter(prevTimeDateTime != null ? prevTimeDateTime : currentTime)
? slot.getStart() ? slot.getStart()
: (prevTimeDateTime != null ? prevTimeDateTime : currentTime); : (prevTimeDateTime != null ? prevTimeDateTime : currentTime);
LocalDateTime endCandidate = startCandidate.plusMinutes(processingTime); LocalDateTime endCandidate = startCandidate.plusSeconds((int)processingTime);
if (endCandidate.isAfter(slot.getEnd())) { if (endCandidate.isAfter(slot.getEnd())) {
return CaldEarliestStart(machine, processingTime, currentTime, prevtime, machineTasks, checkprevtime); return CaldEarliestStart(machine, processingTime, currentTime, prevtime, machineTasks, checkprevtime);
...@@ -1352,7 +1357,7 @@ public class AlgorithmScheduler7 { ...@@ -1352,7 +1357,7 @@ public class AlgorithmScheduler7 {
/** /**
* 按设备ID查询可用时间(复用adjustTimeByMachineCalendar逻辑) * 按设备ID查询可用时间(复用adjustTimeByMachineCalendar逻辑)
*/ */
private int adjustTimeByMachineCalendar(int machineId, int proposedTime, boolean isStartTime) { private int adjustTimeByMachineCalendar(Long machineId, int proposedTime, boolean isStartTime) {
Machine machine = _machines.stream() Machine machine = _machines.stream()
.filter(m -> m.getId() == machineId) .filter(m -> m.getId() == machineId)
.findFirst() .findFirst()
......
...@@ -16,17 +16,21 @@ import java.util.stream.Collectors; ...@@ -16,17 +16,21 @@ import java.util.stream.Collectors;
public class MachineSchedulerService { public class MachineSchedulerService {
// 全局缓存(线程安全) // 全局缓存(线程安全)
private static final ConcurrentHashMap<Integer, MachineTimeline> timelineCache = new ConcurrentHashMap<>(); private static final ConcurrentHashMap<Long, MachineTimeline> timelineCache = new ConcurrentHashMap<>();
private LocalDateTime currentTime; private LocalDateTime currentTime;
private List<Holiday> holidays; private List<Holiday> holidays;
public MachineSchedulerService( LocalDateTime currentTime) {
this.holidays = holidays != null ? holidays : new ArrayList<>();
this.currentTime = currentTime;
}
public MachineSchedulerService(List<Holiday> holidays, LocalDateTime currentTime) { public MachineSchedulerService(List<Holiday> holidays, LocalDateTime currentTime) {
this.holidays = holidays != null ? holidays : new ArrayList<>(); this.holidays = holidays != null ? holidays : new ArrayList<>();
this.currentTime = currentTime; this.currentTime = currentTime;
} }
public MachineTimeline getOrCreateTimeline(Machine machine) { public MachineTimeline getOrCreateTimeline(Machine machine) {
int machineId = machine.getId(); long machineId = machine.getId();
// 尝试从缓存获取 // 尝试从缓存获取
MachineTimeline timeline = timelineCache.get(machineId); MachineTimeline timeline = timelineCache.get(machineId);
...@@ -57,7 +61,7 @@ public class MachineSchedulerService { ...@@ -57,7 +61,7 @@ public class MachineSchedulerService {
while (!currentDate.isAfter(endDate)) { while (!currentDate.isAfter(endDate)) {
// 检查是否在假期内 // 检查是否在假期内
boolean isHolidayPeriod = isHoliday(currentDate); boolean isHolidayPeriod = isHoliday(machine,currentDate);
// 生成当日时间段 // 生成当日时间段
List<TimeSegment> daySegments = calculateDaySegments(machine, currentDate, isHolidayPeriod); List<TimeSegment> daySegments = calculateDaySegments(machine, currentDate, isHolidayPeriod);
...@@ -90,7 +94,7 @@ public class MachineSchedulerService { ...@@ -90,7 +94,7 @@ public class MachineSchedulerService {
} }
public List<TimeSegment> generateTimeSegment(Machine machine, LocalDateTime currentTime) { public List<TimeSegment> generateTimeSegment(Machine machine, LocalDateTime currentTime) {
int machineId = machine.getId(); Long machineId = machine.getId();
MachineTimeline timeline = timelineCache.get(machineId); MachineTimeline timeline = timelineCache.get(machineId);
if (timeline == null) { if (timeline == null) {
...@@ -112,7 +116,7 @@ public class MachineSchedulerService { ...@@ -112,7 +116,7 @@ public class MachineSchedulerService {
while (!currentDate.isAfter(endDate)) { while (!currentDate.isAfter(endDate)) {
// 检查是否在假期内 // 检查是否在假期内
boolean isHolidayPeriod = isHoliday(currentDate); boolean isHolidayPeriod = isHoliday(machine,currentDate);
// 生成当日时间段 // 生成当日时间段
List<TimeSegment> daySegments = calculateDaySegments(machine, currentDate, isHolidayPeriod); List<TimeSegment> daySegments = calculateDaySegments(machine, currentDate, isHolidayPeriod);
...@@ -148,8 +152,10 @@ public class MachineSchedulerService { ...@@ -148,8 +152,10 @@ public class MachineSchedulerService {
return segments; return segments;
} }
private boolean isHoliday(LocalDate currentDate) { private boolean isHoliday(Machine machine,LocalDate currentDate) {
for (Holiday holiday : holidays) { if(machine.getHolidays()==null||machine.getHolidays().size()==0)
return false;
for (Holiday holiday : machine.getHolidays()) {
LocalDateTime holidayStart = holiday.getStart(); LocalDateTime holidayStart = holiday.getStart();
LocalDateTime holidayEnd = holiday.getEnd(); LocalDateTime holidayEnd = holiday.getEnd();
...@@ -173,8 +179,9 @@ public class MachineSchedulerService { ...@@ -173,8 +179,9 @@ public class MachineSchedulerService {
// 假期:只处理特定日期的班次 // 假期:只处理特定日期的班次
List<Shift> shifts = machine.getShifts().stream() List<Shift> shifts = machine.getShifts().stream()
.filter(s -> s.getDays() == null && .filter(s -> s.getDays() == null &&
s.getShiftDate() != null && date.compareTo(s.getStartDate().toLocalDate())>=0
s.getShiftDate().toLocalDate().equals(date)) &&s.getEndDate().toLocalDate().compareTo(date)>=0
)
.collect(Collectors.toList()); .collect(Collectors.toList());
for (Shift shift : shifts) { for (Shift shift : shifts) {
...@@ -193,7 +200,11 @@ public class MachineSchedulerService { ...@@ -193,7 +200,11 @@ public class MachineSchedulerService {
} else { } else {
// 非假期:处理常规班次 // 非假期:处理常规班次
List<Shift> shifts = machine.getShifts().stream() List<Shift> shifts = machine.getShifts().stream()
.filter(s -> s.getDays() != null && containsDay(s.getDays(), date.getDayOfWeek())) .filter(s ->
date.compareTo(s.getStartDate().toLocalDate())>=0
&&s.getEndDate().toLocalDate().compareTo(date)>=0
&& s.getDays() != null
&& containsDay(s.getDays(), date.getDayOfWeek()))
.collect(Collectors.toList()); .collect(Collectors.toList());
for (Shift shift : shifts) { for (Shift shift : shifts) {
......
...@@ -2,24 +2,27 @@ package com.aps.service.plan; ...@@ -2,24 +2,27 @@ package com.aps.service.plan;
import com.aps.common.util.FileHelper; import com.aps.common.util.FileHelper;
import com.aps.common.util.JsonFileReader; import com.aps.common.util.JsonFileReader;
import com.aps.common.util.ProductionDeepCopyUtil;
import com.aps.controller.gantt.FileUploadController; import com.aps.controller.gantt.FileUploadController;
import com.aps.entity.*;
import com.aps.entity.Algorithm.Chromosome; import com.aps.entity.Algorithm.Chromosome;
import com.aps.entity.Algorithm.GAScheduleResult; import com.aps.entity.Algorithm.GAScheduleResult;
import com.aps.entity.Algorithm.ScheduleParams; import com.aps.entity.Algorithm.ScheduleParams;
import com.aps.entity.Algorithm.ScheduleResultDetail; import com.aps.entity.Algorithm.ScheduleResultDetail;
import com.aps.entity.MesHoliday;
import com.aps.entity.basic.ScheduleChromosome; import com.aps.entity.basic.ScheduleChromosome;
import com.aps.entity.Schedule.GenVO; import com.aps.entity.Schedule.GenVO;
import com.aps.entity.Schedule.MachineVO; import com.aps.entity.Schedule.MachineVO;
import com.aps.entity.basic.*; import com.aps.entity.basic.*;
import com.aps.service.*;
import com.aps.service.Algorithm.GeneticAlgorithm; import com.aps.service.Algorithm.GeneticAlgorithm;
import com.aps.service.MesHolidayService; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import java.io.IOException; import java.io.IOException;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*; import java.util.*;
import java.util.stream.Collectors; import java.util.stream.Collectors;
...@@ -32,6 +35,21 @@ public class PlanResultService { ...@@ -32,6 +35,21 @@ public class PlanResultService {
@Autowired @Autowired
private MesHolidayService _MesHolidayService; private MesHolidayService _MesHolidayService;
@Autowired
private ProdEquipSpecialCalService _prodEquipSpecialCalService;
@Autowired
private MesShiftWorkSchedService _MesShiftWorkSchedService;
@Autowired
private ProdProcessExecService _prodProcessExecService;
@Autowired
private ProdEquipmentService _prodEquipmentService;
@Autowired
private ProdOrderProcessService _prodOrderProcessService;
private final LocalDateTime baseTime = LocalDateTime.of(2025, 10, 1, 0, 0, 0); private final LocalDateTime baseTime = LocalDateTime.of(2025, 10, 1, 0, 0, 0);
...@@ -201,6 +219,227 @@ public class PlanResultService { ...@@ -201,6 +219,227 @@ public class PlanResultService {
throw new RuntimeException("调度执行失败", e); throw new RuntimeException("调度执行失败", e);
} }
} }
public List<Chromosome> execute2(String SceneId) {
try {
ScheduleParams param = new ScheduleParams();
param.setBaseTime(LocalDateTime.of(2025, 11, 1, 0, 0, 0));
param.setPopulationSize(50);
param.setMaxIterations(100);
// 1. 读取数据
// List<Machine> machines = loadData("machines.json", Machine.class);
// List<Product> products = loadData("products.json", Product.class);
// List<Order> orders = loadData("orders.json", Order.class);
List<ProdProcessExec> ProdProcessExecs= _prodProcessExecService.lambdaQuery()
.eq(ProdProcessExec::getSceneId,SceneId)
.list();
List<ProdEquipment> ProdEquipments= _prodEquipmentService.lambdaQuery()
.eq(ProdEquipment::getSceneId,SceneId)
.list();
List<ProdOrderProcess> ProdOrderProcesss = _prodOrderProcessService.lambdaQuery()
.eq(ProdOrderProcess::getSceneId,SceneId)
.list();
Set<String> targetExecId = ProdOrderProcesss.stream()
.map(ProdOrderProcess::getTargetExecId) // 提取TARGET_ORDER_ID
.collect(Collectors.toSet()); // 转为Set去重
List<ProdProcessExec> ops= ProdProcessExecs.stream()
.filter(e -> !targetExecId.contains(e.getExecId())) // 过滤条件
.collect(Collectors.toList());
// 按设备分组
List<Long> MachineIds = ProdEquipments.stream()
.map(ProdEquipment::getEquipId)
.distinct()
.sorted()
.collect(Collectors.toList());
List<Machine> machines=new ArrayList<>();
for (Long id : MachineIds) {
Machine machine=new Machine();
machine.setId(id);
machines.add(machine);
}
//节假日
List<MesHoliday> holidays= _MesHolidayService.list();
LambdaQueryWrapper<ProdEquipSpecialCal> ProdEquipSpecialCalWrapper = new LambdaQueryWrapper<>();
ProdEquipSpecialCalWrapper.eq(ProdEquipSpecialCal::getSceneId, SceneId);
List<ProdEquipSpecialCal> ProdEquipSpecialCals= _prodEquipSpecialCalService.list(ProdEquipSpecialCalWrapper);
List<MesShiftWorkSched> MesShiftWorkScheds= _MesShiftWorkSchedService.list();
// 将节假日添加到所有设备中
InitCalendarToAllMachines(machines, ProdEquipSpecialCals,MesShiftWorkScheds);
// 3. 创建调度服务
MachineSchedulerService machineScheduler = new MachineSchedulerService(
param.getBaseTime());
// 4. 初始化机器时间线
for (Machine machine : machines) {
MachineTimeline timeline = machineScheduler.getOrCreateTimeline(machine);
machine.setAvailability(timeline.getSegments());
}
// 3. 构建订单-工序数据
List<Entry> allOperations = new ArrayList<>();
Random rnd = new Random(); // 注意:此处变量声明但未使用,可根据实际需求保留或移除
int id = 0;
int groupid = 1;
List<Entry> entrys=new ArrayList<>();
for (ProdProcessExec op : ops) {
int sequence = 1;
Entry entry = new Entry();
id = id + 1;
entry.setId(id);
entry.setGroupId(groupid);
entry.setSequence(sequence);
entry.setExecId(op.getExecId());
entry.setOrderId(op.getOrderId());
entry.setQuantity(op.getPlanQty());
List<ProdEquipment> Equipments= ProdEquipments.stream()
.filter(t->t.getExecId().equals(op.getExecId()))
.collect(Collectors.toList());
if(Equipments!=null&&Equipments.size()>0) {
List<MachineOption> mos=new ArrayList<>();
for (ProdEquipment e : Equipments) {
MachineOption mo=new MachineOption();
mo.setMachineId(e.getEquipId());
mo.setProcessingTime(e.getSpeed());
// mo.setTeardownTime(op.getPostprocessingTime());
mos.add(mo);
}
entry.setMachineOptions(mos);
}
// 假设Operation类有获取机器选项的方法
entry.setPriority(1);
entrys.add(entry);
List<ProdOrderProcess> nextop = ProdOrderProcesss.stream()
.filter(t -> t.getExecId().equals(op.getExecId()))
.collect(Collectors.toList());
if(nextop!=null&&nextop.size()>0) {
entrys.addAll(AddNextEntry(id, sequence, id, op.getExecId(), nextop, ProdOrderProcesss,ProdEquipments, ProdProcessExecs));
}
groupid++;
}
// for (Order order : orders) {
//
// int sequence = 1;
// for (Operation o : product.getOperations()) { // 假设Product类有getOperations()方法返回工序列表
// Entry entry = new Entry();
// entry.setId(id);
// entry.setGroupId(order.getId());
// entry.setSequence(sequence);
// entry.setMachineOptions(o.getMachineOptions()); // 假设Operation类有获取机器选项的方法
// entry.setPriority(order.getPriority());
// entry.setQuantity(order.getQuantity());
// // entry.setMaterialRequirements(o.getMaterialRequirements()); // 假设Operation类有获取物料需求的方法
//
// if (sequence != 1) {
// entry.getPrevEntryIds().add(id - 1); // 假设Entry类有getPrevEntryIds()返回List<Integer>
// }
//
// allOperations.add(entry);
//
// sequence++;
// id++;
// }
// }
// 5. 执行调度算法
GeneticAlgorithm scheduler =new GeneticAlgorithm(machines,null,null,machineScheduler); //new GeneticAlgorithm(products, machines, orders, machineScheduler);
List<Chromosome> Chromosomes =scheduler.Run(param,allOperations);
Chromosomes.forEach(this::WriteScheduleSummary);
return Chromosomes;
} catch (Exception e) {
throw new RuntimeException("调度执行失败", e);
}
}
private List<Entry> AddNextEntry(int previd,int prevsequence,int pid,String execId ,List<ProdOrderProcess> nextop,List<ProdOrderProcess> ProdOrderProcesss,List<ProdEquipment> ProdEquipments,List<ProdProcessExec> ProdProcessExecs)
{
List<Entry> entrys=new ArrayList<>();
int id=previd;
int sequence=prevsequence;
for (ProdOrderProcess o : nextop) {
List<Integer> privids=new ArrayList<>();
privids.add(pid);
Entry entry = new Entry();
id=id+1;
entry.setId(id);
sequence=sequence+1;
entry.setSequence(sequence);
entry.setPrevEntryIds(privids);
entry.setExecId(o.getExecId());
ProdProcessExec op= ProdProcessExecs.stream().filter(t->t.getExecId()==o.getExecId()).findFirst().orElse(null);
entry.setOrderId(op.getOrderId());
entry.setQuantity(op.getPlanQty());
List<ProdEquipment> Equipments= ProdEquipments.stream()
.filter(t->t.getExecId().equals(op.getExecId()))
.collect(Collectors.toList());
if(Equipments!=null&&Equipments.size()>0) {
List<MachineOption> mos=new ArrayList<>();
for (ProdEquipment e : Equipments) {
MachineOption mo=new MachineOption();
mo.setMachineId(e.getEquipId());
mo.setProcessingTime(e.getSpeed());
// mo.setTeardownTime(op.getPostprocessingTime());
mos.add(mo);
}
entry.setMachineOptions(mos);
}
// 假设Operation类有获取机器选项的方法
entry.setPriority(1);
entrys.add(entry);
}
int id1=previd;
for (ProdOrderProcess o : nextop) {
List<ProdOrderProcess> nextop1 = ProdOrderProcesss.stream()
.filter(t -> t.getExecId() == o.getExecId())
.collect(Collectors.toList());
if(nextop1!=null&&nextop1.size()>0)
{
id1=id1+1;
entrys.addAll( AddNextEntry(id,sequence,id1,o.getExecId(),nextop1,ProdOrderProcesss,ProdEquipments,ProdProcessExecs));
}
}
return entrys;
}
public void WriteScheduleSummary(Chromosome schedule) { public void WriteScheduleSummary(Chromosome schedule) {
// 写入日志 // 写入日志
FileHelper.writeLogFile(String.format("\n=== Schedule Summary === %f", schedule.getFitness())); FileHelper.writeLogFile(String.format("\n=== Schedule Summary === %f", schedule.getFitness()));
...@@ -305,6 +544,80 @@ public class PlanResultService { ...@@ -305,6 +544,80 @@ public class PlanResultService {
} }
} }
private void InitCalendarToAllMachines(List<Machine> machines, List<ProdEquipSpecialCal> ProdEquipSpecialCals,List<MesShiftWorkSched> MesShiftWorkScheds) {
if (machines == null) {
return;
}
for (Machine machine : machines) {
// 确保维护窗口列表不为null
if (machine.getMaintenanceWindows() == null) {
machine.setMaintenanceWindows(new ArrayList<>());
}
List<ProdEquipSpecialCal> machineProdEquipSpecialCals = ProdEquipSpecialCals.stream()
.filter(t -> t.getEquipId() == machine.getId())
.collect(Collectors.toList());
List<Shift> shifts1=new ArrayList<>();
for (ProdEquipSpecialCal machineProdEquipSpecialCal : machineProdEquipSpecialCals) {
List<MesShiftWorkSched> ShiftWorkScheds = MesShiftWorkScheds.stream()
.filter(t -> (long) t.getWeekWorkSchedId() == machineProdEquipSpecialCal.getReferenceId())
.collect(Collectors.toList());
List<Shift> Shifts = mergeShiftData(ShiftWorkScheds);
for (Shift shift : Shifts) {
shift.setMachineId(machine.getId());
shift.setStartDate(machineProdEquipSpecialCal.getStartDate());
shift.setEndDate(machineProdEquipSpecialCal.getEndDate());
shifts1.add(shift);
}
}
machine.setShifts(shifts1);
}
}
/**
* 合并重复的ShiftData,将serialNumber收集为列表
* @param originalList 原始数据列表
* @return 合并后的MergedShiftData列表
*/
public static List<Shift> mergeShiftData(List<MesShiftWorkSched> originalList) {
// 按shiftStart和shiftEnd分组
Map<String, Shift> groupMap = new HashMap<>();
for (MesShiftWorkSched data : originalList) {
// 用shiftStart+shiftEnd作为分组key
String groupKey = data.getShiftStart().toString() + "_" + data.getShiftEnd().toString();
if (groupMap.containsKey(groupKey)) {
// 已存在分组:添加serialNumber到列表
Shift merged = groupMap.get(groupKey);
merged.getDays().add(data.getStartWeekDay());
} else {
// 新分组:创建MergedShiftData并初始化
Shift merged = new Shift();
merged.setStartTime(data.getShiftStart().toLocalTime());
merged.setEndTime(data.getShiftEnd().toLocalTime());
merged.setStatus(0);
// 初始化序号列表
Set<Integer> serials =new HashSet<>();
serials.add(data.getStartWeekDay());
merged.setDays(serials);
groupMap.put(groupKey, merged);
}
}
// 转换为列表返回
return new ArrayList<>(groupMap.values());
}
public GenVO convertGeneToGenVO(Gene gene, LocalDateTime baseTime) { public GenVO convertGeneToGenVO(Gene gene, LocalDateTime baseTime) {
GenVO genVO = new GenVO(); GenVO genVO = new GenVO();
genVO.setOrderId(String.valueOf(gene.getOrderId())); genVO.setOrderId(String.valueOf(gene.getOrderId()));
......
...@@ -58,7 +58,7 @@ public class PlanSchedulerService { ...@@ -58,7 +58,7 @@ public class PlanSchedulerService {
.collect(Collectors.toList()); .collect(Collectors.toList());
// 按设备ID分组任务 // 按设备ID分组任务
Map<Integer, List<GenVO>> taskMap = genVOS.stream() Map<Long, List<GenVO>> taskMap = genVOS.stream()
.collect(Collectors.groupingBy(GenVO::getEquipId)); .collect(Collectors.groupingBy(GenVO::getEquipId));
// 为每个设备设置任务 // 为每个设备设置任务
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment