Commit 34d7e700 authored by Tong Li's avatar Tong Li

优化速度

parent 993afbe6
package com.aps.entity.Algorithm; package com.aps.entity.Algorithm;
import com.aps.entity.basic.TimeSegment;
import lombok.Data; import lombok.Data;
import java.util.List;
/** /**
* 作者:佟礼 * 作者:佟礼
* 时间:2025-11-21 * 时间:2025-11-21
...@@ -14,6 +17,9 @@ public class ScheduleResultDetail { ...@@ -14,6 +17,9 @@ public class ScheduleResultDetail {
private double OneTime; // 单件工时 private double OneTime; // 单件工时
private double Quantity; // 时间段 private double Quantity; // 时间段
private List<TimeSegment> usedSegment;
// Key 的 getter/setter // Key 的 getter/setter
public String getKey() { public String getKey() {
return Key; return Key;
......
...@@ -374,6 +374,7 @@ if(finishedOrder==null||finishedOrder.size()==0) ...@@ -374,6 +374,7 @@ if(finishedOrder==null||finishedOrder.size()==0)
int teardownTime = machineOption.getTeardownTime(); int teardownTime = machineOption.getTeardownTime();
int preTime = machineOption.getPreTime(); int preTime = machineOption.getPreTime();
int setupTime = calculateSetupTime(chromosome.getResult(), operation, machine, machineOption); int setupTime = calculateSetupTime(chromosome.getResult(), operation, machine, machineOption);
......
...@@ -92,7 +92,7 @@ public class MachineCalculator { ...@@ -92,7 +92,7 @@ public class MachineCalculator {
time.setQuantity(quantity); time.setQuantity(quantity);
times.add(time); times.add(time);
if(islockMachineTime) { if(islockMachineTime) {
RemoveMachineAvailable(machine, time); RemoveMachineAvailable(machine, time,slot);
} }
return times; return times;
} }
...@@ -159,7 +159,7 @@ public class MachineCalculator { ...@@ -159,7 +159,7 @@ public class MachineCalculator {
times.add(time); times.add(time);
if (islockMachineTime) { if (islockMachineTime) {
// 还原未使用的时间段 // 还原未使用的时间段
RemoveMachineAvailable(machine, time); RemoveMachineAvailable(machine, time,shift);
} }
} }
...@@ -183,10 +183,81 @@ public class MachineCalculator { ...@@ -183,10 +183,81 @@ public class MachineCalculator {
List<ScheduleResultDetail> oldTimes = new ArrayList<>(); List<ScheduleResultDetail> oldTimes = new ArrayList<>();
List<TimeSegment> timeSegments= findAvailableSegments(machine, currentTime, machineTasks, remainingTime, isInterrupt); List<TimeSegment> timeSegments= findAvailableSegments(machine, currentTime, machineTasks, remainingTime, isInterrupt);
int estimateIndex= (int) Math.ceil(remainingTime / (double) ONE_DAY_MINUTES);
List<TimeSegment> timeSegments1=null;
if(estimateIndex>10)
{
timeSegments1= getEnoughSegmentsByEstimateIndex(timeSegments,currentTime,remainingTime);
}
int i=0; if(timeSegments1==null) {
int i = 0;
while (remainingTime > 0) { while (remainingTime > 0) {
TimeSegment shift= timeSegments.get(i); TimeSegment shift = timeSegments.get(i);
Map<Integer, Object> outMap = CreateScheduleResultDetail(shift, st, remainingTime, oneTime);
remainingTime = (int) outMap.get(1);
ScheduleResultDetail time = (ScheduleResultDetail) outMap.get(2);
times.add(time);
// 还原未使用的时间段
RemoveMachineAvailable(machine, time,shift);
i++;
}
}else {
times= CaldScheduleResultDetail(timeSegments1,machine,st,remainingTime,oneTime);
}
return times;
}
private List<ScheduleResultDetail> CaldScheduleResultDetail(List<TimeSegment> timeSegments,Machine machine,LocalDateTime st,int remainingTime,double oneTime)
{
int processable1 =(int)calculateTotalAvailableSecond(timeSegments, st);
List<ScheduleResultDetail> times = new ArrayList<>();
TimeSegment shiftfrist= timeSegments.get(0);
Map<Integer, Object> outMap= CreateScheduleResultDetail(shiftfrist,st,remainingTime,oneTime);
remainingTime=(int)outMap.get(1);
ScheduleResultDetail time1=(ScheduleResultDetail)outMap.get(2);
times.add(time1);
RemoveMachineAvailable(machine, time1,shiftfrist);
// 计算有效时间
List<TimeSegment> timeSegments2= timeSegments.subList(1,timeSegments.size()-1);
LocalDateTime effectiveStart=timeSegments2.get(0).getStart();
LocalDateTime effectiveend=timeSegments2.get(timeSegments2.size()-1).getEnd();
int processable =(int)calculateTotalAvailableSecond(timeSegments2, st);
ScheduleResultDetail time = new ScheduleResultDetail();
time.setKey(UUID.randomUUID().toString());
time.setStartTime((int) ChronoUnit.SECONDS.between(baseTime, effectiveStart));
time.setEndTime((int) ChronoUnit.SECONDS.between(baseTime, effectiveend));
time.setQuantity((int)(processable/oneTime));
time.setOneTime(oneTime);
time.setUsedSegment(timeSegments2);
timeSegments2.forEach(t->t.setUsed(true));
remainingTime-=processable;
times.add(time);
TimeSegment shiftlast= timeSegments.get(timeSegments.size()-1);
Map<Integer, Object> outMaplast= CreateScheduleResultDetail(shiftlast,st,remainingTime,oneTime);
remainingTime=(int)outMaplast.get(1);
ScheduleResultDetail timelast=(ScheduleResultDetail)outMaplast.get(2);
times.add(timelast);
RemoveMachineAvailable(machine, timelast,shiftlast);
return times;
}
private Map<Integer, Object> CreateScheduleResultDetail(TimeSegment shift,LocalDateTime st,int remainingTime,double oneTime)
{
LocalDateTime shiftStart = shift.getStart(); LocalDateTime shiftStart = shift.getStart();
LocalDateTime shiftEnd = shift.getEnd(); LocalDateTime shiftEnd = shift.getEnd();
...@@ -199,7 +270,9 @@ public class MachineCalculator { ...@@ -199,7 +270,9 @@ public class MachineCalculator {
// 处理当前班次 // 处理当前班次
int processable = Math.min(remainingTime, (int) availableSeconds_e); int processable = Math.min(remainingTime, (int) availableSeconds_e);
remainingTime -= processable; remainingTime -= processable;
currentTime = effectiveStart.plusSeconds(availableSeconds/availableSeconds_e*processable); double e= (double)availableSeconds/availableSeconds_e*processable;
LocalDateTime currentTime = effectiveStart.plusSeconds((int)Math.ceil(e));
// 添加时间详情 // 添加时间详情
ScheduleResultDetail time = new ScheduleResultDetail(); ScheduleResultDetail time = new ScheduleResultDetail();
...@@ -208,16 +281,12 @@ public class MachineCalculator { ...@@ -208,16 +281,12 @@ public class MachineCalculator {
time.setEndTime((int) ChronoUnit.SECONDS.between(baseTime, currentTime)); time.setEndTime((int) ChronoUnit.SECONDS.between(baseTime, currentTime));
time.setQuantity((int)(processable/oneTime)); time.setQuantity((int)(processable/oneTime));
time.setOneTime(oneTime); time.setOneTime(oneTime);
times.add(time); Map<Integer, Object> outMap=new HashMap<>();
outMap.put(1, remainingTime);
// 还原未使用的时间段 outMap.put(2, time);
RemoveMachineAvailable(machine, time); return outMap;
i++;
} }
return times;
}
/** /**
* 查找满足时长要求的无冲突可用时段 * 查找满足时长要求的无冲突可用时段
...@@ -320,7 +389,7 @@ i++; ...@@ -320,7 +389,7 @@ i++;
} }
} }
private static final int ONE_DAY_MINUTES = 24 * 60; // 固定锚点:一天1440分钟,永不改变 private static final int ONE_DAY_MINUTES = 24 * 60*60; // 固定锚点:一天1440分钟,永不改变
/** /**
* 按预估索引快速获取满足时长的时段数组 * 按预估索引快速获取满足时长的时段数组
...@@ -330,7 +399,7 @@ i++; ...@@ -330,7 +399,7 @@ i++;
* @return 刚好满足时长的片段数组 * @return 刚好满足时长的片段数组
* @throws IllegalArgumentException 总时长不足时抛出 * @throws IllegalArgumentException 总时长不足时抛出
*/ */
public TimeSegment[] getEnoughSegmentsByEstimateIndex( public List<TimeSegment> getEnoughSegmentsByEstimateIndex(
List<TimeSegment> availableSegments, List<TimeSegment> availableSegments,
LocalDateTime currentTime, LocalDateTime currentTime,
int requiredMinutes) { int requiredMinutes) {
...@@ -339,7 +408,7 @@ i++; ...@@ -339,7 +408,7 @@ i++;
throw new IllegalArgumentException("可用时段列表不能为空"); throw new IllegalArgumentException("可用时段列表不能为空");
} }
if (requiredMinutes <= 0) { if (requiredMinutes <= 0) {
return new TimeSegment[0]; return null;
} }
int totalSegmentCount = availableSegments.size(); int totalSegmentCount = availableSegments.size();
...@@ -371,8 +440,11 @@ i++; ...@@ -371,8 +440,11 @@ i++;
} }
break; // 找到最小满足索引,退出循环 break; // 找到最小满足索引,退出循环
} else { } else {
double syday= (int)Math.ceil((requiredMinutes-currentTotal)/(double) ONE_DAY_MINUTES);
// ❌ 总时长不足,往后加索引(每次加5,大步前进,加快逼近速度) // ❌ 总时长不足,往后加索引(每次加5,大步前进,加快逼近速度)
targetIndex += 5; targetIndex +=Math.max(syday, 5);
if (targetIndex >= totalSegmentCount) { if (targetIndex >= totalSegmentCount) {
// 所有片段总时长不足,抛出异常 // 所有片段总时长不足,抛出异常
double allTotal = calculateTotalMinutesByIndex(availableSegments, currentTime, totalSegmentCount - 1); double allTotal = calculateTotalMinutesByIndex(availableSegments, currentTime, totalSegmentCount - 1);
...@@ -388,7 +460,7 @@ i++; ...@@ -388,7 +460,7 @@ i++;
} }
else if(allTotal==requiredMinutes) else if(allTotal==requiredMinutes)
{ {
return availableSegments.toArray(new TimeSegment[0]); return availableSegments;
}else { }else {
return null; return null;
} }
...@@ -398,7 +470,7 @@ i++; ...@@ -398,7 +470,7 @@ i++;
// ========== 步骤3:精准裁剪片段,返回最终结果 ========== // ========== 步骤3:精准裁剪片段,返回最终结果 ==========
List<TimeSegment> resultList = availableSegments.subList(0,targetIndex); List<TimeSegment> resultList = availableSegments.subList(0,targetIndex);
return resultList.toArray(new TimeSegment[0]); return resultList;
} }
/** /**
...@@ -904,7 +976,43 @@ i++; ...@@ -904,7 +976,43 @@ i++;
return times; return times;
} }
private void RemoveMachineAvailable(Machine machine, ScheduleResultDetail geneDetails) { private void RemoveMachineAvailable(Machine machine, ScheduleResultDetail geneDetails,TimeSegment targetSegment) {
// 关键修复2:加锁(若多线程访问),避免并发修改
synchronized (machine.getAvailability()) {
List<TimeSegment> availabilitySnapshot = new ArrayList<>(machine.getAvailability());
LocalDateTime geneEndTime = baseTime.plusSeconds(geneDetails.getEndTime());
if (targetSegment.getEnd().isAfter(geneEndTime)) {
TimeSegment usedSegment = new TimeSegment();
usedSegment.setStart(baseTime.plusSeconds(geneDetails.getStartTime()));
usedSegment.setEnd(geneEndTime);
usedSegment.setHoliday(false);
usedSegment.setKey(UUID.randomUUID().toString());
usedSegment.setType(SegmentType.REGULAR);
usedSegment.setUsed(true);
availabilitySnapshot.add(usedSegment);
geneDetails.setKey(usedSegment.getKey());
targetSegment.setStart(geneEndTime);
} else {
targetSegment.setUsed(true);
}
availabilitySnapshot.sort(Comparator.comparing(TimeSegment::getStart));
machine.setAvailability(availabilitySnapshot);
}
}
private void RemoveMachineAvailable1(Machine machine, ScheduleResultDetail geneDetails) {
List<TimeSegment> timeSegments = new ArrayList<>(); List<TimeSegment> timeSegments = new ArrayList<>();
List<TimeSegment> availabilitySnapshot = new ArrayList<>(machine.getAvailability()); List<TimeSegment> availabilitySnapshot = new ArrayList<>(machine.getAvailability());
...@@ -946,15 +1054,46 @@ i++; ...@@ -946,15 +1054,46 @@ i++;
} }
public void AddMachineAvailable(Machine machine, List<ScheduleResultDetail> geneDetails) { public void AddMachineAvailable(Machine machine, List<ScheduleResultDetail> geneDetails) {
if (geneDetails == null || geneDetails.isEmpty()) return;
synchronized (machine.getAvailability()) {
List<String> keys= geneDetails.stream().
filter(t->t.getUsedSegment()==null||t.getUsedSegment().size()==0)
.map(ScheduleResultDetail::getKey)
.collect(Collectors.toList());
List<String> keys1= geneDetails.stream().
filter(t->t.getUsedSegment()!=null)
.flatMap(detail -> detail.getUsedSegment().stream())
.map(TimeSegment::getKey).collect(Collectors.toList());
if(keys1!=null&&keys1.size()>0) {
keys.addAll(keys1);
}
machine.getAvailability().stream()
.filter(t ->keys.contains(t.getKey()))
.forEach(t->t.setUsed(false));
}
}
public void AddMachineAvailable1(Machine machine, List<ScheduleResultDetail> geneDetails) {
if (geneDetails == null || geneDetails.isEmpty()) return; if (geneDetails == null || geneDetails.isEmpty()) return;
List<TimeSegment> availabilitySnapshot = new ArrayList<>(machine.getAvailability()); List<TimeSegment> availabilitySnapshot = new ArrayList<>(machine.getAvailability());
for (ScheduleResultDetail detail : geneDetails) { for (ScheduleResultDetail detail : geneDetails) {
if(detail.getUsedSegment()!=null&&detail.getUsedSegment().size()>0)
{
List<TimeSegment> availabilitySnapshot1= detail.getUsedSegment();
availabilitySnapshot1.forEach(t->t.setUsed(false));
}else {
availabilitySnapshot.stream() availabilitySnapshot.stream()
.filter(t -> t.getKey().equals(detail.getKey())) .filter(t -> t.getKey().equals(detail.getKey()))
.findFirst() .findFirst()
.ifPresent(t -> t.setUsed(false)); .ifPresent(t -> t.setUsed(false));
} }
}
availabilitySnapshot= MergeSegments(availabilitySnapshot); availabilitySnapshot= MergeSegments(availabilitySnapshot);
synchronized (machine.getAvailability()) { synchronized (machine.getAvailability()) {
machine.setAvailability(availabilitySnapshot); machine.setAvailability(availabilitySnapshot);
......
...@@ -97,7 +97,8 @@ public class PlanResultService { ...@@ -97,7 +97,8 @@ public class PlanResultService {
@Autowired @Autowired
private MaterialInfoMapper materialInfoMapper; private MaterialInfoMapper materialInfoMapper;
@Autowired
private MaterialPurchaseMapper materialPurchaseMapper;
@Autowired @Autowired
private StockMapper stockMapper; private StockMapper stockMapper;
...@@ -1137,14 +1138,19 @@ private GlobalParam InitGlobalParam() ...@@ -1137,14 +1138,19 @@ private GlobalParam InitGlobalParam()
public List<Material> getMaterials(){ public List<Material> getMaterials(){
List<Material> materials=new ArrayList<>(); List<Material> materials=new ArrayList<>();
System.out.println("开始初始化物料数据");
LambdaQueryWrapper<MaterialInfo> MaterialInfoWrapper = new LambdaQueryWrapper<>(); LambdaQueryWrapper<MaterialInfo> MaterialInfoWrapper = new LambdaQueryWrapper<>();
MaterialInfoWrapper.eq(MaterialInfo::getIsdeleted,0); MaterialInfoWrapper.eq(MaterialInfo::getIsdeleted,0);
List<MaterialInfo> materiallist=materialInfoMapper.selectList(MaterialInfoWrapper); List<MaterialInfo> materiallist=materialInfoMapper.selectList(MaterialInfoWrapper);
LambdaQueryWrapper<MaterialPurchase> materialPurchaseWrapper= new LambdaQueryWrapper<>();
materialPurchaseWrapper.eq(MaterialPurchase::getIsdeleted,0);
List<MaterialPurchase> MaterialPurchaselist=materialPurchaseMapper.selectList(materialPurchaseWrapper);
System.out.println("开始初始化物料数据");
LambdaQueryWrapper<Stock> StockWrapper = new LambdaQueryWrapper<>(); LambdaQueryWrapper<Stock> StockWrapper = new LambdaQueryWrapper<>();
StockWrapper.eq(Stock::getIsdeleted,0); StockWrapper.eq(Stock::getIsdeleted,0);
......
...@@ -38,13 +38,13 @@ public class PlanResultServiceTest { ...@@ -38,13 +38,13 @@ public class PlanResultServiceTest {
// nsgaiiUtils.Test(); // nsgaiiUtils.Test();
//planResultService.execute2("C5FB5EF2A7334A0A92F826F4937E1008"); //planResultService.execute2("C5FB5EF2A7334A0A92F826F4937E1008");
// planResultService.execute2("726D4C1A712B4B1393175BD44B775B66"); planResultService.execute2("726D4C1A712B4B1393175BD44B775B66");
planResultService.execute2("BCA6FA43FFA444D3952CF8F6E1EA291B"); // planResultService.execute2("BCA6FA43FFA444D3952CF8F6E1EA291B");
// LocalDateTime t= LocalDateTime.of(2025, 11, 15, 6, 51, 11); // LocalDateTime t= LocalDateTime.of(2025, 11, 15, 6, 51, 11);
// List<Integer> opids=new ArrayList<>(); // List<Integer> opids=new ArrayList<>();
// opids.add(1); // opids.add(1);
// planResultService.Move("B571EF6682DB463AB2977B1055A74112",opids,t,3403L); // planResultService.Move("B571EF6682DB463AB2977B1055A74112",opids,t,3403L);
// planResultService.Redecode("12345679"); planResultService.Redecode("12345679");
// MaintenanceWindow maintenanceWindow=new MaintenanceWindow(); // MaintenanceWindow maintenanceWindow=new MaintenanceWindow();
// maintenanceWindow.setStartTime(LocalDateTime.of(2025, 10, 21, 0, 0, 0)); // maintenanceWindow.setStartTime(LocalDateTime.of(2025, 10, 21, 0, 0, 0));
// maintenanceWindow.setEndTime(LocalDateTime.of(2025, 10, 31, 0, 0, 0)); // maintenanceWindow.setEndTime(LocalDateTime.of(2025, 10, 31, 0, 0, 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