Commit 3995638d authored by jidongtao's avatar jidongtao

添加注释

parent 73a7b529
...@@ -1106,11 +1106,18 @@ public class GeneticDecoder { ...@@ -1106,11 +1106,18 @@ public class GeneticDecoder {
int setupTime=0; int setupTime=0;
long machineId = machine.getId(); long machineId = machine.getId();
// 只有存在物料约束(或本次被强制要求重算 BOM)的工序,才需要联立求解“机台何时能排”和“物料何时可用”。
// targetFinishedOperationId != null 的工序通常由前置成品工序驱动,这里不再额外触发一轮 BOM 试算。
boolean needMaterialCheck = (operation.getMaterialRequirements()!=null&&operation.getMaterialRequirements().size()>0&&operation.getTargetFinishedOperationId()==null)||calbom; boolean needMaterialCheck = (operation.getMaterialRequirements()!=null&&operation.getMaterialRequirements().size()>0&&operation.getTargetFinishedOperationId()==null)||calbom;
// 正式落排后还要再做一次带提交的物料校验,把试算阶段推导出的 BOM 状态真正写回 chromosome。
boolean commitMaterialCheck = needMaterialCheck; boolean commitMaterialCheck = needMaterialCheck;
// baseEarliestStartTime:不考虑 BOM 推迟时的理论最早开工时间。
// candidateStartTime:固定点迭代时本轮尝试的开工时间。
// bomtime:按当前候选开工时间试算出来的物料最早可开工时间。
int baseEarliestStartTime = earliestStartTime; int baseEarliestStartTime = earliestStartTime;
int candidateStartTime = earliestStartTime; int candidateStartTime = earliestStartTime;
int bomtime=0; int bomtime=0;
// 机台时间和物料时间可能会互相推动,最多迭代 maxSolveIterations 次来找收敛点。
int maxSolveIterations = Math.max(1, _globalParam.getMaterialSolveMaxIterations()); int maxSolveIterations = Math.max(1, _globalParam.getMaterialSolveMaxIterations());
boolean converged = !needMaterialCheck; boolean converged = !needMaterialCheck;
Entry scheduledOperation = operation; Entry scheduledOperation = operation;
...@@ -1120,8 +1127,13 @@ public class GeneticDecoder { ...@@ -1120,8 +1127,13 @@ public class GeneticDecoder {
MachineSchedulePreview machinePreview = null; MachineSchedulePreview machinePreview = null;
CopyOnWriteArrayList<ScheduleResultDetail> geneDetails=new CopyOnWriteArrayList<>(); CopyOnWriteArrayList<ScheduleResultDetail> geneDetails=new CopyOnWriteArrayList<>();
// 固定点求解过程:
// 1. 先按 candidateStartTime 试排机台;
// 2. 再按试排结果试算物料/BOM 的最早可开工时间;
// 3. 如果物料时间继续把开工点往后推,就用新时间再次试排,直到收敛。
if(needMaterialCheck) { if(needMaterialCheck) {
for (int iteration = 0; iteration < maxSolveIterations; iteration++) { for (int iteration = 0; iteration < maxSolveIterations; iteration++) {
// trial BOM 试算会在内部恢复快照,因此每轮都重新从最新 chromosome 中取对象,避免拿到旧引用。
Entry refreshedOperation = entryIndexById.get(operationId); Entry refreshedOperation = entryIndexById.get(operationId);
if (refreshedOperation != null) { if (refreshedOperation != null) {
scheduledOperation = refreshedOperation; scheduledOperation = refreshedOperation;
...@@ -1137,13 +1149,15 @@ public class GeneticDecoder { ...@@ -1137,13 +1149,15 @@ public class GeneticDecoder {
{ {
candidateStartTime = Math.max(candidateStartTime,lastGeneOnMachine.getEndTime()); candidateStartTime = Math.max(candidateStartTime,lastGeneOnMachine.getEndTime());
} }
// 0 884400 // 先在机台侧做一次“试排”,geneDetails 中会记录本轮临时占用的机台时间段。
machinePreview = buildMachinePreview(scheduledOperation, scheduledMachine, processingTime, processingTimeTotal, machinePreview = buildMachinePreview(scheduledOperation, scheduledMachine, processingTime, processingTimeTotal,
candidateStartTime, lastGeneOnMachine, machineTasks, chromosome); candidateStartTime, lastGeneOnMachine, machineTasks, chromosome);
try { try {
//864000 // 物料侧只做试算,不提交最终状态;本轮只关心 BOM 约束会把开工时间推迟到哪里。
bomtime = EditOperationBOMTime(scheduledOperation,chromosome,machinePreview.getStartTime(),machineTasksCache, entryIndexById, scheduleIndexById, false); bomtime = EditOperationBOMTime(scheduledOperation,chromosome,machinePreview.getStartTime(),machineTasksCache, entryIndexById, scheduleIndexById, false);
} finally { } finally {
// buildMachinePreview 会临时锁住机台 availability,这里无论成功或异常都必须释放,
// 否则下一轮迭代会被本轮的试排残留状态污染。
Machine liveMachineAfterTrial = getMachineById(chromosome, machineId); Machine liveMachineAfterTrial = getMachineById(chromosome, machineId);
if (liveMachineAfterTrial != null) { if (liveMachineAfterTrial != null) {
AddMachineAvailable(liveMachineAfterTrial, machinePreview.getGeneDetails()); AddMachineAvailable(liveMachineAfterTrial, machinePreview.getGeneDetails());
...@@ -1152,7 +1166,9 @@ public class GeneticDecoder { ...@@ -1152,7 +1166,9 @@ public class GeneticDecoder {
} }
} }
// 下一轮候选开工时间取“基准最早开工”和“物料最早可开工”两者中的较晚值。
int nextCandidateStartTime = Math.max(baseEarliestStartTime, bomtime); int nextCandidateStartTime = Math.max(baseEarliestStartTime, bomtime);
// 如果物料时间已经不再把机台试排结果往后推,说明机台时间与物料时间达成一致。
if (nextCandidateStartTime <= machinePreview.getStartTime()) { if (nextCandidateStartTime <= machinePreview.getStartTime()) {
converged = true; converged = true;
candidateStartTime = nextCandidateStartTime; candidateStartTime = nextCandidateStartTime;
...@@ -1161,6 +1177,7 @@ public class GeneticDecoder { ...@@ -1161,6 +1177,7 @@ public class GeneticDecoder {
candidateStartTime = nextCandidateStartTime; candidateStartTime = nextCandidateStartTime;
} }
// 固定点求解结束后,用收敛得到的候选开工时间作为正式排产的最早开工时间。
earliestStartTime = candidateStartTime; earliestStartTime = candidateStartTime;
Entry refreshedOperation = entryIndexById.get(operationId); Entry refreshedOperation = entryIndexById.get(operationId);
if (refreshedOperation != null) { if (refreshedOperation != null) {
...@@ -1176,35 +1193,35 @@ public class GeneticDecoder { ...@@ -1176,35 +1193,35 @@ public class GeneticDecoder {
lastGeneOnMachine = getLastMachineTask(machineTasks); lastGeneOnMachine = getLastMachineTask(machineTasks);
needMaterialCheck = false; needMaterialCheck = false;
} }
// 旧兜底单次试算路径:当前固定点迭代执行完后会把 needMaterialCheck 置为 false,
// 因此这段分支实际上不会再进入。先注释保留,后续若确认无用可直接删除,
// 或按真实意图改成 !converged 时的兜底处理。
if(needMaterialCheck) { // if(needMaterialCheck) {
int earliestStartTimeold=earliestStartTime; // int earliestStartTimeold=earliestStartTime;
if (_globalParam.is_smoothChangeOver()) { // if (_globalParam.is_smoothChangeOver()) {
//
Map<Integer, Object> reslte = calculateSetupTime(lastGeneOnMachine, operation, machine, earliestStartTime, processingTimeTotal, _globalParam.is_smoothChangeOverInWeek(), chromosome.getAllOperations()); // Map<Integer, Object> reslte = calculateSetupTime(lastGeneOnMachine, operation, machine, earliestStartTime, processingTimeTotal, _globalParam.is_smoothChangeOverInWeek(), chromosome.getAllOperations());
// setupTime = (int) reslte.get(1);//换型时间 // // setupTime = (int) reslte.get(1);//换型时间
// int setupStartTime = (int) reslte.get(2);//换型开始时间 // // int setupStartTime = (int) reslte.get(2);//换型开始时间
//earliestStartTime=(int)reslte.get(3);//上个任务的结束时间 // //earliestStartTime=(int)reslte.get(3);//上个任务的结束时间
earliestStartTime = (int) reslte.get(4);//最早开工时间 // earliestStartTime = (int) reslte.get(4);//最早开工时间
} // }
LocalDateTime startTime1 = baseTime.plus(earliestStartTime, ChronoUnit.SECONDS); // LocalDateTime startTime1 = baseTime.plus(earliestStartTime, ChronoUnit.SECONDS);
//
TimeSegment slot = machineCalculator.GetCurrentOrNextShift(machine, startTime1, "", false); // TimeSegment slot = machineCalculator.GetCurrentOrNextShift(machine, startTime1, "", false);
//
if(slot!=null) // if(slot!=null)
{ // {
earliestStartTime = slot.getStart().isAfter(startTime1) // earliestStartTime = slot.getStart().isAfter(startTime1)
?(int) ChronoUnit.SECONDS.between(baseTime, slot.getStart()) // ?(int) ChronoUnit.SECONDS.between(baseTime, slot.getStart())
: earliestStartTime; // : earliestStartTime;
//
} // }
bomtime= EditOperationBOMTime(operation,chromosome,earliestStartTime,machineTasksCache, entryIndexById, scheduleIndexById, false); // bomtime= EditOperationBOMTime(operation,chromosome,earliestStartTime,machineTasksCache, entryIndexById, scheduleIndexById, false);
//
//
earliestStartTime = Math.max(earliestStartTime, bomtime); // earliestStartTime = Math.max(earliestStartTime, bomtime);
} // }
// machineTasks =chromosome.getResult().stream() // machineTasks =chromosome.getResult().stream()
...@@ -1214,11 +1231,14 @@ public class GeneticDecoder { ...@@ -1214,11 +1231,14 @@ public class GeneticDecoder {
// //
// machineTasksCache.put(machine.getId(), machineTasks); // machineTasksCache.put(machine.getId(), machineTasks);
// 正式落排前,再取一次当前机台最后一道工序,保证换型计算基于最新排程结果。
if(machineTasks!=null&&machineTasks.size()>0&&_globalParam.is_smoothChangeOver()) if(machineTasks!=null&&machineTasks.size()>0&&_globalParam.is_smoothChangeOver())
{ {
lastGeneOnMachine=machineTasks.get(machineTasks.size()-1); lastGeneOnMachine=machineTasks.get(machineTasks.size()-1);
} }
// 下面开始生成正式的 geneDetails。
// 与 buildMachinePreview 的区别是:这里得到的结果会继续向下写入 GAScheduleResult,成为真正排程结果。
if (_globalParam.is_smoothChangeOver()) { if (_globalParam.is_smoothChangeOver()) {
//是否考虑换型时间 //是否考虑换型时间
Map<Integer,Object> reslte = calculateSetupTime(lastGeneOnMachine, operation, machine,earliestStartTime,processingTimeTotal, _globalParam.is_smoothChangeOverInWeek(),chromosome.getAllOperations()); Map<Integer,Object> reslte = calculateSetupTime(lastGeneOnMachine, operation, machine,earliestStartTime,processingTimeTotal, _globalParam.is_smoothChangeOverInWeek(),chromosome.getAllOperations());
...@@ -1290,6 +1310,9 @@ public class GeneticDecoder { ...@@ -1290,6 +1310,9 @@ public class GeneticDecoder {
// 准备工时 加入到加工时间里 // 准备工时 加入到加工时间里
// 后处理时间 相同任务的前一工序的结束时间+后处理时间 =当前工序最早开工时间 // 后处理时间 相同任务的前一工序的结束时间+后处理时间 =当前工序最早开工时间
// 正式提交 BOM 校验:
// 1. 按最终 startTime 重新计算一次物料占用,并把状态真正写回;
// 2. 如果提交后的 BOM 时间仍然晚于 startTime,说明机台时间与物料时间没有收敛,需要直接报错。
if (commitMaterialCheck) { if (commitMaterialCheck) {
int committedBomTime = EditOperationBOMTime(operation,chromosome,startTime,machineTasksCache, entryIndexById, scheduleIndexById, true); int committedBomTime = EditOperationBOMTime(operation,chromosome,startTime,machineTasksCache, entryIndexById, scheduleIndexById, true);
bomtime = Math.max(bomtime, committedBomTime); bomtime = Math.max(bomtime, committedBomTime);
...@@ -1407,6 +1430,10 @@ public class GeneticDecoder { ...@@ -1407,6 +1430,10 @@ public class GeneticDecoder {
} }
} }
/**
* 按当前候选开工时间做一次机台侧试排。
* 注意:该方法会临时占用 machine.availability 中对应的时段,调用方用完后必须配合 AddMachineAvailable 释放。
*/
private MachineSchedulePreview buildMachinePreview(Entry operation, Machine machine, double processingTime, int processingTimeTotal, private MachineSchedulePreview buildMachinePreview(Entry operation, Machine machine, double processingTime, int processingTimeTotal,
int earliestStartTime, GAScheduleResult lastGeneOnMachine, int earliestStartTime, GAScheduleResult lastGeneOnMachine,
CopyOnWriteArrayList<GAScheduleResult> machineTasks, Chromosome chromosome) { CopyOnWriteArrayList<GAScheduleResult> machineTasks, Chromosome chromosome) {
...@@ -1416,6 +1443,7 @@ public class GeneticDecoder { ...@@ -1416,6 +1443,7 @@ public class GeneticDecoder {
CopyOnWriteArrayList<ScheduleResultDetail> geneDetails; CopyOnWriteArrayList<ScheduleResultDetail> geneDetails;
if (_globalParam.is_smoothChangeOver()) { if (_globalParam.is_smoothChangeOver()) {
// 先把换型时间、换型起点以及加工总时长修正到当前候选时间点。
Map<Integer,Object> reslte = calculateSetupTime(lastGeneOnMachine, operation, machine, previewStart, previewProcessingTotal, _globalParam.is_smoothChangeOverInWeek(),chromosome.getAllOperations()); Map<Integer,Object> reslte = calculateSetupTime(lastGeneOnMachine, operation, machine, previewStart, previewProcessingTotal, _globalParam.is_smoothChangeOverInWeek(),chromosome.getAllOperations());
setupTime=(int)reslte.get(1); setupTime=(int)reslte.get(1);
int setupStartTime=(int)reslte.get(2); int setupStartTime=(int)reslte.get(2);
...@@ -1423,10 +1451,12 @@ public class GeneticDecoder { ...@@ -1423,10 +1451,12 @@ public class GeneticDecoder {
previewProcessingTotal=(int)reslte.get(5); previewProcessingTotal=(int)reslte.get(5);
if(setupTime==0) if(setupTime==0)
{ {
// 没有换型占用时,直接查机台下一段可排的可用窗口。
geneDetails = machineCalculator.getNextAvailableTime(machine, previewStart, -1, geneDetails = machineCalculator.getNextAvailableTime(machine, previewStart, -1,
previewProcessingTotal, machineTasks, operation.getIsInterrupt()!=1, true,processingTime, operation.getQuantity(), true); previewProcessingTotal, machineTasks, operation.getIsInterrupt()!=1, true,processingTime, operation.getQuantity(), true);
}else { }else {
// 有换型占用时,需要把换型段和加工段一起拼成完整的试排结果。
CopyOnWriteArrayList<TimeSegment> AvailableTimeSegment = (CopyOnWriteArrayList<TimeSegment>) reslte.get(6); CopyOnWriteArrayList<TimeSegment> AvailableTimeSegment = (CopyOnWriteArrayList<TimeSegment>) reslte.get(6);
Map<Integer,Object> result = machineCalculator.CreateScheduleResult(machine, previewProcessingTotal, previewStart, Map<Integer,Object> result = machineCalculator.CreateScheduleResult(machine, previewProcessingTotal, previewStart,
AvailableTimeSegment, processingTime, operation.getQuantity(), operation.getIsInterrupt() != 1, setupTime, _globalParam.is_smoothChangeOverInWeek(), setupStartTime); AvailableTimeSegment, processingTime, operation.getQuantity(), operation.getIsInterrupt() != 1, setupTime, _globalParam.is_smoothChangeOverInWeek(), setupStartTime);
...@@ -1435,10 +1465,12 @@ public class GeneticDecoder { ...@@ -1435,10 +1465,12 @@ public class GeneticDecoder {
geneDetails=(CopyOnWriteArrayList<ScheduleResultDetail>) result.get(2); geneDetails=(CopyOnWriteArrayList<ScheduleResultDetail>) result.get(2);
} }
}else { }else {
// 不考虑平滑换型时,只需要找加工段可用窗口。
geneDetails = machineCalculator.getNextAvailableTime(machine, previewStart, -1, geneDetails = machineCalculator.getNextAvailableTime(machine, previewStart, -1,
previewProcessingTotal, machineTasks, operation.getIsInterrupt()!=1, true,processingTime, operation.getQuantity(), true); previewProcessingTotal, machineTasks, operation.getIsInterrupt()!=1, true,processingTime, operation.getQuantity(), true);
} }
// geneDetails 可能跨多个班次/时段,开始时间取最小值,结束时间取最大值。
int startTime = geneDetails.stream() int startTime = geneDetails.stream()
.mapToInt(ScheduleResultDetail::getStartTime) .mapToInt(ScheduleResultDetail::getStartTime)
.min() .min()
...@@ -1450,6 +1482,7 @@ public class GeneticDecoder { ...@@ -1450,6 +1482,7 @@ public class GeneticDecoder {
return new MachineSchedulePreview(startTime, endTime, setupTime, geneDetails); return new MachineSchedulePreview(startTime, endTime, setupTime, geneDetails);
} }
// 按机台缓存已排结果,避免固定点迭代期间反复全表扫描 chromosome.getResult()。
private CopyOnWriteArrayList<GAScheduleResult> getMachineTasks(long machineId, Chromosome chromosome, private CopyOnWriteArrayList<GAScheduleResult> getMachineTasks(long machineId, Chromosome chromosome,
Map<Long, CopyOnWriteArrayList<GAScheduleResult>> machineTasksCache) { Map<Long, CopyOnWriteArrayList<GAScheduleResult>> machineTasksCache) {
if (machineTasksCache.containsKey(machineId)) { if (machineTasksCache.containsKey(machineId)) {
...@@ -1463,6 +1496,7 @@ public class GeneticDecoder { ...@@ -1463,6 +1496,7 @@ public class GeneticDecoder {
return machineTasks; return machineTasks;
} }
// 当前机台最后一道已排工序,用于约束连续排程和换型起点。
private GAScheduleResult getLastMachineTask(CopyOnWriteArrayList<GAScheduleResult> machineTasks) { private GAScheduleResult getLastMachineTask(CopyOnWriteArrayList<GAScheduleResult> machineTasks) {
if(machineTasks!=null&&machineTasks.size()>0) if(machineTasks!=null&&machineTasks.size()>0)
{ {
...@@ -1471,6 +1505,7 @@ public class GeneticDecoder { ...@@ -1471,6 +1505,7 @@ public class GeneticDecoder {
return null; return null;
} }
// trial BOM 恢复快照后,旧的 Machine 引用可能已经失效,因此统一从 chromosome 中重新取当前有效对象。
private Machine getMachineById(Chromosome chromosome, long machineId) { private Machine getMachineById(Chromosome chromosome, long machineId) {
return chromosome.getMachines().stream() return chromosome.getMachines().stream()
.filter(m -> m.getId() == machineId) .filter(m -> m.getId() == machineId)
...@@ -1629,6 +1664,10 @@ public class GeneticDecoder { ...@@ -1629,6 +1664,10 @@ public class GeneticDecoder {
} }
/**
* 汇总当前工序的物料约束,返回所有原料/半成品中最晚满足的那个时刻。
* 返回值含义是“这道工序最早允许因物料而开工的秒数”。
*/
private int getOperationBOMTime(Entry currentOp, Chromosome chromosome) { private int getOperationBOMTime(Entry currentOp, Chromosome chromosome) {
List<OrderMaterialRequirement> opboms= currentOp.getMaterialRequirements(); List<OrderMaterialRequirement> opboms= currentOp.getMaterialRequirements();
...@@ -1696,10 +1735,16 @@ public class GeneticDecoder { ...@@ -1696,10 +1735,16 @@ public class GeneticDecoder {
return Math.max(rawTime, sfTime); return Math.max(rawTime, sfTime);
} }
// 默认走正式提交路径,调用方不传 commitChanges 时认为要把物料状态真实写回。
private int EditOperationBOMTime(Entry currentOp, Chromosome chromosome,int earliestStartTime,Map<Long, CopyOnWriteArrayList<GAScheduleResult>> machineTasksCache,Map<Integer, Entry> entryIndexById,Map<Integer, GAScheduleResult> scheduleIndexById) { private int EditOperationBOMTime(Entry currentOp, Chromosome chromosome,int earliestStartTime,Map<Long, CopyOnWriteArrayList<GAScheduleResult>> machineTasksCache,Map<Integer, Entry> entryIndexById,Map<Integer, GAScheduleResult> scheduleIndexById) {
return EditOperationBOMTime(currentOp, chromosome, earliestStartTime, machineTasksCache, entryIndexById, scheduleIndexById, true); return EditOperationBOMTime(currentOp, chromosome, earliestStartTime, machineTasksCache, entryIndexById, scheduleIndexById, true);
} }
/**
* 按指定 earliestStartTime 重新计算当前工序的 BOM 可开工时间。
* commitChanges=true:正式提交,真实修改物料/订单/排程状态。
* commitChanges=false:只做试算,方法结束后恢复 chromosome 和相关索引缓存。
*/
private int EditOperationBOMTime(Entry currentOp, Chromosome chromosome,int earliestStartTime,Map<Long, CopyOnWriteArrayList<GAScheduleResult>> machineTasksCache,Map<Integer, Entry> entryIndexById,Map<Integer, GAScheduleResult> scheduleIndexById, boolean commitChanges) { private int EditOperationBOMTime(Entry currentOp, Chromosome chromosome,int earliestStartTime,Map<Long, CopyOnWriteArrayList<GAScheduleResult>> machineTasksCache,Map<Integer, Entry> entryIndexById,Map<Integer, GAScheduleResult> scheduleIndexById, boolean commitChanges) {
List<OrderMaterialRequirement> opboms= currentOp.getMaterialRequirements(); List<OrderMaterialRequirement> opboms= currentOp.getMaterialRequirements();
if(opboms==null) if(opboms==null)
...@@ -1708,20 +1753,24 @@ public class GeneticDecoder { ...@@ -1708,20 +1753,24 @@ public class GeneticDecoder {
} }
LocalDateTime earliestStartTime1=baseTime.plusSeconds(earliestStartTime); LocalDateTime earliestStartTime1=baseTime.plusSeconds(earliestStartTime);
if(commitChanges) { if(commitChanges) {
// 正式提交模式:直接把当前开工时间对应的物料占用/供应结果写回业务对象。
materialRequirementService.EditOperationBOM(currentOp,chromosome,earliestStartTime1,this,machineTasksCache, entryIndexById, scheduleIndexById, baseTime, true); materialRequirementService.EditOperationBOM(currentOp,chromosome,earliestStartTime1,this,machineTasksCache, entryIndexById, scheduleIndexById, baseTime, true);
return getOperationBOMTime(currentOp, chromosome); return getOperationBOMTime(currentOp, chromosome);
} }
// 试算模式:先复制一份完整状态,等 BOM 计算完成后再整体恢复。
TrialDecodeSnapshot snapshot = createTrialDecodeSnapshot(chromosome); TrialDecodeSnapshot snapshot = createTrialDecodeSnapshot(chromosome);
try { try {
materialRequirementService.EditOperationBOM(currentOp,chromosome,earliestStartTime1,this,machineTasksCache, entryIndexById, scheduleIndexById, baseTime, true); materialRequirementService.EditOperationBOM(currentOp,chromosome,earliestStartTime1,this,machineTasksCache, entryIndexById, scheduleIndexById, baseTime, true);
return getOperationBOMTime(currentOp, chromosome); return getOperationBOMTime(currentOp, chromosome);
} finally { } finally {
// 试算期间 materialRequirementService 可能会改动 machine/order/material/result,这里统一回滚。
restoreTrialDecodeSnapshot(snapshot, chromosome, machineTasksCache, entryIndexById, scheduleIndexById); restoreTrialDecodeSnapshot(snapshot, chromosome, machineTasksCache, entryIndexById, scheduleIndexById);
} }
} }
// 试算 BOM 会改动多类状态对象,因此先把排程求解会依赖的核心集合做一次深拷贝快照。
private TrialDecodeSnapshot createTrialDecodeSnapshot(Chromosome chromosome) { private TrialDecodeSnapshot createTrialDecodeSnapshot(Chromosome chromosome) {
TrialDecodeSnapshot snapshot = new TrialDecodeSnapshot(); TrialDecodeSnapshot snapshot = new TrialDecodeSnapshot();
snapshot.machines = ProductionDeepCopyUtil.deepCopyList(chromosome.getMachines(), Machine.class); snapshot.machines = ProductionDeepCopyUtil.deepCopyList(chromosome.getMachines(), Machine.class);
...@@ -1733,6 +1782,7 @@ public class GeneticDecoder { ...@@ -1733,6 +1782,7 @@ public class GeneticDecoder {
return snapshot; return snapshot;
} }
// 恢复试算前的 chromosome 状态,并同步重建几个按 id/机台组织的缓存索引。
private void restoreTrialDecodeSnapshot(TrialDecodeSnapshot snapshot, Chromosome chromosome, private void restoreTrialDecodeSnapshot(TrialDecodeSnapshot snapshot, Chromosome chromosome,
Map<Long, CopyOnWriteArrayList<GAScheduleResult>> machineTasksCache, Map<Long, CopyOnWriteArrayList<GAScheduleResult>> machineTasksCache,
Map<Integer, Entry> entryIndexById, Map<Integer, Entry> entryIndexById,
...@@ -2550,6 +2600,7 @@ public class GeneticDecoder { ...@@ -2550,6 +2600,7 @@ public class GeneticDecoder {
return reslte; return reslte;
} }
// 释放试排阶段占用的机台 availability 段,避免临时状态污染下一轮排程/BOM 试算。
public void AddMachineAvailable(Machine machine, List<ScheduleResultDetail> geneDetails) { public void AddMachineAvailable(Machine machine, List<ScheduleResultDetail> geneDetails) {
if (geneDetails == null || geneDetails.isEmpty()) return; if (geneDetails == null || geneDetails.isEmpty()) return;
......
...@@ -41,6 +41,7 @@ public class MachineCalculator { ...@@ -41,6 +41,7 @@ public class MachineCalculator {
/** /**
* 获取机器下一个可用时间窗口(考虑班次约束) * 获取机器下一个可用时间窗口(考虑班次约束)
*/ */
// 从 proposedStartTime 开始查找机台下一段可排窗口;必要时会把命中的 availability 临时标记为已占用。
public CopyOnWriteArrayList<ScheduleResultDetail> getNextAvailableTime(Machine machine, int proposedStartTime, public CopyOnWriteArrayList<ScheduleResultDetail> getNextAvailableTime(Machine machine, int proposedStartTime,
int prevtime, int processingTime, int prevtime, int processingTime,
CopyOnWriteArrayList<GAScheduleResult> existingTasks, CopyOnWriteArrayList<GAScheduleResult> existingTasks,
...@@ -70,6 +71,7 @@ public class MachineCalculator { ...@@ -70,6 +71,7 @@ public class MachineCalculator {
return findAvailableSegments(machine, startTime, existingTasks, processingTime, isInterrupt); return findAvailableSegments(machine, startTime, existingTasks, processingTime, isInterrupt);
} }
// 基于已选可用时段组装排程结果,并把换型段/加工段对应的 availability 临时占用。
public Map<Integer,Object> CreateScheduleResult( public Map<Integer,Object> CreateScheduleResult(
Machine machine, int processingTime, int proposedStartTime,CopyOnWriteArrayList<TimeSegment> timeSegments, Machine machine, int processingTime, int proposedStartTime,CopyOnWriteArrayList<TimeSegment> timeSegments,
double oneTime,double quantity double oneTime,double quantity
...@@ -1289,6 +1291,7 @@ public class MachineCalculator { ...@@ -1289,6 +1291,7 @@ public class MachineCalculator {
return times; return times;
} }
// 把目标 availability 按本次排程切成“剩余可用段”和“本次已占用段”,并把占用段 key 回写到 geneDetails。
private CopyOnWriteArrayList<TimeSegment> RemoveMachineAvailable(Machine machine, ScheduleResultDetail geneDetails,TimeSegment targetSegment) { private CopyOnWriteArrayList<TimeSegment> RemoveMachineAvailable(Machine machine, ScheduleResultDetail geneDetails,TimeSegment targetSegment) {
......
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