Commit ae460151 authored by Tong Li's avatar Tong Li

Merge remote-tracking branch 'origin/tl'

parents c5c9a28b 5767b7da
...@@ -290,7 +290,7 @@ public class GeneticDecoder { ...@@ -290,7 +290,7 @@ public class GeneticDecoder {
return 1; return 1;
} }
private void CreateNewOpSequence(Chromosome chromosome,boolean isJit) private void CreateNewOpSequence(Chromosome chromosome,Map<Integer, Integer> orderDueDate,Map<Integer, List<Entry>> entrysBygroupId,boolean isJit)
{ {
//成品订单 //成品订单
...@@ -334,22 +334,31 @@ public class GeneticDecoder { ...@@ -334,22 +334,31 @@ public class GeneticDecoder {
scheduledCount = orderProcessCounter.get(num)+1; scheduledCount = orderProcessCounter.get(num)+1;
} }
int scheduledCount1=scheduledCount; int scheduledCount1=scheduledCount;
List<Entry> allOperations=chromosome.getAllOperations();
Entry entry=allOperations.stream() List<Entry> operations= entrysBygroupId.get(num);
.filter(t->t.getGroupId()==num&&t.getSequence()==scheduledCount1) Entry entry=operations.stream()
.filter(t->t.getSequence()==scheduledCount1)
.findFirst().orElse(null); .findFirst().orElse(null);
// 找不到当前成品工序时跳过,避免重建排序时空指针。 // 找不到当前成品工序时跳过,避免重建排序时空指针。
if (entry == null) { if (entry == null) {
continue; continue;
} }
int ordertime=orderDueDate.get(entry.getGroupId());
if(isJit) { if(isJit) {
entry.setSchedulingMode(Entry.SchedulingMode.BACKWARD.name());
if(ordertime>0) {
entry.setSchedulingMode(Entry.SchedulingMode.BACKWARD.name());
}else {
entry.setSchedulingMode(Entry.SchedulingMode.FORWARD.name());
}
}else { }else {
entry.setSchedulingMode(Entry.SchedulingMode.FORWARD.name()); entry.setSchedulingMode(Entry.SchedulingMode.FORWARD.name());
} }
if(entry!=null&&entry.getDependentOnOrderIds().size()>0) if(entry!=null&&entry.getDependentOnOrderIds().size()>0)
{ {
if(isJit) { if(isJit&& ordertime>0) {
finalSequence.add(num); finalSequence.add(num);
} }
for (int order : entry.getDependentOnOrderIds()) { for (int order : entry.getDependentOnOrderIds()) {
...@@ -360,10 +369,10 @@ public class GeneticDecoder { ...@@ -360,10 +369,10 @@ public class GeneticDecoder {
continue; continue;
} }
for (int num1 : childSequence){ for (int num1 : childSequence){
InsertSimSequence(orderProcessCounter,num1,finalSequence,sfSequence,allOperations); InsertSimSequence(orderProcessCounter,num1,finalSequence,sfSequence,entrysBygroupId);
} }
} }
if(!isJit) { if(!isJit|| ordertime<=0) {
finalSequence.add(num); finalSequence.add(num);
} }
}else { }else {
...@@ -375,7 +384,7 @@ public class GeneticDecoder { ...@@ -375,7 +384,7 @@ public class GeneticDecoder {
chromosome.setOperationSequencing(finalSequence); chromosome.setOperationSequencing(finalSequence);
} }
private void InsertSimSequence(Map<Integer, Integer> orderProcessCounter,int orderid,List<Integer> finalSequence,Map<Integer, List<Integer>> sfSequence,List<Entry> allOperations) private void InsertSimSequence(Map<Integer, Integer> orderProcessCounter,int orderid,List<Integer> finalSequence,Map<Integer, List<Integer>> sfSequence,Map<Integer, List<Entry>> entrysBygroupId)
{ {
Random rnd = new Random(); Random rnd = new Random();
int scheduledCount=1; int scheduledCount=1;
...@@ -384,8 +393,8 @@ public class GeneticDecoder { ...@@ -384,8 +393,8 @@ public class GeneticDecoder {
scheduledCount = orderProcessCounter.get(orderid)+1; scheduledCount = orderProcessCounter.get(orderid)+1;
} }
int scheduledCount1=scheduledCount; int scheduledCount1=scheduledCount;
Entry entry=allOperations.stream() Entry entry=entrysBygroupId.get(orderid).stream()
.filter(t->t.getGroupId()==orderid&&t.getSequence()==scheduledCount1) .filter(t->t.getSequence()==scheduledCount1)
.findFirst().orElse(null); .findFirst().orElse(null);
// 找不到下一道工序说明该订单已插够次数,不能再写入 finalSequence。 // 找不到下一道工序说明该订单已插够次数,不能再写入 finalSequence。
if (entry == null) { if (entry == null) {
...@@ -402,7 +411,7 @@ public class GeneticDecoder { ...@@ -402,7 +411,7 @@ public class GeneticDecoder {
continue; continue;
} }
for (int num1 : childSequence) { for (int num1 : childSequence) {
InsertSimSequence(orderProcessCounter,num1,finalSequence,sfSequence,allOperations); InsertSimSequence(orderProcessCounter,num1,finalSequence,sfSequence,entrysBygroupId);
} }
} }
finalSequence.add(orderid); finalSequence.add(orderid);
...@@ -502,7 +511,53 @@ public class GeneticDecoder { ...@@ -502,7 +511,53 @@ public class GeneticDecoder {
materialRequirementService.buildMultiLevelRequirementNetwork(chromosome, sceneId, baseTime,_globalParam); materialRequirementService.buildMultiLevelRequirementNetwork(chromosome, sceneId, baseTime,_globalParam);
// FileHelper.writeLogFile("[PERF] serialDecode buildMultiLevelRequirementNetwork 耗时=" + fmtMs(System.nanoTime() - t1)); // FileHelper.writeLogFile("[PERF] serialDecode buildMultiLevelRequirementNetwork 耗时=" + fmtMs(System.nanoTime() - t1));
} }
List<Entry> allOperations=chromosome.getAllOperations();
Map<Integer, Integer> orderProcessCounter = new HashMap<>();
Map<Integer, Integer> orderLastEndTime = new HashMap<>();
//工序对应的排产结果
Map<Integer, GAScheduleResult> scheduleIndexById = new ConcurrentHashMap<>();
Map<Integer, Entry> entryIndexById = new HashMap<>();
Map<Integer, List<Entry>> entrysBygroupId = new HashMap<>();
for (Entry op : allOperations) {
int groupId = op.getGroupId();
orderProcessCounter.putIfAbsent(groupId, 0);
orderLastEndTime.putIfAbsent(groupId, 0);
//工序
entryIndexById.put(op.getId(),op);
//订单下全部工序
entrysBygroupId.computeIfAbsent(groupId, k -> new ArrayList<>()).add(op);
//scheduleIndexById.put(op.getId(),null);
}
Map<Integer, Integer> orderDueDate = new HashMap<>();
Map<Integer, AbstractMap.SimpleEntry<Boolean, Integer>> orderSchedulingInfo = new HashMap<>();
for (Order order : chromosome.getOrders()) {
int end = (int) ChronoUnit.SECONDS.between(baseTime, order.getDueDate());
orderDueDate.putIfAbsent(order.getId(), end);
//存储锚点时间
if(isJit)
{
if(end>0)
{
orderSchedulingInfo.put(order.getId(), new AbstractMap.SimpleEntry<>(true, end));
}else {
orderSchedulingInfo.put(order.getId(), new AbstractMap.SimpleEntry<>(false, 0));
}
}else {
orderSchedulingInfo.put(order.getId(), new AbstractMap.SimpleEntry<>(false, 0));
}
}
if(rebuildStructureForCurrentDecode && _globalParam.isIsCheckSf()) { if(rebuildStructureForCurrentDecode && _globalParam.isIsCheckSf()) {
long t1 = System.nanoTime(); long t1 = System.nanoTime();
int isnew= generateGlobalOpList(chromosome); int isnew= generateGlobalOpList(chromosome);
...@@ -510,7 +565,7 @@ public class GeneticDecoder { ...@@ -510,7 +565,7 @@ public class GeneticDecoder {
if(isnew==1) { if(isnew==1) {
long t2 = System.nanoTime(); long t2 = System.nanoTime();
CreateNewOpSequence(chromosome,isJit); CreateNewOpSequence(chromosome,orderDueDate,entrysBygroupId,isJit);
// CreateNewOpSequence 会重建半成品插入顺序,生成后再规整一次,避免重复调度同一订单。 // CreateNewOpSequence 会重建半成品插入顺序,生成后再规整一次,避免重复调度同一订单。
normalizeOperationSequencing(chromosome); normalizeOperationSequencing(chromosome);
// FileHelper.writeLogFile("[PERF] serialDecode CreateNewOpSequence 耗时=" + fmtMs(System.nanoTime() - t2)); // FileHelper.writeLogFile("[PERF] serialDecode CreateNewOpSequence 耗时=" + fmtMs(System.nanoTime() - t2));
...@@ -518,7 +573,6 @@ public class GeneticDecoder { ...@@ -518,7 +573,6 @@ public class GeneticDecoder {
} }
List<GlobalOperationInfo> globalOpList=chromosome.getGlobalOpList(); List<GlobalOperationInfo> globalOpList=chromosome.getGlobalOpList();
List<Entry> allOperations=chromosome.getAllOperations();
allOperations.forEach(t -> t.setLatestCompletionTime(null)); allOperations.forEach(t -> t.setLatestCompletionTime(null));
...@@ -573,45 +627,9 @@ public class GeneticDecoder { ...@@ -573,45 +627,9 @@ public class GeneticDecoder {
} }
// 步骤2:按OperationSequencing顺序调度工序
Map<Integer, Integer> orderProcessCounter = new HashMap<>();
Map<Integer, Integer> orderLastEndTime = new HashMap<>();
//工序对应的排产结果
Map<Integer, GAScheduleResult> scheduleIndexById = new ConcurrentHashMap<>();
Map<Integer, Entry> entryIndexById = new HashMap<>();
Map<Integer, List<Entry>> entrysBygroupId = new HashMap<>();
for (Entry op : allOperations) {
int groupId = op.getGroupId();
orderProcessCounter.putIfAbsent(groupId, 0);
orderLastEndTime.putIfAbsent(groupId, 0);
//工序
entryIndexById.put(op.getId(),op);
//订单下全部工序
entrysBygroupId.computeIfAbsent(groupId, k -> new ArrayList<>()).add(op);
//scheduleIndexById.put(op.getId(),null);
}
Map<Integer, Integer> orderDueDate = new HashMap<>();
Map<Integer, AbstractMap.SimpleEntry<Boolean, Integer>> orderSchedulingInfo = new HashMap<>();
for (Order order : chromosome.getOrders()) {
int end = (int) ChronoUnit.SECONDS.between(baseTime, order.getDueDate());
orderDueDate.putIfAbsent(order.getId(), end);
//存储锚点时间
if(isJit)
{
orderSchedulingInfo.put(order.getId(), new AbstractMap.SimpleEntry<>(true, end));
}else {
orderSchedulingInfo.put(order.getId(), new AbstractMap.SimpleEntry<>(false, 0));
}
}
Set<Integer> semiFinishedOrderIds=new HashSet<>(); Set<Integer> semiFinishedOrderIds=new HashSet<>();
if(isJit) if(isJit)
{ {
...@@ -645,6 +663,8 @@ public class GeneticDecoder { ...@@ -645,6 +663,8 @@ public class GeneticDecoder {
Set<Integer> reForwardFinishedOrderIds = new HashSet<>(); Set<Integer> reForwardFinishedOrderIds = new HashSet<>();
// 延迟重排映射:半成品ID → 关联成品ID集合(等半成品全部排完后再处理) // 延迟重排映射:半成品ID → 关联成品ID集合(等半成品全部排完后再处理)
Map<Integer, Set<Integer>> pendingReForwardMap = new HashMap<>(); Map<Integer, Set<Integer>> pendingReForwardMap = new HashMap<>();
// 倒排订单:延迟扣库存,等整单排完后按正序统一扣
Set<Integer> jitDeferredBomOrderIds = new HashSet<>();
Map<Integer, Order> orders = chromosome.getOrders().stream() Map<Integer, Order> orders = chromosome.getOrders().stream()
.collect(Collectors.toMap( .collect(Collectors.toMap(
...@@ -723,6 +743,10 @@ if(groupId==7) ...@@ -723,6 +743,10 @@ if(groupId==7)
if(orderIsJit) if(orderIsJit)
{ {
jitDeferredBomOrderIds.add(groupId);
orderOps = entrysBygroupId.get(groupId).stream() orderOps = entrysBygroupId.get(groupId).stream()
.sorted(Comparator.comparing(Entry::getSequence).reversed()) .sorted(Comparator.comparing(Entry::getSequence).reversed())
.collect(Collectors.toList()); .collect(Collectors.toList());
...@@ -774,15 +798,22 @@ if(groupId==7) ...@@ -774,15 +798,22 @@ if(groupId==7)
OperationScheduleResult operationResult = processOperationSchedule(currentOp, machineId, processTime, OperationScheduleResult operationResult = processOperationSchedule(currentOp, machineId, processTime,
machineOption, chromosome, machineIdMap, machineTasksCache, entryIndexById, machineOption, chromosome, machineIdMap, machineTasksCache, entryIndexById,
scheduleIndexById, dueDateForOp, true, opIsJit); scheduleIndexById, dueDateForOp, 0,true, opIsJit);
if (operationResult.isForwardFallbackRequired()) { if (operationResult.isForwardFallbackRequired()) {
// 倒排中任一道序因换型/日历约束放不下时,先撤回本订单已倒排结果,再整单正排。 // 倒排中任一道序因换型/日历约束放不下时,先撤回本订单已倒排结果,再整单正排。
clearOrderSchedulingForForwardFallback(chromosome, groupId, machineTasksCache, scheduleIndexById); List<Integer> removeOp= clearOrderSchedulingForForwardFallback(chromosome, groupId, machineTasksCache, scheduleIndexById);
int forwardEndTime = scheduleOrderForwardFallback(groupId, chromosome, machineIdMap, machineTasksCache,
if(operationResult.getStartTime()==0)
{
removeOp.clear();
}
int forwardEndTime = scheduleOrderForwardFallback(groupId, removeOp,0, chromosome,entrysBygroupId, machineIdMap, machineTasksCache,
entryIndexById, scheduleIndexById, opMachineKeyMap); entryIndexById, scheduleIndexById, opMachineKeyMap);
orderProcessCounter.put(groupId, entrysBygroupId.get(groupId).size()); orderProcessCounter.put(groupId, entrysBygroupId.get(groupId).size());
orderLastEndTime.put(groupId, forwardEndTime); orderLastEndTime.put(groupId, forwardEndTime);
forwardFallbackOrderIds.add(groupId); forwardFallbackOrderIds.add(groupId);
//如果是半成品
if (semiFinishedOrderIds.contains(groupId)) { if (semiFinishedOrderIds.contains(groupId)) {
Set<Integer> fallbackFinishedIds = new HashSet<>(); Set<Integer> fallbackFinishedIds = new HashSet<>();
List<Integer> targetFinishedOpIds = currentOp.getTargetFinishedOperationId(); List<Integer> targetFinishedOpIds = currentOp.getTargetFinishedOperationId();
...@@ -794,7 +825,7 @@ if(groupId==7) ...@@ -794,7 +825,7 @@ if(groupId==7)
} }
} }
} }
reForwardFinishedOrders(groupId, fallbackFinishedIds, reForwardFinishedOrders(groupId,forwardEndTime, fallbackFinishedIds,
chromosome, machineTasksCache, scheduleIndexById, chromosome, machineTasksCache, scheduleIndexById,
machineIdMap, entryIndexById, opMachineKeyMap, machineIdMap, entryIndexById, opMachineKeyMap,
entrysBygroupId, orderProcessCounter, orderLastEndTime, entrysBygroupId, orderProcessCounter, orderLastEndTime,
...@@ -810,20 +841,32 @@ if(groupId==7) ...@@ -810,20 +841,32 @@ if(groupId==7)
orderProcessCounter.put(groupId, orderProcessCounter.get(groupId) + 1); orderProcessCounter.put(groupId, orderProcessCounter.get(groupId) + 1);
orderLastEndTime.put(groupId, actualEndTime); orderLastEndTime.put(groupId, actualEndTime);
if (orderProcessCounter.get(groupId) >= entrysBygroupId.get(groupId).size()) {
if (semiFinishedOrderIds.contains(groupId) && // if (jitDeferredBomOrderIds.remove(groupId)) {
orderProcessCounter.get(groupId) >= entrysBygroupId.get(groupId).size()) { // entrysBygroupId.get(groupId).stream()
Set<Integer> pendingFinishedIds = pendingReForwardMap.remove(groupId); // .sorted(Comparator.comparingInt(Entry::getSequence))
if (pendingFinishedIds != null && !pendingFinishedIds.isEmpty()) { // .forEach(op -> {
int semiEndTime = orderLastEndTime.get(groupId); // GAScheduleResult result = scheduleIndexById.get(op.getId());
FileHelper.writeLogFile("[ReForward] 半成品" + groupId // if (result != null) {
+ "全部排完(结束时间=" + semiEndTime + "),重新正排关联成品" // EditOperationBOMTime(op, chromosome, result.getStartTime(),
+ pendingFinishedIds); // machineTasksCache, entryIndexById,
reForwardFinishedOrders(groupId, pendingFinishedIds, // scheduleIndexById);
chromosome, machineTasksCache, scheduleIndexById, // }
machineIdMap, entryIndexById, opMachineKeyMap, // });
entrysBygroupId, orderProcessCounter, orderLastEndTime, // }
forwardFallbackOrderIds, orderSchedulingInfo); if (semiFinishedOrderIds.contains(groupId)) {
Set<Integer> pendingFinishedIds = pendingReForwardMap.remove(groupId);
if (pendingFinishedIds != null && !pendingFinishedIds.isEmpty()) {
int semiEndTime = orderLastEndTime.get(groupId);
FileHelper.writeLogFile("[ReForward] 半成品" + groupId
+ "全部排完(结束时间=" + semiEndTime + "),重新正排关联成品"
+ pendingFinishedIds);
reForwardFinishedOrders(groupId,semiEndTime, pendingFinishedIds,
chromosome, machineTasksCache, scheduleIndexById,
machineIdMap, entryIndexById, opMachineKeyMap,
entrysBygroupId, orderProcessCounter, orderLastEndTime,
forwardFallbackOrderIds, orderSchedulingInfo);
}
} }
} }
} }
...@@ -848,7 +891,7 @@ if(groupId==7) ...@@ -848,7 +891,7 @@ if(groupId==7)
int isnew= generateGlobalOpList(chromosome); int isnew= generateGlobalOpList(chromosome);
if(isnew==1) { if(isnew==1) {
CreateNewOpSequence(chromosome, _globalParam.isJit()); CreateNewOpSequence(chromosome,null,null, _globalParam.isJit());
// CreateNewOpSequence 会重建半成品插入顺序,生成后再规整一次,避免重复调度同一订单。 // CreateNewOpSequence 会重建半成品插入顺序,生成后再规整一次,避免重复调度同一订单。
normalizeOperationSequencing(chromosome); normalizeOperationSequencing(chromosome);
} }
...@@ -1287,20 +1330,31 @@ if(groupId==7) ...@@ -1287,20 +1330,31 @@ if(groupId==7)
/** /**
* 倒排兜底:当前订单已排结果清掉后,按 sequence 从小到大重新正排整单。 * 倒排兜底:当前订单已排结果清掉后,按 sequence 从小到大重新正排整单。
*/ */
private int scheduleOrderForwardFallback(int groupId, private int scheduleOrderForwardFallback(int groupId,List<Integer> removeOp,int starttime,
Chromosome chromosome, Chromosome chromosome,Map<Integer, List<Entry>> entrysBygroupId,
Map<Long, Machine> machineIdMap, Map<Long, Machine> machineIdMap,
Map<Long, CopyOnWriteArrayList<GAScheduleResult>> machineTasksCache, Map<Long, CopyOnWriteArrayList<GAScheduleResult>> machineTasksCache,
Map<Integer, Entry> entryIndexById, Map<Integer, Entry> entryIndexById,
Map<Integer, GAScheduleResult> scheduleIndexById, Map<Integer, GAScheduleResult> scheduleIndexById,
Map<String, OpMachine> opMachineKeyMap) { Map<String, OpMachine> opMachineKeyMap) {
List<Entry> orderOps = chromosome.getAllOperations().stream() List<Entry> orderOps =entrysBygroupId.get(groupId);
.filter(t -> t.getGroupId() == groupId) List<Entry> operations=new ArrayList<>();
.sorted(Comparator.comparing(Entry::getSequence)) if(removeOp!=null&&removeOp.size()>0)
.collect(Collectors.toList()); {
operations= orderOps.stream()
.filter(t ->removeOp.contains(t.getId()))
.sorted(Comparator.comparing(Entry::getSequence))
.collect(Collectors.toList());
}else {
operations= orderOps.stream()
int finalEndTime = 0; .sorted(Comparator.comparing(Entry::getSequence))
for (Entry currentOp : orderOps) { .collect(Collectors.toList());
}
int finalEndTime = starttime;
for (Entry currentOp : operations) {
String opMachineKey = groupId + "_" + currentOp.getSequence(); String opMachineKey = groupId + "_" + currentOp.getSequence();
OpMachine machineOption = opMachineKeyMap.get(opMachineKey); OpMachine machineOption = opMachineKeyMap.get(opMachineKey);
if (machineOption == null) { if (machineOption == null) {
...@@ -1311,7 +1365,7 @@ if(groupId==7) ...@@ -1311,7 +1365,7 @@ if(groupId==7)
OperationScheduleResult operationResult = processOperationSchedule(currentOp, machineOption.getMachineId(), OperationScheduleResult operationResult = processOperationSchedule(currentOp, machineOption.getMachineId(),
machineOption.getProcessingTime(), machineOption, chromosome, machineIdMap, machineOption.getProcessingTime(), machineOption, chromosome, machineIdMap,
machineTasksCache, entryIndexById, scheduleIndexById, 0, true, false); machineTasksCache, entryIndexById, scheduleIndexById, 0, 0,true, false);
if (operationResult.isForwardFallbackRequired()) { if (operationResult.isForwardFallbackRequired()) {
throw new IllegalStateException("正排兜底过程中不应再次触发正排兜底,groupId=" + groupId throw new IllegalStateException("正排兜底过程中不应再次触发正排兜底,groupId=" + groupId
+ ", operationId=" + currentOp.getId()); + ", operationId=" + currentOp.getId());
...@@ -1324,14 +1378,17 @@ if(groupId==7) ...@@ -1324,14 +1378,17 @@ if(groupId==7)
/** /**
* 整单正排前先撤回本订单已经写入的倒排结果,同时归还机台可用时间。 * 整单正排前先撤回本订单已经写入的倒排结果,同时归还机台可用时间。
*/ */
private void clearOrderSchedulingForForwardFallback(Chromosome chromosome, private List<Integer> clearOrderSchedulingForForwardFallback(Chromosome chromosome,
int groupId, int groupId,
Map<Long, CopyOnWriteArrayList<GAScheduleResult>> machineTasksCache, Map<Long, CopyOnWriteArrayList<GAScheduleResult>> machineTasksCache,
Map<Integer, GAScheduleResult> scheduleIndexById) { Map<Integer, GAScheduleResult> scheduleIndexById) {
List<GAScheduleResult> resultsToRemove = chromosome.getResult().stream() List<GAScheduleResult> resultsToRemove = chromosome.getResult().stream()
.filter(t -> t.getGroupId() == groupId) .filter(t -> t.getGroupId() == groupId)
.collect(Collectors.toList()); .collect(Collectors.toList());
List<Integer> operations=new ArrayList<>();
for (GAScheduleResult result : resultsToRemove) { for (GAScheduleResult result : resultsToRemove) {
operations.add(result.getOperationId());
Machine machine = getMachineById(chromosome, result.getMachineId()); Machine machine = getMachineById(chromosome, result.getMachineId());
if (machine != null) { if (machine != null) {
AddMachineAvailable(machine, result.getGeneDetails()); AddMachineAvailable(machine, result.getGeneDetails());
...@@ -1344,7 +1401,9 @@ if(groupId==7) ...@@ -1344,7 +1401,9 @@ if(groupId==7)
machineTasks.removeIf(t -> t.getOperationId() == result.getOperationId()); machineTasks.removeIf(t -> t.getOperationId() == result.getOperationId());
} }
} }
machineTasksCache.clear(); machineTasksCache.clear();
return operations;
} }
...@@ -1359,7 +1418,7 @@ if(groupId==7) ...@@ -1359,7 +1418,7 @@ if(groupId==7)
int orderDueDate, boolean islockMachineTime, boolean isJit) { int orderDueDate, boolean islockMachineTime, boolean isJit) {
OperationScheduleResult result = processOperationSchedule(currentOp, machineId, processTime, machineOption, OperationScheduleResult result = processOperationSchedule(currentOp, machineId, processTime, machineOption,
chromosome, machineIdMap, machineTasksCache, entryIndexById, scheduleIndexById, chromosome, machineIdMap, machineTasksCache, entryIndexById, scheduleIndexById,
orderDueDate, islockMachineTime, isJit); orderDueDate,0, islockMachineTime, isJit);
return result.getEndTime(); return result.getEndTime();
} }
...@@ -1369,9 +1428,9 @@ if(groupId==7) ...@@ -1369,9 +1428,9 @@ if(groupId==7)
Map<Long, CopyOnWriteArrayList<GAScheduleResult>> machineTasksCache, Map<Long, CopyOnWriteArrayList<GAScheduleResult>> machineTasksCache,
Map<Integer, Entry> entryIndexById, Map<Integer, Entry> entryIndexById,
Map<Integer, GAScheduleResult> scheduleIndexById, Map<Integer, GAScheduleResult> scheduleIndexById,
int orderDueDate, boolean islockMachineTime, boolean isJit) { int orderDueDate,int starttime, boolean islockMachineTime, boolean isJit) {
Machine targetMachine = machineIdMap.get(machineId); Machine targetMachine = machineIdMap.get(machineId);
int prevtime = 0; int prevtime = starttime;
if (isJit) { if (isJit) {
// 倒排边界来自订单交期/锚点;如果存在后道序,则以后道序约束继续往前推。 // 倒排边界来自订单交期/锚点;如果存在后道序,则以后道序约束继续往前推。
prevtime = orderDueDate; prevtime = orderDueDate;
...@@ -1380,7 +1439,7 @@ if(groupId==7) ...@@ -1380,7 +1439,7 @@ if(groupId==7)
entryIndexById, scheduleIndexById); entryIndexById, scheduleIndexById);
} }
} else { } else {
if (!currentOp.getPrevEntryIds().isEmpty()) { if (!currentOp.getPrevEntryIds().isEmpty()&&starttime==0) {
// 正排边界来自前道序完成时间。 // 正排边界来自前道序完成时间。
prevtime = CalPrevtime(prevtime, currentOp, chromosome, processTime, targetMachine, prevtime = CalPrevtime(prevtime, currentOp, chromosome, processTime, targetMachine,
entryIndexById, scheduleIndexById); entryIndexById, scheduleIndexById);
...@@ -1401,7 +1460,7 @@ if(groupId==7) ...@@ -1401,7 +1460,7 @@ if(groupId==7)
Map<Integer, GAScheduleResult> scheduleIndexById, Map<Integer, GAScheduleResult> scheduleIndexById,
int orderDueDate, boolean islockMachineTime, boolean isJit) { int orderDueDate, boolean islockMachineTime, boolean isJit) {
return processOperationSchedule(currentOp, machineId, processTime, machineOption, chromosome, machineIdMap, return processOperationSchedule(currentOp, machineId, processTime, machineOption, chromosome, machineIdMap,
machineTasksCache, entryIndexById, scheduleIndexById, orderDueDate, islockMachineTime, isJit) machineTasksCache, entryIndexById, scheduleIndexById, orderDueDate, 0,islockMachineTime, isJit)
.getScheduleResult(); .getScheduleResult();
} }
...@@ -1505,10 +1564,12 @@ if(groupId==7) ...@@ -1505,10 +1564,12 @@ if(groupId==7)
GAScheduleResult lastGeneOnMachine = getLastMachineTask(machineTasks); GAScheduleResult lastGeneOnMachine = getLastMachineTask(machineTasks);
int bomtime = 0; int bomtime = 0;
if (needMaterialCheck&&islockMachineTime) { if (needMaterialCheck&&islockMachineTime) {
if(!isJit) { if(!isJit) {
//正排获取半成品结束时间,如果没有半成品获取原材料时间
bomtime = getOperationBOMTime(operation, chromosome, earliestStartTime, 2); bomtime = getOperationBOMTime(operation, chromosome, earliestStartTime, 2);
earliestStartTime = Math.max(earliestStartTime, bomtime); earliestStartTime = Math.max(earliestStartTime, bomtime);
//倒排需要工序排完再验证原材料,保证bom供应商就行
FileHelper.writeLogFile("工序:"+operation.getId()+ "BOMTIME:"+bomtime);
} }
} }
...@@ -1590,8 +1651,9 @@ if(groupId==7) ...@@ -1590,8 +1651,9 @@ if(groupId==7)
// ", 前处理: " + preTime + ", 换型: " + setupTime + ", 数量: " + operation.getQuantity() + ", 设备: " + machine.getId() + ", 是否可中断: " + operation.getIsInterrupt()); // ", 前处理: " + preTime + ", 换型: " + setupTime + ", 数量: " + operation.getQuantity() + ", 设备: " + machine.getId() + ", 是否可中断: " + operation.getIsInterrupt());
} }
return OperationScheduleResult.forwardFallback();
return OperationScheduleResult.success(null);
} }
...@@ -1642,14 +1704,40 @@ if(groupId==7) ...@@ -1642,14 +1704,40 @@ if(groupId==7)
//扣库存 //扣库存
if (needMaterialCheck && islockMachineTime) { if (needMaterialCheck && islockMachineTime) {
if(!isJit) { if(!isJit) {
//修改原材料采购时间
EditOperationBOMTime(operation, chromosome, startTime, machineTasksCache, entryIndexById, scheduleIndexById); EditOperationBOMTime(operation, chromosome, startTime, machineTasksCache, entryIndexById, scheduleIndexById);
}else { }else {
int bomtime1 = getOperationBOMTime(operation, chromosome, startTime, 2);
if(bomtime1<=startTime) Long maxPurchase = operation.getMaterialRequirements().stream()
.filter(t -> "MP".equals(t.getMaterialTypeName())
||( t.getProductOrderID() == null && t.getProductOrderID().isEmpty()))
.map(item -> {
Long pt = item.getPurchaseTime() == null ? 0L : item.getPurchaseTime();
Integer lead = item.getCheckLeadTime() == null ? 0 : item.getCheckLeadTime();
return pt + lead;
})
.max(Long::compareTo).orElse(0L)*24*60*60;
if(maxPurchase>startTime)
{ {
EditOperationBOMTime(operation, chromosome, startTime, machineTasksCache, entryIndexById, scheduleIndexById); int bomtime1 = getOperationBOMTime(operation, chromosome, startTime, 3);
if(bomtime1>startTime)
{
if (isJit && islockMachineTime) {
OperationScheduleResult result= OperationScheduleResult.forwardFallback();
result.setStartTime(bomtime1);
return result;
}
}else
{
// EditOperationBOMTime(operation, chromosome, startTime, machineTasksCache, entryIndexById, scheduleIndexById);
}
} }
} }
} }
//换型时间是否占用设备加工时间 //换型时间是否占用设备加工时间
...@@ -2071,21 +2159,27 @@ if(geneDetails!=null&&geneDetails.size()>0) ...@@ -2071,21 +2159,27 @@ if(geneDetails!=null&&geneDetails.size()>0)
*/ */
private static class OperationScheduleResult { private static class OperationScheduleResult {
private final GAScheduleResult scheduleResult; private final GAScheduleResult scheduleResult;
private int startTime;
private final boolean forwardFallbackRequired; private final boolean forwardFallbackRequired;
private OperationScheduleResult(GAScheduleResult scheduleResult, boolean forwardFallbackRequired) { private OperationScheduleResult(GAScheduleResult scheduleResult, boolean forwardFallbackRequired,int startTime) {
this.scheduleResult = scheduleResult; this.scheduleResult = scheduleResult;
this.forwardFallbackRequired = forwardFallbackRequired; this.forwardFallbackRequired = forwardFallbackRequired;
this.startTime=startTime;
} }
private static OperationScheduleResult success(GAScheduleResult scheduleResult) { private static OperationScheduleResult success(GAScheduleResult scheduleResult) {
return new OperationScheduleResult(scheduleResult, false); return new OperationScheduleResult(scheduleResult, false,0);
} }
private static OperationScheduleResult forwardFallback() { private static OperationScheduleResult forwardFallback() {
return new OperationScheduleResult(null, true); return new OperationScheduleResult(null, true,0);
}
public int getStartTime() {
return startTime;
} }
public void setStartTime(int startTime){this.startTime=startTime;}
private GAScheduleResult getScheduleResult() { private GAScheduleResult getScheduleResult() {
return scheduleResult; return scheduleResult;
} }
...@@ -2287,7 +2381,8 @@ if(geneDetails!=null&&geneDetails.size()>0) ...@@ -2287,7 +2381,8 @@ if(geneDetails!=null&&geneDetails.size()>0)
private int getOperationBOMTime(Entry currentOp, Chromosome chromosome,int estimatedStartTime,int bomtype) { private int getOperationBOMTime(Entry currentOp, Chromosome chromosome,int estimatedStartTime,int bomtype) {
List<OrderMaterialRequirement> opboms= currentOp.getMaterialRequirements(); List<OrderMaterialRequirement> opboms= currentOp.getMaterialRequirements();
if(opboms==null||!_globalParam.isIsCheckMp()) //if(opboms==null||!_globalParam.isIsCheckMp())
if(opboms==null)
{ {
return 0; return 0;
} }
...@@ -2298,7 +2393,7 @@ if(geneDetails!=null&&geneDetails.size()>0) ...@@ -2298,7 +2393,7 @@ if(geneDetails!=null&&geneDetails.size()>0)
// 计算RawTime // 计算RawTime
if (bomtype == 0 || bomtype == 1) { if (bomtype == 0 || bomtype == 1) {
Optional<LocalDateTime> rawDateOpt = opboms.stream() Optional<LocalDateTime> rawDateOpt = opboms.stream()
.filter(t -> "MP".equals(t.getMaterialTypeName())) .filter(t -> "MP".equals(t.getMaterialTypeName())||( t.getProductOrderID() == null || t.getProductOrderID().isEmpty()))
.map(OrderMaterialRequirement::getUseTime) .map(OrderMaterialRequirement::getUseTime)
.filter(Objects::nonNull) .filter(Objects::nonNull)
.max(LocalDateTime::compareTo); .max(LocalDateTime::compareTo);
...@@ -2384,6 +2479,46 @@ if(geneDetails!=null&&geneDetails.size()>0) ...@@ -2384,6 +2479,46 @@ if(geneDetails!=null&&geneDetails.size()>0)
} }
} }
if ( bomtype == 3) {
Map<String, OrderMaterialRequirement> totalNeededByMaterial = new HashMap<>();
List<OrderMaterialRequirement> mpBoms = opboms.stream()
.filter(t -> "MP".equals(t.getMaterialTypeName())
||( t.getProductOrderID() == null && t.getProductOrderID().isEmpty()))
.collect(Collectors.toList());
for (OrderMaterialRequirement req : mpBoms) {
OrderMaterialRequirement reqq = totalNeededByMaterial.get(req.getMaterialId());
if (reqq != null) {
double allneeded = req.getSpentQty() / req.getMainQty() * currentOp.getQuantity();
allneeded = reqq.getRequiredQuantity() + allneeded;
reqq.setRequiredQuantity(allneeded);
reqq.setQjQty(allneeded);
} else {
OrderMaterialRequirement reqq1 = ProductionDeepCopyUtil.deepCopy(req);
double allneeded = req.getSpentQty() / req.getMainQty() * currentOp.getQuantity();
reqq1.setRequiredQuantity(allneeded);
reqq1.setQjQty(allneeded);
totalNeededByMaterial.put(req.getMaterialId(), reqq1);
}
}
List<OrderMaterialRequirement> remove=new ArrayList<>();
materialRequirementService.CalBom(chromosome,0, totalNeededByMaterial,chromosome.getMaterials(),baseTime.plusSeconds(estimatedStartTime) ,false,remove,null,false);
Optional<LocalDateTime> rawDateOpt = totalNeededByMaterial.values().stream()
.map(OrderMaterialRequirement::getUseTime)
.filter(Objects::nonNull)
.max(LocalDateTime::compareTo);
if (rawDateOpt.isPresent()) {
rawTime = (int) Duration.between(baseTime, rawDateOpt.get()).getSeconds();
}
}
} }
return Math.max(rawTime, sfTime); return Math.max(rawTime, sfTime);
} }
...@@ -3430,7 +3565,7 @@ if(geneDetails!=null&&geneDetails.size()>0) ...@@ -3430,7 +3565,7 @@ if(geneDetails!=null&&geneDetails.size()>0)
orders.removeIf(t ->newoorderids.contains(t.getId())); orders.removeIf(t ->newoorderids.contains(t.getId()));
} }
} }
private void reForwardFinishedOrders(int semiOrderId, private void reForwardFinishedOrders(int semiOrderId,int forwardEndTime,
Set<Integer> reForwardFinishedOrderIds, Set<Integer> reForwardFinishedOrderIds,
Chromosome chromosome, Chromosome chromosome,
Map<Long, CopyOnWriteArrayList<GAScheduleResult>> machineTasksCache, Map<Long, CopyOnWriteArrayList<GAScheduleResult>> machineTasksCache,
...@@ -3448,16 +3583,16 @@ if(geneDetails!=null&&geneDetails.size()>0) ...@@ -3448,16 +3583,16 @@ if(geneDetails!=null&&geneDetails.size()>0)
if (scheduledCount == 0) { if (scheduledCount == 0) {
continue; continue;
} }
clearOrderSchedulingForForwardFallback(chromosome, finishedId, List<Integer> removeOp= clearOrderSchedulingForForwardFallback(chromosome, finishedId,
machineTasksCache, scheduleIndexById); machineTasksCache, scheduleIndexById);
int forwardEndTime = scheduleOrderForwardFallback(finishedId, int forwardEndTime1 = scheduleOrderForwardFallback(finishedId,removeOp,forwardEndTime,
chromosome, machineIdMap, machineTasksCache, chromosome,entrysBygroupId, machineIdMap, machineTasksCache,
entryIndexById, scheduleIndexById, opMachineKeyMap); entryIndexById, scheduleIndexById, opMachineKeyMap);
orderProcessCounter.put(finishedId, orderProcessCounter.put(finishedId,
entrysBygroupId.get(finishedId).size()); entrysBygroupId.get(finishedId).size());
orderLastEndTime.put(finishedId, forwardEndTime); orderLastEndTime.put(finishedId, forwardEndTime1);
forwardFallbackOrderIds.add(finishedId); forwardFallbackOrderIds.add(finishedId);
orderSchedulingInfo.put(finishedId, orderSchedulingInfo.put(finishedId,
new AbstractMap.SimpleEntry<>(false, 0)); new AbstractMap.SimpleEntry<>(false, 0));
......
...@@ -408,37 +408,21 @@ if(isJit) ...@@ -408,37 +408,21 @@ if(isJit)
if (targetFinishedOpIds == null || targetFinishedOpIds.isEmpty()) { if (targetFinishedOpIds == null || targetFinishedOpIds.isEmpty()) {
return 0; return 0;
} }
int start=Integer.MAX_VALUE;
// 找关联的成品订单 for (Integer targetFinishedOpId :targetFinishedOpIds) {
int finishedOrderId = -1;
Entry targetFinishedOp = null;
for (Integer targetOpId : targetFinishedOpIds) { Entry finishedFirstOp = entryIndexById.get(targetFinishedOpId);
Entry op = entryIndexById.get(targetOpId); int finishedOrderId = finishedFirstOp.getGroupId();
if (op != null) { GAScheduleResult finishedFirstResult = scheduleIndexById.get(finishedFirstOp.getId());
targetFinishedOp = op; if (finishedFirstResult == null) {
finishedOrderId = op.getGroupId(); // 成品还没排(不应该发生在JIT模式),降级为原有逻辑
break; return computeSemiFinishedAnchor(decoder, semiOrderId, entrysBygroupId,
opMachineKeyMap, chromosome, scheduleIndexById, machineTasksCache,
machineIdMap, entryIndexById);
} }
}
if (finishedOrderId <= 0) return 0;
List<Entry> finishedOps = entrysBygroupId.get(finishedOrderId).stream()
.sorted(Comparator.comparing(Entry::getSequence))
.collect(Collectors.toList());
if (finishedOps.isEmpty()) return 0;
// JIT倒排模式成品已排完,直接从scheduleIndexById取成品第一道工序的开始时间
Entry finishedFirstOp = finishedOps.get(0);
GAScheduleResult finishedFirstResult = scheduleIndexById.get(finishedFirstOp.getId());
if (finishedFirstResult == null) {
// 成品还没排(不应该发生在JIT模式),降级为原有逻辑
return computeSemiFinishedAnchor(decoder, semiOrderId, entrysBygroupId,
opMachineKeyMap, chromosome, scheduleIndexById, machineTasksCache,
machineIdMap, entryIndexById);
}
String schedulingMode = finishedFirstOp.getSchedulingMode();
if (Entry.SchedulingMode.BACKWARD.name().equals(schedulingMode)) {
// 成品倒排成功 → 半成品倒排:锚点 = 成品开始时间 - 缓冲 // 成品倒排成功 → 半成品倒排:锚点 = 成品开始时间 - 缓冲
int semiLatestEndTime = finishedFirstResult.getStartTime(); int semiLatestEndTime = finishedFirstResult.getStartTime();
...@@ -446,35 +430,31 @@ if(isJit) ...@@ -446,35 +430,31 @@ if(isJit)
for (Entry op : sfOps) { for (Entry op : sfOps) {
String key = semiOrderId + "_" + op.getSequence(); String key = semiOrderId + "_" + op.getSequence();
OpMachine opt = opMachineKeyMap.get(key); OpMachine opt = opMachineKeyMap.get(key);
if (opt != null) semiTotalTime += calculateOperationProcessingTime(op, opt,_globalParam); if (opt != null) semiTotalTime += calculateOperationProcessingTime(op, opt, _globalParam);
} }
Material material= chromosome.getMaterials().get(order.getMaterialId()); Material material = chromosome.getMaterials().get(order.getMaterialId());
int ckeckLeadTime=0; int ckeckLeadTime = 0;
if(material.getCkeckLeadTime()!=null) if (material.getCkeckLeadTime() != null) {
{ ckeckLeadTime = (material.getCkeckLeadTime().intValue() * 24 * 60 * 60);
ckeckLeadTime=(material.getCkeckLeadTime().intValue()*24*60*60);
} }
semiTotalTime+=ckeckLeadTime; semiTotalTime += ckeckLeadTime;
if (semiLatestEndTime - semiTotalTime < 0) { if (semiLatestEndTime - semiTotalTime < 0) {
FileHelper.writeLogFile("[HybridSemi] 半成品" + semiOrderId + FileHelper.writeLogFile("[HybridSemi] 半成品" + semiOrderId +
" 倒排开工<0,正排+成品" + finishedOrderId + "重排"); " 倒排开工<0,正排+成品" + finishedOrderId + "重排");
reForwardFinishedOrderIds.add(finishedOrderId); reForwardFinishedOrderIds.add(finishedOrderId);
return -1; start= Math.min(start, -1);
}else {
FileHelper.writeLogFile("[HybridSemi] 半成品" + semiOrderId +
" 锚点=" + semiLatestEndTime + " (成品" + finishedOrderId +
"开始=" + finishedFirstResult.getStartTime() + ")");
start = Math.min(start, semiLatestEndTime - ckeckLeadTime);
} }
FileHelper.writeLogFile("[HybridSemi] 半成品" + semiOrderId +
" 锚点=" + semiLatestEndTime + " (成品" + finishedOrderId +
"开始=" + finishedFirstResult.getStartTime() + ")");
return semiLatestEndTime-ckeckLeadTime;
} else {
// 成品正排了 → 半成品也正排
FileHelper.writeLogFile("[HybridSemi] 成品" + finishedOrderId +
"已正排,半成品" + semiOrderId + "也正排");
reForwardFinishedOrderIds.add(finishedOrderId);
return -1;
} }
return start;
} }
private int calculateOperationProcessingTime(Entry op, OpMachine machineOption,GlobalParam _globalParam) { private int calculateOperationProcessingTime(Entry op, OpMachine machineOption,GlobalParam _globalParam) {
int total = 0; int total = 0;
......
...@@ -506,7 +506,10 @@ public class MachineCalculator { ...@@ -506,7 +506,10 @@ public class MachineCalculator {
} }
TimeSegment slot = GetCurrentOrNextShift(machine, currentTime, prevtime, checkprevtime,isJit); TimeSegment slot = GetCurrentOrNextShift(machine, currentTime, prevtime, checkprevtime,isJit);
if (slot == null) return times; if (slot == null)
{
return times;
}
LocalDateTime startCandidate=null; LocalDateTime startCandidate=null;
LocalDateTime endCandidate1= null; LocalDateTime endCandidate1= null;
LocalDateTime prevTimeDateTime = StringUtils.isEmpty(prevtime) ? null : LocalDateTime.parse(prevtime); LocalDateTime prevTimeDateTime = StringUtils.isEmpty(prevtime) ? null : LocalDateTime.parse(prevtime);
...@@ -1993,7 +1996,7 @@ public class MachineCalculator { ...@@ -1993,7 +1996,7 @@ public class MachineCalculator {
usedSegments.add(usedSegment); usedSegments.add(usedSegment);
TimeSegment usedSegment2=new TimeSegment(); TimeSegment usedSegment2=new TimeSegment();
usedSegment2.setStart(geneStartTime); usedSegment2.setStart(geneStartTime.plusSeconds(1));
usedSegment2.setEnd(geneEndTime); usedSegment2.setEnd(geneEndTime);
usedSegment2.setHoliday(false); usedSegment2.setHoliday(false);
usedSegment2.setKey(UUID.randomUUID().toString()); usedSegment2.setKey(UUID.randomUUID().toString());
...@@ -2026,7 +2029,7 @@ public class MachineCalculator { ...@@ -2026,7 +2029,7 @@ public class MachineCalculator {
} }
usedSegments.add(usedSegment); usedSegments.add(usedSegment);
geneDetails.setKey(usedSegment.getKey()); geneDetails.setKey(usedSegment.getKey());
targetSegment.setStart(geneEndTime); targetSegment.setStart(geneEndTime.plusSeconds(1));
}else if (targetSegment.getStart().isBefore(geneStartTime)) { }else if (targetSegment.getStart().isBefore(geneStartTime)) {
//换型时可能需要把前面的时间分割处理 //换型时可能需要把前面的时间分割处理
TimeSegment usedSegment=new TimeSegment(); TimeSegment usedSegment=new TimeSegment();
...@@ -2039,7 +2042,7 @@ public class MachineCalculator { ...@@ -2039,7 +2042,7 @@ public class MachineCalculator {
usedSegment.setKey(UUID.randomUUID().toString()); usedSegment.setKey(UUID.randomUUID().toString());
usedSegments.add(usedSegment); usedSegments.add(usedSegment);
geneDetails.setKey(targetSegment.getKey()); geneDetails.setKey(targetSegment.getKey());
targetSegment.setStart(geneStartTime); targetSegment.setStart(geneStartTime.plusSeconds(1));
if(islockMachineTime) if(islockMachineTime)
{ {
targetSegment.setUsed(true); targetSegment.setUsed(true);
......
...@@ -188,7 +188,7 @@ public class PlanResultService { ...@@ -188,7 +188,7 @@ public class PlanResultService {
try { try {
ScheduleParams param = InitScheduleParams(); ScheduleParams param = InitScheduleParams();
// param.setBaseTime(LocalDateTime.of(2026, 1, 1, 0, 0, 0)); // param.setBaseTime(LocalDateTime.of(2026, 5, 20, 0, 0, 0));
this.baseTime=param.getBaseTime(); this.baseTime=param.getBaseTime();
// 策略读取入口:优先使用前端传入的 userId;没传时用 sceneId 查场景创建人。 // 策略读取入口:优先使用前端传入的 userId;没传时用 sceneId 查场景创建人。
Long effectiveUserId = scheduleStrategyService.resolveScheduleUserId(SceneId, userId); Long effectiveUserId = scheduleStrategyService.resolveScheduleUserId(SceneId, userId);
......
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