Commit ff8e1628 authored by Tong Li's avatar Tong Li

重叠

parent 9ab085a3
...@@ -712,6 +712,7 @@ if(finishedOrder==null||finishedOrder.size()==0) ...@@ -712,6 +712,7 @@ if(finishedOrder==null||finishedOrder.size()==0)
} }
} }
} }
//重叠
List<OperationDependency> SSOperations = currentOp.getPrevEntryIds().stream() List<OperationDependency> SSOperations = currentOp.getPrevEntryIds().stream()
.filter(t -> t.getDependencyType() == DependencyType.StartToStart) .filter(t -> t.getDependencyType() == DependencyType.StartToStart)
.collect(Collectors.toList());//重叠 .collect(Collectors.toList());//重叠
...@@ -736,6 +737,18 @@ if(finishedOrder==null||finishedOrder.size()==0) ...@@ -736,6 +737,18 @@ if(finishedOrder==null||finishedOrder.size()==0)
.orElse(0); .orElse(0);
prevtime = calculateNextOperationStartTime(newScheduleResult, newScheduleResultDetails, 0, processTime); prevtime = calculateNextOperationStartTime(newScheduleResult, newScheduleResultDetails, 0, processTime);
// 下一工序结束时间需晚于上一工序结束时间一个产品加工时间 // 下一工序结束时间需晚于上一工序结束时间一个产品加工时间
// int ssStartTimeWithCalendar = calculateSSStartTimeWithCalendar(
// newScheduleResult,
// newScheduleResultDetails,
// currentOp,
// machine,
// processTime,
// prevtime);
//
// prevtime = Math.max(prevtime, ssStartTimeWithCalendar);
double nextopplanend = prevperationEndTime + processTime; double nextopplanend = prevperationEndTime + processTime;
List<ScheduleResultDetail> geneDetails1 = machineCalculator.checkMachineStartTime(machine, (int) (processTime * currentOp.getQuantity()), List<ScheduleResultDetail> geneDetails1 = machineCalculator.checkMachineStartTime(machine, (int) (processTime * currentOp.getQuantity()),
...@@ -1064,6 +1077,155 @@ if(MaterialRequirements==null||MaterialRequirements.size()==0) ...@@ -1064,6 +1077,155 @@ if(MaterialRequirements==null||MaterialRequirements.size()==0)
// 单设备时使用原逻辑 // 单设备时使用原逻辑
return (int)calculateWithSingleMachine(details, leadCount, time1); return (int)calculateWithSingleMachine(details, leadCount, time1);
} }
/**
* 计算基于日历重叠约束的开始时间
* 整合了产能计算和连续性检查
* @param prevScheduleResults 前一工序的调度结果
* @param prevDetails 前一工序的详细调度信息
* @param currentOp 当前工序
* @param machine 当前工序的目标机器
* @param processTime 当前工序的处理时间
* @param prevtime 基础前序时间
* @return 修正后的开始时间
*/
private int calculateSSStartTimeWithCalendar(List<GAScheduleResult> prevScheduleResults,
List<ScheduleResultDetail> prevDetails,
Entry currentOp, Machine machine,
double processTime, int prevtime) {
if (prevScheduleResults == null || prevScheduleResults.isEmpty()) {
return prevtime;
}
//前工序生产数量和
double qty = prevScheduleResults.stream()
.mapToDouble(GAScheduleResult::getQuantity)
.sum();
if (qty <= 0) {
return prevtime;
}
double prevTimePerUnit = prevScheduleResults.stream()
.mapToDouble(r -> r.getOneTime())
.sum() / qty;
double currentTimePerUnit = processTime;
int leadCount = (int) calculateLeadProductionItems(qty, prevTimePerUnit, currentTimePerUnit);
int productionTimeForLeadCount = calculateProductionTimeWithCalendar(
prevDetails, leadCount, machine, currentOp);
int prevEndTime = prevScheduleResults.stream()
.mapToInt(GAScheduleResult::getEndTime)
.max()
.orElse(0);
int minEndTimeForContinuity = prevEndTime - (int) ((qty - leadCount) * prevTimePerUnit);
int adjustedStartTime = Math.max(productionTimeForLeadCount, minEndTimeForContinuity);
adjustedStartTime = Math.max(adjustedStartTime, prevtime);
int totalProcessingTime = (int) (currentTimePerUnit * qty);
int continuityAdjustedTime = ensureContinuousProduction(machine, adjustedStartTime,
totalProcessingTime, currentOp);
return Math.max(adjustedStartTime, continuityAdjustedTime);
}
/**
* 确保下一工序能够连续生产(不中断)
* 检查并调整开始时间以保证生产连续性
*/
private int ensureContinuousProduction(Machine machine, int proposedStartTime,
int processingTime, Entry currentOp) {
if (machine == null || processingTime <= 0) {
return proposedStartTime;
}
LocalDateTime proposedStart = baseTime.plusSeconds(proposedStartTime);
LocalDateTime proposedEnd = proposedStart.plusSeconds(processingTime);
CopyOnWriteArrayList<TimeSegment> availableSegments = machineCalculator.getMachineAvailableTime(
machine, proposedStartTime, processingTime, null, currentOp.getIsInterrupt() != 1);
if (availableSegments == null || availableSegments.isEmpty()) {
return proposedStartTime;
}
for (TimeSegment segment : availableSegments) {
LocalDateTime segStart = segment.getStart();
LocalDateTime segEnd = segment.getEnd();
if (!segStart.isAfter(proposedStart) && !segEnd.isBefore(proposedEnd)) {
return proposedStartTime;
}
if (segEnd.isAfter(proposedStart) && segEnd.isBefore(proposedEnd)) {
int newStartTime = (int) ChronoUnit.SECONDS.between(baseTime, segEnd);
return ensureContinuousProduction(machine, newStartTime, processingTime, currentOp);
}
if (segStart.isAfter(proposedStart) && segStart.isBefore(proposedEnd)) {
int newStartTime = (int) ChronoUnit.SECONDS.between(baseTime, segStart);
return newStartTime;
}
}
TimeSegment firstSegment = availableSegments.get(0);
int segStart = (int) ChronoUnit.SECONDS.between(baseTime, firstSegment.getStart());
if (segStart > proposedStartTime) {
return segStart;
}
return proposedStartTime;
}
/**
* 根据日历计算生产指定数量所需时间(考虑效率系数)
*/
private int calculateProductionTimeWithCalendar(List<ScheduleResultDetail> details, int leadCount,
Machine machine, Entry currentOp) {
if (details == null || details.isEmpty() || leadCount <= 0) {
return 0;
}
Set<Integer> timePoints = new TreeSet<>();
for (ScheduleResultDetail detail : details) {
timePoints.add(detail.getStartTime());
timePoints.add(detail.getEndTime());
}
List<Integer> sortedTimes = new ArrayList<>(timePoints);
double accumulatedQty = 0.0;
for (int i = 0; i < sortedTimes.size() - 1; i++) {
int startTime = sortedTimes.get(i);
int endTime = sortedTimes.get(i + 1);
int duration = endTime - startTime;
if (duration <= 0) continue;
double efficiency = details.stream()
.filter(d -> d.getStartTime() <= startTime && d.getEndTime() >= endTime)
.mapToDouble(d -> d.getProcessingTime() > 0 ? 1.0 / d.getOneTime() : 0)
.sum();
double segmentQty = efficiency * duration;
if (accumulatedQty + segmentQty >= leadCount) {
double remainingQty = leadCount - accumulatedQty;
int requiredTime = (int) Math.ceil(remainingQty / efficiency);
return startTime + requiredTime;
}
accumulatedQty += segmentQty;
}
return details.stream()
.mapToInt(ScheduleResultDetail::getEndTime)
.max()
.orElse(0);
}
/** /**
* 多设备并行时计算满足提前量的最早时间 * 多设备并行时计算满足提前量的最早时间
*/ */
......
...@@ -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("D6836ADCEF5F4537A4BDD896ECC2EC6A"); 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
......
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