Commit a0c8a9c1 authored by Tong Li's avatar Tong Li

重叠

parent ff8e1628
...@@ -16,7 +16,7 @@ public class ScheduleResultDetail { ...@@ -16,7 +16,7 @@ public class ScheduleResultDetail {
private int EndTime; // 相对结束时间(秒) private int EndTime; // 相对结束时间(秒)
private double OneTime; // 单件工时 private double OneTime; // 单件工时
private double Quantity; // 时间段 private double Quantity; // 时间段
private double efficiency=1;//效率
private List<TimeSegment> usedSegment; private List<TimeSegment> usedSegment;
......
...@@ -10,6 +10,7 @@ import com.aps.service.plan.MachineSchedulerService; ...@@ -10,6 +10,7 @@ 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.math.BigDecimal;
import java.math.RoundingMode;
import java.time.Duration; import java.time.Duration;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter; import java.time.format.DateTimeFormatter;
...@@ -272,7 +273,7 @@ public class MachineCalculator { ...@@ -272,7 +273,7 @@ public class MachineCalculator {
String prevtime, CopyOnWriteArrayList<GAScheduleResult> existingTasks,double oneTime,double quantity, boolean checkprevtime, boolean islockMachineTime String prevtime, CopyOnWriteArrayList<GAScheduleResult> existingTasks,double oneTime,double quantity, boolean checkprevtime, boolean islockMachineTime
,boolean isInterrupt) { ,boolean isInterrupt) {
CopyOnWriteArrayList<GAScheduleResult> machineTasks=null; CopyOnWriteArrayList<GAScheduleResult> machineTasks=null;
if(existingTasks!=null) { if(existingTasks!=null&&existingTasks.size()>0) {
machineTasks = existingTasks.stream() 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))
...@@ -506,6 +507,7 @@ public class MachineCalculator { ...@@ -506,6 +507,7 @@ public class MachineCalculator {
CopyOnWriteArrayList<ScheduleResultDetail> times = new CopyOnWriteArrayList<>(); CopyOnWriteArrayList<ScheduleResultDetail> times = new CopyOnWriteArrayList<>();
//第一个数据
TimeSegment shiftfrist= timeSegments.get(0); TimeSegment shiftfrist= timeSegments.get(0);
Map<Integer, Object> outMap= CreateScheduleResultDetail(shiftfrist,st,remainingTime,oneTime); Map<Integer, Object> outMap= CreateScheduleResultDetail(shiftfrist,st,remainingTime,oneTime);
...@@ -517,7 +519,7 @@ public class MachineCalculator { ...@@ -517,7 +519,7 @@ public class MachineCalculator {
usedSegments.addAll(usedSegments1); usedSegments.addAll(usedSegments1);
} }
// 计算有效时间 // 计算有效时间
//中间的数据
CopyOnWriteArrayList<TimeSegment> timeSegments2= new CopyOnWriteArrayList<>(timeSegments.subList(1,timeSegments.size()-1)); CopyOnWriteArrayList<TimeSegment> timeSegments2= new CopyOnWriteArrayList<>(timeSegments.subList(1,timeSegments.size()-1));
...@@ -531,7 +533,14 @@ public class MachineCalculator { ...@@ -531,7 +533,14 @@ public class MachineCalculator {
time.setKey(UUID.randomUUID().toString()); time.setKey(UUID.randomUUID().toString());
time.setStartTime((int) ChronoUnit.SECONDS.between(baseTime, effectiveStart)); time.setStartTime((int) ChronoUnit.SECONDS.between(baseTime, effectiveStart));
time.setEndTime((int) ChronoUnit.SECONDS.between(baseTime, effectiveend)); time.setEndTime((int) ChronoUnit.SECONDS.between(baseTime, effectiveend));
time.setQuantity((int)(processable/oneTime));
BigDecimal bd = new BigDecimal(String.valueOf(processable/oneTime));
BigDecimal roundedBd = bd.setScale(4, RoundingMode.HALF_UP);
time.setQuantity(roundedBd.doubleValue());
time.setOneTime(oneTime); time.setOneTime(oneTime);
time.setUsedSegment(timeSegments2); time.setUsedSegment(timeSegments2);
timeSegments2.forEach(t->t.setUsed(true)); timeSegments2.forEach(t->t.setUsed(true));
...@@ -540,7 +549,7 @@ public class MachineCalculator { ...@@ -540,7 +549,7 @@ public class MachineCalculator {
times.add(time); times.add(time);
//最后的时间段
TimeSegment shiftlast= timeSegments.get(timeSegments.size()-1); TimeSegment shiftlast= timeSegments.get(timeSegments.size()-1);
Map<Integer, Object> outMaplast= CreateScheduleResultDetail(shiftlast,st,remainingTime,oneTime); Map<Integer, Object> outMaplast= CreateScheduleResultDetail(shiftlast,st,remainingTime,oneTime);
...@@ -586,7 +595,12 @@ public class MachineCalculator { ...@@ -586,7 +595,12 @@ public class MachineCalculator {
time.setStartTime(Math.abs ((int) ChronoUnit.SECONDS.between(baseTime, effectiveStart))); time.setStartTime(Math.abs ((int) ChronoUnit.SECONDS.between(baseTime, effectiveStart)));
time.setEndTime(Math.abs ((int) ChronoUnit.SECONDS.between(baseTime, currentTime))); time.setEndTime(Math.abs ((int) ChronoUnit.SECONDS.between(baseTime, currentTime)));
time.setQuantity((int)(processable/oneTime)); time.setEfficiency(shift.getEfficiency());
BigDecimal bd = new BigDecimal(String.valueOf(processable/oneTime));
BigDecimal roundedBd = bd.setScale(4, RoundingMode.HALF_UP);
time.setQuantity(roundedBd.doubleValue());
time.setOneTime(oneTime); time.setOneTime(oneTime);
Map<Integer, Object> outMap=new HashMap<>(); Map<Integer, Object> outMap=new HashMap<>();
outMap.put(1, remainingTime); outMap.put(1, remainingTime);
...@@ -737,7 +751,7 @@ public class MachineCalculator { ...@@ -737,7 +751,7 @@ public class MachineCalculator {
if (currentTotal >= requiredMinutes) { if (currentTotal >= requiredMinutes) {
// ✔️ 总时长满足,尝试往前减索引,找「最小满足索引」(减少后续裁剪的工作量) // 总时长满足,尝试往前减索引,找「最小满足索引」(减少后续裁剪的工作量)
if (targetIndex > 0) { if (targetIndex > 0) {
double prevTotal = calculateTotalMinutesByIndex(availableSegments, currentTime, targetIndex - 1); double prevTotal = calculateTotalMinutesByIndex(availableSegments, currentTime, targetIndex - 1);
if (prevTotal >= requiredMinutes) { if (prevTotal >= requiredMinutes) {
...@@ -750,7 +764,7 @@ public class MachineCalculator { ...@@ -750,7 +764,7 @@ public class MachineCalculator {
double syday= (int)Math.ceil((requiredMinutes-currentTotal)/(double) ONE_DAY_MINUTES); double syday= (int)Math.ceil((requiredMinutes-currentTotal)/(double) ONE_DAY_MINUTES);
// 总时长不足,往后加索引(每次加5,大步前进,加快逼近速度) // 总时长不足,往后加索引(每次加5,大步前进,加快逼近速度)
targetIndex +=Math.max(syday, 5); targetIndex +=Math.max(syday, 5);
if (targetIndex >= totalSegmentCount) { if (targetIndex >= totalSegmentCount) {
// 所有片段总时长不足,抛出异常 // 所有片段总时长不足,抛出异常
...@@ -1026,6 +1040,7 @@ public class MachineCalculator { ...@@ -1026,6 +1040,7 @@ public class MachineCalculator {
LocalDateTime taskStart = baseTime.plusSeconds(t.getStartTime()); LocalDateTime taskStart = baseTime.plusSeconds(t.getStartTime());
return taskStart.isAfter(finalPrevEnd) && taskStart.isBefore(shiftStart); return taskStart.isAfter(finalPrevEnd) && taskStart.isBefore(shiftStart);
}); });
if (!hasTask) { if (!hasTask) {
// 检查班次间维修窗口 // 检查班次间维修窗口
if (machine.getMaintenanceWindows() != null) { if (machine.getMaintenanceWindows() != null) {
...@@ -1107,9 +1122,9 @@ public class MachineCalculator { ...@@ -1107,9 +1122,9 @@ public class MachineCalculator {
if (slot == null) { if (slot == null) {
return null; return null;
} }
int processingTime1=(int)Math.ceil( processingTime/slot.getEfficiency());
// 计算候选开始/结束时间(当前时间往前推加工时长) // 计算候选开始/结束时间(当前时间往前推加工时长)
LocalDateTime startCandidate = currentTime.minusSeconds(processingTime); LocalDateTime startCandidate = currentTime.minusSeconds(processingTime1);
LocalDateTime endCandidate = currentTime; LocalDateTime endCandidate = currentTime;
// 检查是否在可用时间段内 // 检查是否在可用时间段内
...@@ -1225,8 +1240,8 @@ public class MachineCalculator { ...@@ -1225,8 +1240,8 @@ public class MachineCalculator {
.filter(t -> baseTime.plusSeconds(t.getStartTime()).isAfter(shiftStart) .filter(t -> baseTime.plusSeconds(t.getStartTime()).isAfter(shiftStart)
&& baseTime.plusSeconds(t.getStartTime()).isBefore(finalPrevEnd)) && baseTime.plusSeconds(t.getStartTime()).isBefore(finalPrevEnd))
.findFirst(); .findFirst();
boolean hasTask= CheckTask( machine, machineTasks, prevEnd, shiftStart);
if (task.isPresent()) { if (hasTask) {
// 班次间有任务,重置状态重新查找 // 班次间有任务,重置状态重新查找
currentTime = shiftStart; currentTime = shiftStart;
remainingTime = processingTime; remainingTime = processingTime;
...@@ -1236,23 +1251,6 @@ public class MachineCalculator { ...@@ -1236,23 +1251,6 @@ public class MachineCalculator {
} }
} }
// 检查维护窗口
if (machine.getMaintenanceWindows() != null && !machine.getMaintenanceWindows().isEmpty()) {
LocalDateTime finalPrevEnd = prevEnd;
Optional<MaintenanceWindow> maintenanceTask = machine.getMaintenanceWindows().stream()
.filter(t -> t.getStartTime().isAfter(shiftStart)
&& t.getStartTime().isBefore(finalPrevEnd))
.findFirst();
if (maintenanceTask.isPresent()) {
// 班次间有维护任务,重置状态重新查找
currentTime = shiftStart;
remainingTime = processingTime;
prevEnd = LocalDateTime.of(2000, 1, 1, 0, 0);
times.clear();
continue;
}
}
} }
// 调整班次有效结束时间(不超过当前时间) // 调整班次有效结束时间(不超过当前时间)
...@@ -1262,11 +1260,14 @@ public class MachineCalculator { ...@@ -1262,11 +1260,14 @@ public class MachineCalculator {
Duration availableDuration = Duration.between(shiftStart, effectiveEnd); Duration availableDuration = Duration.between(shiftStart, effectiveEnd);
long availableMinutes = availableDuration.getSeconds(); long availableMinutes = availableDuration.getSeconds();
// 当前班次可处理的时长(不超过剩余需要的时长) // 当前班次可处理的时长(不超过剩余需要的时长)
int processableMinutes = (int) Math.min(remainingTime, availableMinutes); int processableMinutes = (int) Math.min(remainingTime, availableMinutes);
long availableSeconds_e =Math.round(processableMinutes/shift.getEfficiency()) ;
// 计算当前班次的有效开始时间 // 计算当前班次的有效开始时间
LocalDateTime effectiveStart = effectiveEnd.minusSeconds(processableMinutes); LocalDateTime effectiveStart = effectiveEnd.minusSeconds(availableSeconds_e);
prevEnd = effectiveStart; // 更新上一班次结束时间 prevEnd = effectiveStart; // 更新上一班次结束时间
remainingTime -= processableMinutes; // 剩余时长递减 remainingTime -= processableMinutes; // 剩余时长递减
currentTime = effectiveStart; // 更新当前时间,继续循环 currentTime = effectiveStart; // 更新当前时间,继续循环
......
...@@ -98,12 +98,12 @@ public class RoutingDataService { ...@@ -98,12 +98,12 @@ public class RoutingDataService {
Map<Integer, Object> list=new HashMap<>(); Map<Integer, Object> list=new HashMap<>();
List<String> soutceExecId = ProdOrderProcesss.stream() List<String> soutceExecId = ProdOrderProcesss.stream()
.map(ProdOrderProcess::getExecId) .map(ProdOrderProcess::getExecId)
.distinct() // 提取Exec_ID // .distinct() // 提取Exec_ID
.collect(Collectors.toList()); .collect(Collectors.toList());
List<String> targetExecId = ProdOrderProcesss.stream() List<String> targetExecId = ProdOrderProcesss.stream()
.map(ProdOrderProcess::getTargetExecId) .map(ProdOrderProcess::getTargetExecId)
.distinct() // 提取TARGET_Exec_ID // .distinct() // 提取TARGET_Exec_ID
.collect(Collectors.toList()); .collect(Collectors.toList());
List<String> ExecIdNoChild= ProdProcessExecs.stream() List<String> ExecIdNoChild= ProdProcessExecs.stream()
......
...@@ -42,7 +42,7 @@ public class PlanResultServiceTest { ...@@ -42,7 +42,7 @@ public class PlanResultServiceTest {
// planResultService.execute2("5475E00B844847ACB6DC20227967BA2F"); // planResultService.execute2("5475E00B844847ACB6DC20227967BA2F");
// planResultService.execute2("00E0C5D3E4AD4F36B56C39395906618D"); // planResultService.execute2("00E0C5D3E4AD4F36B56C39395906618D");
planResultService.execute2("92BB773E1E2447C99D8176C991D5C9D2"); // planResultService.execute2("92BB773E1E2447C99D8176C991D5C9D2");
// planResultService.execute2("265F24B6DF3C40E4B17D193B0CC8AAF2"); // planResultService.execute2("265F24B6DF3C40E4B17D193B0CC8AAF2");
// LocalDateTime t= LocalDateTime.of(2026, 02, 14, 1, 25, 52); // LocalDateTime t= LocalDateTime.of(2026, 02, 14, 1, 25, 52);
// List<Integer> opids=new ArrayList<>();//BCA6FA43FFA444D3952CF8F6E1EA291B // List<Integer> opids=new ArrayList<>();//BCA6FA43FFA444D3952CF8F6E1EA291B
...@@ -56,7 +56,7 @@ public class PlanResultServiceTest { ...@@ -56,7 +56,7 @@ public class PlanResultServiceTest {
// maintenanceWindow.setEndTime(LocalDateTime.of(2025, 9, 19, 0, 0, 0)); // maintenanceWindow.setEndTime(LocalDateTime.of(2025, 9, 19, 0, 0, 0));
// planResultService.AddMaintenanceWindow("5475E00B844847ACB6DC20227967BA2F",2488l,maintenanceWindow); // planResultService.AddMaintenanceWindow("5475E00B844847ACB6DC20227967BA2F",2488l,maintenanceWindow);
// // planResultService.DelOperation("B6AE363FF5044DDF8DECE32D5FE0F7EA",7); // // planResultService.DelOperation("B6AE363FF5044DDF8DECE32D5FE0F7EA",7);
planResultService.SpiltOperation("92BB773E1E2447C99D8176C991D5C9D2",1,new Double[]{50d, 50d});
// planResultService.SpiltOrder("A41D662EE0764D008173C5A0E42B15F6","5f9d5383-b89a-4a4f-8805-2f617c711968",new Double[]{500d, 500d}); // planResultService.SpiltOrder("A41D662EE0764D008173C5A0E42B15F6","5f9d5383-b89a-4a4f-8805-2f617c711968",new Double[]{500d, 500d});
} }
......
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