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