Commit f7bdf363 authored by Tong Li's avatar Tong Li

遗传算法

parent eee3a165
...@@ -106,9 +106,9 @@ public class ResourceGanttController { ...@@ -106,9 +106,9 @@ public class ResourceGanttController {
@GetMapping("/getScene") @GetMapping("/getScene")
@Operation(summary = "获取所有场景ID", description = "获取所有场景ID") @Operation(summary = "获取所有场景ID", description = "获取所有场景ID")
public List<Chromosome> getScene() { public Chromosome getScene() {
// 调用 PlanResultService 获取 ScheduleChromosome 列表 // 调用 PlanResultService 获取 ScheduleChromosome 列表
List<Chromosome> scheduleChromosomes = planResultService.execute1(); Chromosome scheduleChromosomes = planResultService.execute1();
// 提取所有场景ID // 提取所有场景ID
return scheduleChromosomes; return scheduleChromosomes;
...@@ -116,9 +116,9 @@ public class ResourceGanttController { ...@@ -116,9 +116,9 @@ public class ResourceGanttController {
@GetMapping("/getScene2") @GetMapping("/getScene2")
@Operation(summary = "获取所有场景ID", description = "获取所有场景ID") @Operation(summary = "获取所有场景ID", description = "获取所有场景ID")
public List<Chromosome> getScene2() { public Chromosome getScene2() {
// 调用 PlanResultService 获取 ScheduleChromosome 列表 // 调用 PlanResultService 获取 ScheduleChromosome 列表
List<Chromosome> scheduleChromosomes = planResultService.execute2("EAA26D85B5824B40A17554297B4EA32B"); Chromosome scheduleChromosomes = planResultService.execute2("B571EF6682DB463AB2977B1055A74112");
// 提取所有场景ID // 提取所有场景ID
return scheduleChromosomes; return scheduleChromosomes;
......
...@@ -12,11 +12,18 @@ import java.util.List; ...@@ -12,11 +12,18 @@ import java.util.List;
@Data @Data
public class GAScheduleResult { public class GAScheduleResult {
private int GroupId; private int GroupId;
private int ProductId;
private int OperationId; private int OperationId;
/**
* 工单ID
*/
public String ExecId ;
public String OrderId ;
private String productId;
private long MachineId; private long MachineId;
private int StartTime; // 相对开始时间(分钟) private int StartTime; // 相对开始时间(秒)
private int EndTime; // 相对结束时间(分钟) private int EndTime; // 相对结束时间(秒)
private int teardownTime; //后处理
private double Quantity; // 批次大小(订单可拆分) private double Quantity; // 批次大小(订单可拆分)
private List<ScheduleResultDetail> GeneDetails; // 时间详情 private List<ScheduleResultDetail> GeneDetails; // 时间详情
private double OneTime; // 单件工时 private double OneTime; // 单件工时
......
package com.aps.entity.Algorithm.IDAndChildID;
import java.util.List;
import java.util.Map;
/**
* 作者:佟礼
* 时间:2025-11-29
*/
// 存储分组结果:节点信息列表、新父子映射
// 存储分组结果:节点信息列表、原始ID(String)→全局序号映射
// 存储分组结果:节点信息列表、原始ID→全局序号映射
public class GroupResult {
private List<NodeInfo> nodeInfoList;
private Map<String, Integer> originalToGlobalSerial;
public GroupResult(List<NodeInfo> nodeInfoList, Map<String, Integer> originalToGlobalSerial) {
this.nodeInfoList = nodeInfoList;
this.originalToGlobalSerial = originalToGlobalSerial;
}
// getter
public List<NodeInfo> getNodeInfoList() { return nodeInfoList; }
public Map<String, Integer> getOriginalToGlobalSerial() { return originalToGlobalSerial; }
}
package com.aps.entity.Algorithm.IDAndChildID;
import lombok.Data;
import java.util.List;
/**
* 作者:佟礼
* 时间:2025-11-29
*/
// 存储节点信息:原ID、新序号、新父ID、新子ID列表
@Data
// 存储节点信息:原ID(String)、全局新序号、分组内序号、新父ID列表、新子ID列表
public class NodeInfo {
private String originalId; // 原始ID
private Integer globalSerial; // 全局新序号
private Integer groupSerial; // 分组内序号
private List<Integer> newParentIds; // 新父ID列表(基于全局序号)
private List<Integer> newChildIds; // 新子ID列表(基于全局序号)
public NodeInfo(String originalId, Integer globalSerial, Integer groupSerial, List<Integer> newParentIds, List<Integer> newChildIds) {
this.originalId = originalId;
this.globalSerial = globalSerial;
this.groupSerial = groupSerial;
this.newParentIds = newParentIds;
this.newChildIds = newChildIds;
}
@Override
public String toString() {
return originalId + ":" + globalSerial;
}
}
...@@ -29,6 +29,7 @@ public class Entry { ...@@ -29,6 +29,7 @@ public class Entry {
*/ */
public String OrderId ; public String OrderId ;
private String productId;
/** /**
* 工单ID * 工单ID
*/ */
...@@ -36,7 +37,7 @@ public class Entry { ...@@ -36,7 +37,7 @@ public class Entry {
/** /**
* 离散参数 * 离散参数
*/ */
public String DiscreteParameter ; public List<String> DiscreteParameter ;
/** /**
* 基因编号 * 基因编号
*/ */
...@@ -58,6 +59,11 @@ public class Entry { ...@@ -58,6 +59,11 @@ public class Entry {
*/ */
public List<Integer> PrevEntryIds ;//前工序 public List<Integer> PrevEntryIds ;//前工序
/**
* 前工单ID
*/
public List<Integer> NextEntryIds ;//后工序
/** /**
* 是否可中断,间缝插针 * 是否可中断,间缝插针
*/ */
......
...@@ -11,15 +11,17 @@ public class GlobalParam { ...@@ -11,15 +11,17 @@ public class GlobalParam {
/// <summary> /// <summary>
/// 是否可以打破优先级 /// 是否可以打破优先级
/// </summary> /// </summary>
public static boolean IsBreakPriority = false; private boolean IsBreakPriority = false;
/// <summary> /// <summary>
/// 是否多台设备 /// 是否多台设备
/// </summary> /// </summary>
public static boolean IsMultipleMachine = false; private boolean IsMultipleMachine = false;
/// <summary> /// <summary>
/// 是否重叠 /// 是否重叠
/// </summary> /// </summary>
public static boolean IsOverlap = false; private boolean IsOverlap = false;
private boolean _smoothSetup = false; // 默认true,不占用设备时长
} }
...@@ -11,11 +11,14 @@ import java.time.OffsetDateTime; ...@@ -11,11 +11,14 @@ import java.time.OffsetDateTime;
@Data @Data
public class Order { public class Order {
private int id; private int id;
private String OrderId;
private int productId; private int productId;
private String materialId;
private double quantity = 100; // 100个 private double quantity = 100; // 100个
private double sYQuantity; private double sYQuantity;
private OffsetDateTime dueDate; private LocalDateTime dueDate;
private LocalDateTime orderCompletion; private LocalDateTime orderCompletion;
private double tardiness; private double tardiness;
private int priority; private int priority;
......
...@@ -96,38 +96,38 @@ public class ScheduleChromosome { ...@@ -96,38 +96,38 @@ public class ScheduleChromosome {
private List<Order> calTardiness() { private List<Order> calTardiness() {
tardiness = 0; tardiness = 0;
for (Order order : orders) { // for (Order order : orders) {
final int orderId = order.getId(); // final int orderId = order.getId();
List<Gene> orderGroups = genes.stream() // List<Gene> orderGroups = genes.stream()
.filter(g -> g.getOrderId() == orderId) // .filter(g -> g.getOrderId() == orderId)
.collect(Collectors.toList()); // .collect(Collectors.toList());
//
int orderCompletion = orderGroups.stream() // int orderCompletion = orderGroups.stream()
.mapToInt(Gene::getEndTime) // .mapToInt(Gene::getEndTime)
.max() // .max()
.orElse(0); // .orElse(0);
//
LocalDateTime orderCompletionTime = baseTime.plusMinutes(orderCompletion); // LocalDateTime orderCompletionTime = baseTime.plusMinutes(orderCompletion);
order.setOrderCompletion(orderCompletionTime); // order.setOrderCompletion(orderCompletionTime);
order.setTardiness(0); // order.setTardiness(0);
//
// 修复:统一时间类型 // // 修复:统一时间类型
LocalDateTime dueDateTime = order.getDueDate().toLocalDateTime(); // LocalDateTime dueDateTime = order.getDueDate();
//
if (orderCompletionTime.isAfter(dueDateTime)) { // if (orderCompletionTime.isAfter(dueDateTime)) {
// 方法1:使用分钟计算再转换为小时(推荐) // // 方法1:使用分钟计算再转换为小时(推荐)
long totalMinutes = java.time.temporal.ChronoUnit.MINUTES.between(dueDateTime, orderCompletionTime); // long totalMinutes = java.time.temporal.ChronoUnit.MINUTES.between(dueDateTime, orderCompletionTime);
double tardinessHours = totalMinutes / 60.0; // double tardinessHours = totalMinutes / 60.0;
//
// 方法2:或者保持原有逻辑但使用统一的时间类型 // // 方法2:或者保持原有逻辑但使用统一的时间类型
// long diffHours = java.time.temporal.ChronoUnit.HOURS.between(dueDateTime, orderCompletionTime); // // long diffHours = java.time.temporal.ChronoUnit.HOURS.between(dueDateTime, orderCompletionTime);
// long remainingMinutes = java.time.temporal.ChronoUnit.MINUTES.between(dueDateTime, orderCompletionTime) % 60; // // long remainingMinutes = java.time.temporal.ChronoUnit.MINUTES.between(dueDateTime, orderCompletionTime) % 60;
// double tardinessHours = diffHours + (double) remainingMinutes / 60; // // double tardinessHours = diffHours + (double) remainingMinutes / 60;
//
order.setTardiness(tardinessHours); // order.setTardiness(tardinessHours);
tardiness += tardinessHours; // tardiness += tardinessHours;
} // }
} // }
return orders; return null;
} }
} }
\ No newline at end of file
...@@ -6,10 +6,7 @@ import com.aps.entity.Algorithm.Chromosome; ...@@ -6,10 +6,7 @@ import com.aps.entity.Algorithm.Chromosome;
import com.aps.entity.Algorithm.GlobalOperationInfo; import com.aps.entity.Algorithm.GlobalOperationInfo;
import com.aps.entity.Algorithm.Pair; import com.aps.entity.Algorithm.Pair;
import com.aps.entity.Algorithm.ScheduleParams; import com.aps.entity.Algorithm.ScheduleParams;
import com.aps.entity.basic.Entry; import com.aps.entity.basic.*;
import com.aps.entity.basic.Machine;
import com.aps.entity.basic.Material;
import com.aps.entity.basic.Order;
import com.aps.service.plan.MachineSchedulerService; import com.aps.service.plan.MachineSchedulerService;
import java.util.*; import java.util.*;
...@@ -25,20 +22,22 @@ public class GeneticAlgorithm { ...@@ -25,20 +22,22 @@ public class GeneticAlgorithm {
private final MachineSchedulerService machineScheduler; private final MachineSchedulerService machineScheduler;
private final List<Order> orders; private final List<Order> orders;
private final List<Material> materials; private final List<Material> materials;
private static GlobalParam _GlobalParam;
public GeneticAlgorithm(List<Machine> machines, List<Order> orders, public GeneticAlgorithm(GlobalParam globalParam,List<Machine> machines, List<Order> orders,
List<Material> materials, MachineSchedulerService machineScheduler) { List<Material> materials, MachineSchedulerService machineScheduler) {
this.machines = machines; this.machines = machines;
this.orders = orders; this.orders = orders;
this.materials = materials; this.materials = materials;
this.machineScheduler = machineScheduler; this.machineScheduler = machineScheduler;
_GlobalParam=globalParam;
} }
public List<Chromosome> Run(ScheduleParams param, List<Entry> allOperations) { public Chromosome Run(ScheduleParams param, List<Entry> allOperations) {
System.out.println("开始"); System.out.println("开始");
Initialization initialization = new Initialization(allOperations); Initialization initialization = new Initialization(_GlobalParam,allOperations);
GeneticOperations geneticOps = new GeneticOperations(allOperations); GeneticOperations geneticOps = new GeneticOperations(_GlobalParam,allOperations);
// 预生成全局工序列表(所有初始化方法共享同一顺序) // 预生成全局工序列表(所有初始化方法共享同一顺序)
List<GlobalOperationInfo> globalOpList = initialization.generateGlobalOpList(); List<GlobalOperationInfo> globalOpList = initialization.generateGlobalOpList();
...@@ -124,36 +123,43 @@ public class GeneticAlgorithm { ...@@ -124,36 +123,43 @@ public class GeneticAlgorithm {
Iteration++; Iteration++;
} }
if(Iteration>20) if(Iteration>10)
{ {
break; break;
} }
} }
// 步骤3:返回最优解 // 步骤3:返回最优解
return population.stream() return best;
.sorted((c1, c2) -> Double.compare(c2.getFitness(), c1.getFitness()))
.limit(10)
.collect(Collectors.toList());
} }
private void Chromosomedecode(ScheduleParams param, List<Entry> allOperations,List<GlobalOperationInfo> globalOpList,List<Chromosome> population) private void Chromosomedecode(ScheduleParams param, List<Entry> allOperations,List<GlobalOperationInfo> globalOpList,List<Chromosome> population)
{ {
GeneticDecoder decoder = new GeneticDecoder(param.getBaseTime(), machines, orders, materials, machineScheduler); GeneticDecoder decoder = new GeneticDecoder(_GlobalParam, param.getBaseTime(), machines, orders, materials, machineScheduler);
FitnessCalculator fitnessCalc = new FitnessCalculator(); FitnessCalculator fitnessCalc = new FitnessCalculator();
population.parallelStream().forEach(chromosome -> { // population.parallelStream().forEach(chromosome -> {
// chromosome.setResult(new ArrayList<>());
//
// // 假设Machine类有拷贝方法,或使用MapStruct等工具进行映射
// chromosome.setMachines(ProductionDeepCopyUtil.deepCopyList(machines)); // 简单拷贝,实际可能需要深拷贝
//
// decoder.decodeChromosomeWithCache(chromosome, globalOpList, allOperations);
// chromosome.setFitness(fitnessCalc.calculateFitness(chromosome));
// });
population.forEach(chromosome -> {
chromosome.setResult(new ArrayList<>()); chromosome.setResult(new ArrayList<>());
// 假设Machine类有拷贝方法,或使用MapStruct等工具进行映射 // 假设Machine类有拷贝方法,或使用MapStruct等工具进行映射
chromosome.setMachines(ProductionDeepCopyUtil.deepCopyList(machines)); // 简单拷贝,实际可能需要深拷贝 chromosome.setMachines(ProductionDeepCopyUtil.deepCopyList(machines)); // 简单拷贝,实际可能需要深拷贝
decoder.decodeChromosomeWithCache(chromosome, globalOpList, allOperations); Chromosome chromosomen= decoder.decodeChromosomeWithCache(chromosome, globalOpList, allOperations);
chromosome.setFitness(fitnessCalc.calculateFitness(chromosome)); if(chromosomen.getFitness()==0) {
chromosomen.setFitness(fitnessCalc.calculateFitness(chromosomen));
}
}); });
} }
} }
...@@ -18,9 +18,13 @@ import java.util.stream.Collectors; ...@@ -18,9 +18,13 @@ import java.util.stream.Collectors;
*/ */
public class GeneticOperations { public class GeneticOperations {
private final Random rnd = new Random(); private final Random rnd = new Random();
private static GlobalParam _GlobalParam;
private static List<Entry> allOperations; private static List<Entry> allOperations;
public GeneticOperations(List<Entry> allOperations) { public GeneticOperations(GlobalParam globalParam,List<Entry> allOperations) {
_GlobalParam=globalParam;
GeneticOperations.allOperations = allOperations; GeneticOperations.allOperations = allOperations;
} }
...@@ -225,7 +229,7 @@ public class GeneticOperations { ...@@ -225,7 +229,7 @@ public class GeneticOperations {
Random rnd = new Random(); Random rnd = new Random();
List<OperationSequencingWeight> indexWeights = CommonCalculator.getOsw(os, allOperations); List<OperationSequencingWeight> indexWeights = CommonCalculator.getOsw(os, allOperations);
if (!GlobalParam.IsBreakPriority) { if (!_GlobalParam.isIsBreakPriority()) {
if (weight == 0) { if (weight == 0) {
return indexWeights.get(rnd.nextInt(indexWeights.size())); return indexWeights.get(rnd.nextInt(indexWeights.size()));
} else { } else {
......
...@@ -17,9 +17,11 @@ import java.util.stream.IntStream; ...@@ -17,9 +17,11 @@ import java.util.stream.IntStream;
*/ */
public class Initialization { public class Initialization {
private static List<Entry> allOperations; private static List<Entry> allOperations;
private static GlobalParam _globalParam;
public Initialization(List<Entry> allOperations) { public Initialization(GlobalParam globalParam,List<Entry> allOperations) {
Initialization.allOperations = allOperations; Initialization.allOperations = allOperations;
_globalParam= globalParam;
} }
/** /**
* 预生成全局工序列表(按“订单0→订单1→…+订单内工序1→2→…”排序,分配GlobalOpId) * 预生成全局工序列表(按“订单0→订单1→…+订单内工序1→2→…”排序,分配GlobalOpId)
...@@ -257,7 +259,7 @@ int populationSize=param.getPopulationSize(); ...@@ -257,7 +259,7 @@ int populationSize=param.getPopulationSize();
*/ */
private List<Integer> shuffleWithPriority(List<Integer> os) { private List<Integer> shuffleWithPriority(List<Integer> os) {
if (!GlobalParam.IsBreakPriority) { if (!_globalParam.isIsBreakPriority()) {
return new ArrayList<>(os); return new ArrayList<>(os);
} }
......
...@@ -4,6 +4,7 @@ import com.aps.common.util.ProductionDeepCopyUtil; ...@@ -4,6 +4,7 @@ import com.aps.common.util.ProductionDeepCopyUtil;
import com.aps.entity.Algorithm.GAScheduleResult; import com.aps.entity.Algorithm.GAScheduleResult;
import com.aps.entity.Algorithm.ScheduleResultDetail; import com.aps.entity.Algorithm.ScheduleResultDetail;
import com.aps.entity.basic.*; import com.aps.entity.basic.*;
import com.aps.service.plan.AlgorithmScheduler8;
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;
...@@ -37,15 +38,15 @@ public class MachineCalculator { ...@@ -37,15 +38,15 @@ public class MachineCalculator {
* 获取机器下一个可用时间窗口(考虑班次约束) * 获取机器下一个可用时间窗口(考虑班次约束)
*/ */
public List<ScheduleResultDetail> getNextAvailableTime(Machine machine, int proposedStartTime, public List<ScheduleResultDetail> getNextAvailableTime(Machine machine, int proposedStartTime,
int prevtime, double processingTime, int prevtime, int processingTime,
List<GAScheduleResult> existingTasks, List<GAScheduleResult> existingTasks,
boolean isInterrupt, boolean istask, boolean isInterrupt, boolean istask,
boolean islockMachineTime) { boolean islockMachineTime) {
LocalDateTime startTime = baseTime.plus(proposedStartTime, ChronoUnit.MINUTES); LocalDateTime startTime = baseTime.plus(proposedStartTime, ChronoUnit.SECONDS);
String prevtimestr = ""; String prevtimestr = "";
if (prevtime > -1) { if (prevtime > -1) {
prevtimestr = baseTime.plus(prevtime, ChronoUnit.MINUTES) prevtimestr = baseTime.plus(prevtime, ChronoUnit.SECONDS)
.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")); .format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
} }
...@@ -55,54 +56,49 @@ public class MachineCalculator { ...@@ -55,54 +56,49 @@ public class MachineCalculator {
} }
// 查找最早可用开始时间 // 查找最早可用开始时间
private List<ScheduleResultDetail> findEarliestStart(Machine machine, double processingTime,
LocalDateTime currentTime, String prevtime, private List<ScheduleResultDetail> findEarliestStart(
List<GAScheduleResult> existingTasks, Machine machine, int processingTime, LocalDateTime currentTime,
boolean checkprevtime, boolean islockMachineTime) { String prevtime, List<GAScheduleResult> existingTasks, boolean checkprevtime, boolean islockMachineTime
// 获取设备上已有任务 ) {
List<GAScheduleResult> machineTasks = existingTasks.stream() List<GAScheduleResult> machineTasks = existingTasks.stream()
.filter(t -> t.getMachineId() == machine.getId()) .filter(t -> t.getMachineId() == machine.getId())
.sorted(Comparator.comparingInt(GAScheduleResult::getStartTime)) .sorted(Comparator.comparingInt(GAScheduleResult::getStartTime))
.collect(Collectors.toList()); .collect(Collectors.toList());
List<ScheduleResultDetail> times = new ArrayList<>(); List<ScheduleResultDetail> times = new ArrayList<>();
TimeSegment slot =GetCurrentOrNextShift(machine, currentTime, prevtime, checkprevtime); TimeSegment slot = GetCurrentOrNextShift(machine, currentTime, prevtime, checkprevtime);
if (slot == null) return times;
LocalDateTime startCandidate = slot.getStart().isAfter(
(prevtime.isEmpty() ? currentTime : LocalDateTime.parse(prevtime, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")))
) ? slot.getStart() : (prevtime.isEmpty() ? currentTime : LocalDateTime.parse(prevtime, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
LocalDateTime endCandidate = startCandidate.plus((long)processingTime, ChronoUnit.MINUTES); LocalDateTime prevTimeDateTime = StringUtils.isEmpty(prevtime) ? null : LocalDateTime.parse(prevtime);
LocalDateTime startCandidate = slot.getStart().isAfter(prevTimeDateTime != null ? prevTimeDateTime : currentTime)
? slot.getStart()
: (prevTimeDateTime != null ? prevTimeDateTime : currentTime);
LocalDateTime endCandidate = startCandidate.plusSeconds(processingTime);
// 检查是否在可用时间段内
if (endCandidate.isAfter(slot.getEnd())) { if (endCandidate.isAfter(slot.getEnd())) {
// 放不下,继续寻找后续可用时间 return CaldEarliestStart(machine, processingTime, currentTime, prevtime, machineTasks, checkprevtime,islockMachineTime);
return CaldEarliestStart(machine, processingTime, currentTime, prevtime,
machineTasks, checkprevtime, islockMachineTime);
} else { } else {
ScheduleResultDetail time = new ScheduleResultDetail(); ScheduleResultDetail time = new ScheduleResultDetail();
time.setKey(slot.getKey()); time.setKey(slot.getKey());
time.setStartTime((int) ChronoUnit.MINUTES.between(baseTime, startCandidate)); time.setStartTime((int) ChronoUnit.SECONDS.between(baseTime, startCandidate));
time.setEndTime((int) ChronoUnit.MINUTES.between(baseTime, endCandidate)); time.setEndTime((int) ChronoUnit.SECONDS.between(baseTime, endCandidate));
times.add(time); times.add(time);
if(islockMachineTime) {
if (islockMachineTime) {
RemoveMachineAvailable(machine, time); RemoveMachineAvailable(machine, time);
} }
return times; return times;
} }
} }
private List<ScheduleResultDetail> CaldEarliestStart( private List<ScheduleResultDetail> CaldEarliestStart(
Machine machine, double processingTime, LocalDateTime currentTime, Machine machine, int processingTime, LocalDateTime currentTime,
String prevtime, List<GAScheduleResult> machineTasks, boolean checkprevtime, boolean islockMachineTime String prevtime, List<GAScheduleResult> machineTasks, boolean checkprevtime, boolean islockMachineTime
) { ) {
double remainingTime = processingTime; int remainingTime = 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<ScheduleResultDetail> times = new ArrayList<>(); List<ScheduleResultDetail> times = new ArrayList<>();
...@@ -122,7 +118,7 @@ public class MachineCalculator { ...@@ -122,7 +118,7 @@ public class MachineCalculator {
LocalDateTime finalPrevEnd = prevEnd; LocalDateTime finalPrevEnd = prevEnd;
boolean hasTask = machineTasks.stream() boolean hasTask = machineTasks.stream()
.anyMatch(t -> { .anyMatch(t -> {
LocalDateTime taskStart = baseTime.plusMinutes(t.getStartTime()); LocalDateTime taskStart = baseTime.plusSeconds(t.getStartTime());
return taskStart.isAfter(finalPrevEnd) && taskStart.isBefore(shiftStart); return taskStart.isAfter(finalPrevEnd) && taskStart.isBefore(shiftStart);
}); });
...@@ -158,29 +154,34 @@ public class MachineCalculator { ...@@ -158,29 +154,34 @@ public class MachineCalculator {
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 availableSeconds = ChronoUnit.SECONDS.between(effectiveStart, shiftEnd);
// 处理当前班次 // 处理当前班次
double processable = Math.min(remainingTime, (int) availableMinutes); int processable = Math.min(remainingTime, (int) availableSeconds);
remainingTime -= processable; remainingTime -= processable;
currentTime = effectiveStart.plusMinutes((long)processable); currentTime = effectiveStart.plusSeconds(processable);
// 添加时间详情 // 添加时间详情
ScheduleResultDetail time = new ScheduleResultDetail(); ScheduleResultDetail time = new ScheduleResultDetail();
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);
if (islockMachineTime) { if (islockMachineTime) {
// 还原未使用的时间段
RemoveMachineAvailable(machine, time); RemoveMachineAvailable(machine, time);
} }
} }
// 还原未使用的时间段
if (islockMachineTime) { if (islockMachineTime) {
// 还原未使用的时间段 // 还原未使用的时间段
AddMachineAvailable(machine, oldTimes); AddMachineAvailable(machine, oldTimes);
} }
return times; return times;
} }
/** /**
* 获取设备当前或下一个有效班次 * 获取设备当前或下一个有效班次
*/ */
...@@ -196,7 +197,7 @@ public class MachineCalculator { ...@@ -196,7 +197,7 @@ public class MachineCalculator {
if (start == null) { if (start == null) {
// 生成新时间段 // 生成新时间段
List<TimeSegment> timeSegments = machineScheduler.generateTimeSegment(machine, time); List<TimeSegment> timeSegments = machineScheduler.generateTimeSegment(machine, time.plusDays(1));
machine.getAvailability().addAll(timeSegments); machine.getAvailability().addAll(timeSegments);
// 更新设备时间线 // 更新设备时间线
...@@ -215,6 +216,8 @@ public class MachineCalculator { ...@@ -215,6 +216,8 @@ public class MachineCalculator {
return start; return start;
} }
private void RemoveMachineAvailable(Machine machine, ScheduleResultDetail geneDetails) { private void RemoveMachineAvailable(Machine machine, ScheduleResultDetail geneDetails) {
List<TimeSegment> timeSegments = new ArrayList<>(); List<TimeSegment> timeSegments = new ArrayList<>();
...@@ -226,11 +229,11 @@ public class MachineCalculator { ...@@ -226,11 +229,11 @@ public class MachineCalculator {
if (index > -1) { if (index > -1) {
TimeSegment targetSegment = machine.getAvailability().get(index); TimeSegment targetSegment = machine.getAvailability().get(index);
LocalDateTime geneEndTime = baseTime.plusMinutes(geneDetails.getEndTime()); LocalDateTime geneEndTime = baseTime.plusSeconds(geneDetails.getEndTime());
if (targetSegment.getEnd().isAfter(geneEndTime)) { if (targetSegment.getEnd().isAfter(geneEndTime)) {
TimeSegment usedSegment = new TimeSegment(); TimeSegment usedSegment = new TimeSegment();
usedSegment.setStart(baseTime.plusMinutes(geneDetails.getStartTime())); usedSegment.setStart(baseTime.plusSeconds(geneDetails.getStartTime()));
usedSegment.setEnd(geneEndTime); usedSegment.setEnd(geneEndTime);
usedSegment.setHoliday(false); usedSegment.setHoliday(false);
usedSegment.setKey(UUID.randomUUID().toString()); usedSegment.setKey(UUID.randomUUID().toString());
......
...@@ -9,6 +9,7 @@ import org.springframework.util.CollectionUtils; ...@@ -9,6 +9,7 @@ import org.springframework.util.CollectionUtils;
import javax.annotation.PostConstruct; import javax.annotation.PostConstruct;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.time.LocalDate; import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.OffsetDateTime; import java.time.OffsetDateTime;
import java.util.*; import java.util.*;
import java.util.function.Function; import java.util.function.Function;
...@@ -35,7 +36,7 @@ public class OrderSortService { ...@@ -35,7 +36,7 @@ public class OrderSortService {
registerFieldExtractor("dueDate", Order -> { registerFieldExtractor("dueDate", Order -> {
// 直接返回LocalDate,处理null情况 // 直接返回LocalDate,处理null情况
return Optional.ofNullable(Order.getDueDate()) return Optional.ofNullable(Order.getDueDate())
.map(OffsetDateTime::toLocalDate) .map(LocalDateTime::toLocalDate)
.orElse(null); .orElse(null);
}); });
registerFieldExtractor("priority", Order::getPriority); registerFieldExtractor("priority", Order::getPriority);
......
...@@ -324,7 +324,7 @@ public class AlgorithmScheduler6 { ...@@ -324,7 +324,7 @@ public class AlgorithmScheduler6 {
LocalDateTime completionTime = chromosome.getBaseTime().plusMinutes(orderCompletion); LocalDateTime completionTime = chromosome.getBaseTime().plusMinutes(orderCompletion);
// 修复:正确处理OffsetDateTime到LocalDateTime的转换 // 修复:正确处理OffsetDateTime到LocalDateTime的转换
LocalDateTime dueDateTime = order.getDueDate().toLocalDateTime(); LocalDateTime dueDateTime = order.getDueDate();
if (completionTime.isAfter(dueDateTime)) { if (completionTime.isAfter(dueDateTime)) {
// 计算延迟小时数(修复时间计算) // 计算延迟小时数(修复时间计算)
......
...@@ -473,7 +473,7 @@ public class AlgorithmScheduler7 { ...@@ -473,7 +473,7 @@ public class AlgorithmScheduler7 {
if (order != null) { if (order != null) {
LocalDateTime completionTime = chromosome.getBaseTime().plusMinutes(orderCompletion); LocalDateTime completionTime = chromosome.getBaseTime().plusMinutes(orderCompletion);
LocalDateTime dueDateTime = order.getDueDate().toLocalDateTime(); LocalDateTime dueDateTime = order.getDueDate();
if (completionTime.isAfter(dueDateTime)) { if (completionTime.isAfter(dueDateTime)) {
long totalMinutes = java.time.temporal.ChronoUnit.MINUTES.between(dueDateTime, completionTime); long totalMinutes = java.time.temporal.ChronoUnit.MINUTES.between(dueDateTime, completionTime);
......
...@@ -94,7 +94,7 @@ public class AlgorithmScheduler8 { ...@@ -94,7 +94,7 @@ public class AlgorithmScheduler8 {
// 为每个订单分配工序 // 为每个订单分配工序
for (Order order : _orders) { for (Order order : _orders) {
Product product = _products.stream() Product product = _products.stream()
.filter(p -> p.getId() == order.getProductId()) .filter(p -> p.getId()==order.getProductId())
.findFirst() .findFirst()
.orElseThrow(() -> new NoSuchElementException("Product not found: " + order.getProductId())); .orElseThrow(() -> new NoSuchElementException("Product not found: " + order.getProductId()));
...@@ -322,7 +322,7 @@ public class AlgorithmScheduler8 { ...@@ -322,7 +322,7 @@ public class AlgorithmScheduler8 {
// 创建基因 // 创建基因
Gene gene = new Gene(); Gene gene = new Gene();
gene.setOrderId(order.getId()); // gene.setOrderId(order.getId());
gene.setProductId(order.getProductId()); gene.setProductId(order.getProductId());
gene.setOperationId(operation.getId()); gene.setOperationId(operation.getId());
gene.setMachineId(machine.getId()); gene.setMachineId(machine.getId());
...@@ -415,21 +415,21 @@ public class AlgorithmScheduler8 { ...@@ -415,21 +415,21 @@ public class AlgorithmScheduler8 {
.mapToInt(Gene::getEndTime) .mapToInt(Gene::getEndTime)
.max() .max()
.orElse(0); .orElse(0);
Order order = _orders.stream() // Order order = _orders.stream()
.filter(o -> o.getId() == group.getKey()) // .filter(o -> o.getId() == group.getKey())
.findFirst() // .findFirst()
.orElse(null); // .orElse(null);
//
if (order != null) { // if (order != null) {
LocalDateTime completionTime = chromosome.getBaseTime().plusMinutes(orderCompletion); // LocalDateTime completionTime = chromosome.getBaseTime().plusMinutes(orderCompletion);
LocalDateTime dueDateTime = order.getDueDate().toLocalDateTime(); // LocalDateTime dueDateTime = order.getDueDate();
//
if (completionTime.isAfter(dueDateTime)) { // if (completionTime.isAfter(dueDateTime)) {
long hours = ChronoUnit.HOURS.between(dueDateTime, completionTime); // long hours = ChronoUnit.HOURS.between(dueDateTime, completionTime);
long minutes = ChronoUnit.MINUTES.between(dueDateTime, completionTime) % 60; // long minutes = ChronoUnit.MINUTES.between(dueDateTime, completionTime) % 60;
tardiness += hours + (double) minutes / 60; // tardiness += hours + (double) minutes / 60;
} // }
} // }
} }
// 3. 总换型时间 // 3. 总换型时间
......
...@@ -206,7 +206,12 @@ public class MachineSchedulerService { ...@@ -206,7 +206,12 @@ public class MachineSchedulerService {
&& s.getDays() != null && s.getDays() != null
&& containsDay(s.getDays(), date.getDayOfWeek())) && containsDay(s.getDays(), date.getDayOfWeek()))
.collect(Collectors.toList()); .collect(Collectors.toList());
if(shifts==null||shifts.size()==0) {
shifts = machine.getShifts().stream()
.filter(s -> s.getDays() != null
&& containsDay(s.getDays(), date.getDayOfWeek()))
.collect(Collectors.toList());
}
for (Shift shift : shifts) { for (Shift shift : shifts) {
LocalDateTime shiftStart = date.atTime(shift.getStartTime()); LocalDateTime shiftStart = date.atTime(shift.getStartTime());
LocalDateTime shiftEnd = shift.getEndTime().isBefore(shift.getStartTime()) ? LocalDateTime shiftEnd = shift.getEndTime().isBefore(shift.getStartTime()) ?
...@@ -247,6 +252,12 @@ public class MachineSchedulerService { ...@@ -247,6 +252,12 @@ public class MachineSchedulerService {
} }
private List<TimeSegment> mergeSegments(List<TimeSegment> segments) { private List<TimeSegment> mergeSegments(List<TimeSegment> segments) {
if(segments==null||segments.size()==0)
{
return null;
}
List<TimeSegment> maintenanceSegments = segments.stream() List<TimeSegment> maintenanceSegments = segments.stream()
.filter(t -> t.getType() == SegmentType.MAINTENANCE) .filter(t -> t.getType() == SegmentType.MAINTENANCE)
.collect(Collectors.toList()); .collect(Collectors.toList());
......
...@@ -69,7 +69,7 @@ class OrderSortServiceTest { ...@@ -69,7 +69,7 @@ class OrderSortServiceTest {
order.setProductId(100 + i); order.setProductId(100 + i);
order.setQuantity(50.0 * i); order.setQuantity(50.0 * i);
order.setPriority(15 - i); // 优先级:5,4,3,2,1(倒序) order.setPriority(15 - i); // 优先级:5,4,3,2,1(倒序)
order.setDueDate(OffsetDateTime.now().plusDays(i)); // 到期日递增 //order.setDueDate(OffsetDateTime.now().plusDays(i)); // 到期日递增
order.setTardiness(i * 0.5); order.setTardiness(i * 0.5);
order.setCanSplit(i % 2 == 0); order.setCanSplit(i % 2 == 0);
order.setCanInterrupt(i % 3 == 0); order.setCanInterrupt(i % 3 == 0);
......
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