Commit ccd683c2 authored by Tong Li's avatar Tong Li

倒排配套

parent da524907
...@@ -38,6 +38,7 @@ public class GAScheduleResult { ...@@ -38,6 +38,7 @@ public class GAScheduleResult {
private int lockStartTime = 0; // 是否固定开始时间(默认-1) private int lockStartTime = 0; // 是否固定开始时间(默认-1)
private Long forcedMachineId =-1L; // 强制分配的设备ID(-1表示无强制) private Long forcedMachineId =-1L; // 强制分配的设备ID(-1表示无强制)
private boolean IsLocked=false; private boolean IsLocked=false;
private boolean IsJit=false;
private double OneTime; // 单件工时 private double OneTime; // 单件工时
private double ProcessingTime; // 绝对处理时间(分钟) private double ProcessingTime; // 绝对处理时间(分钟)
private int changeOverTime; private int changeOverTime;
......
...@@ -863,19 +863,49 @@ public class GeneticDecoder { ...@@ -863,19 +863,49 @@ public class GeneticDecoder {
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 (isJit&& orderProcessCounter.get(groupId) >= entrysBygroupId.get(groupId).size()) {
// if (jitDeferredBomOrderIds.remove(groupId)) {
// entrysBygroupId.get(groupId).stream() List<Entry> orderOpsBySeq = entrysBygroupId.get(groupId).stream()
// .sorted(Comparator.comparingInt(Entry::getSequence)) .sorted(Comparator.comparingInt(Entry::getSequence))
// .forEach(op -> { .collect(Collectors.toList());
// GAScheduleResult result = scheduleIndexById.get(op.getId()); boolean bomFailed = false;
// if (result != null) { int failedSeq = -1;
// EditOperationBOMTime(op, chromosome, result.getStartTime(), int failedBomTime = 0;
// machineTasksCache, entryIndexById, for (Entry op : orderOpsBySeq) {
// scheduleIndexById); GAScheduleResult result = scheduleIndexById.get(op.getId());
// } if (result == null||!result.isIsJit()) continue;
// }); int bomTime = getOperationBOMTime(op, chromosome, result.getStartTime(), 3,_globalParam.isIsCheckMp());
// } if (bomTime <= result.getStartTime()) {
EditOperationBOMTime(op, chromosome, result.getStartTime(),
machineTasksCache, entryIndexById,
scheduleIndexById);
} else {
bomFailed = true;
failedSeq = op.getSequence();
failedBomTime = bomTime;
break;
}
}
if (bomFailed) {
int finalFailedSeq = failedSeq;
Set<Integer> keepOpIds = orderOpsBySeq.stream()
.filter(op -> op.getSequence() < finalFailedSeq)
.map(Entry::getId)
.collect(Collectors.toSet());
FileHelper.writeLogFile("[BomFallback] 订单" + groupId
+ "工序" + failedSeq + "物料不足(bomTime="
+ failedBomTime + " > startTime),从该工序开始正排");
List<Integer> removeOp = clearOrderSchedulingForForwardFallback(chromosome, groupId,
machineTasksCache, scheduleIndexById,entryIndexById, keepOpIds);
int forwardEndTime = scheduleOrderForwardFallback(groupId,removeOp,failedBomTime,
chromosome,entrysBygroupId, machineIdMap, machineTasksCache,
entryIndexById, scheduleIndexById, opMachineKeyMap);
forwardFallbackOrderIds.add(groupId);
orderSchedulingInfo.put(groupId,
new AbstractMap.SimpleEntry<>(false, 0));
orderLastEndTime.put(groupId, forwardEndTime);
}
if (semiFinishedOrderIds.contains(groupId)) { if (semiFinishedOrderIds.contains(groupId)) {
Set<Integer> pendingFinishedIds = pendingReForwardMap.remove(groupId); Set<Integer> pendingFinishedIds = pendingReForwardMap.remove(groupId);
if (pendingFinishedIds != null && !pendingFinishedIds.isEmpty()) { if (pendingFinishedIds != null && !pendingFinishedIds.isEmpty()) {
...@@ -1439,10 +1469,21 @@ public class GeneticDecoder { ...@@ -1439,10 +1469,21 @@ public class GeneticDecoder {
private List<Integer> 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,Map<Integer, Entry> entryIndexById,Set<Integer> keepOpIds) {
List<GAScheduleResult> resultsToRemove = chromosome.getResult().stream() List<GAScheduleResult> resultsToRemove=new ArrayList<>();
if(keepOpIds!=null&&keepOpIds.size()>0)
{
resultsToRemove = chromosome.getResult().stream()
.filter(t -> t.getGroupId() == groupId) .filter(t -> t.getGroupId() == groupId)
.filter(t -> !keepOpIds.contains(t.getOperationId()))
.collect(Collectors.toList()); .collect(Collectors.toList());
}else {
resultsToRemove = chromosome.getResult().stream()
.filter(t -> t.getGroupId() == groupId)
.collect(Collectors.toList());
}
List<Integer> operations=new ArrayList<>(); List<Integer> operations=new ArrayList<>();
for (GAScheduleResult result : resultsToRemove) { for (GAScheduleResult result : resultsToRemove) {
...@@ -1458,6 +1499,14 @@ public class GeneticDecoder { ...@@ -1458,6 +1499,14 @@ public class GeneticDecoder {
if (machineTasks != null) { if (machineTasks != null) {
machineTasks.removeIf(t -> t.getOperationId() == result.getOperationId()); machineTasks.removeIf(t -> t.getOperationId() == result.getOperationId());
} }
Entry op= entryIndexById.get(result.getOperationId());
Map<String, MaterialDeduction> deductions = readOperationStockDeductions(op);
if (deductions != null && !deductions.isEmpty()) {
rollbackOperationStockDeduction(chromosome, deductions);
}
} }
machineTasksCache.clear(); machineTasksCache.clear();
...@@ -1488,8 +1537,13 @@ public class GeneticDecoder { ...@@ -1488,8 +1537,13 @@ public class GeneticDecoder {
for (GAScheduleResult result : resultsToRemove) { for (GAScheduleResult result : resultsToRemove) {
Entry op= entrysBygroupId.get(result.getGroupId()).get(result.getOperationId());
Map<String, MaterialDeduction> deductions = readOperationStockDeductions(op);
if (deductions != null && !deductions.isEmpty()) {
rollbackOperationStockDeduction(chromosome, deductions);
}
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());
...@@ -1633,8 +1687,8 @@ public class GeneticDecoder { ...@@ -1633,8 +1687,8 @@ public class GeneticDecoder {
endTime = startTime + processingTimeTotal; endTime = startTime + processingTimeTotal;
} }
GAScheduleResult result = CreateResult(operation, machine.getId(), startTime, endTime, processingTime, 0, preTime, teardownTime, 0, null, existingResult); GAScheduleResult result = CreateResult(operation, machine.getId(), startTime, endTime, processingTime, 0, preTime, teardownTime, 0, null, existingResult,machine.getCapacityTypeName(),isJit);
result.setCapacityTypeName(machine.getCapacityTypeName());
if(islockMachineTime) { if(islockMachineTime) {
chromosome.getResult().add(result); chromosome.getResult().add(result);
machine.setLastGene(result); machine.setLastGene(result);
...@@ -1849,8 +1903,8 @@ public class GeneticDecoder { ...@@ -1849,8 +1903,8 @@ public class GeneticDecoder {
// 后处理时间 相同任务的前一工序的结束时间+后处理时间 =当前工序最早开工时间 // 后处理时间 相同任务的前一工序的结束时间+后处理时间 =当前工序最早开工时间
GAScheduleResult result = CreateResult(operation, machine.getId(), startTime, endTime, processingTime, setupTime, preTime, teardownTime, bomtime, geneDetails, existingResult); GAScheduleResult result = CreateResult(operation, machine.getId(), startTime, endTime, processingTime, setupTime, preTime, teardownTime, bomtime, geneDetails, existingResult,machine.getCapacityTypeName(),isJit);
result.setCapacityTypeName(machine.getCapacityTypeName());
// System.out.println("huanxingshijian="+result.getChangeOverTime()+"-------------------"+result.getOrderId()+"--------"+result.getExecId()+"---------"+prev.getOrderId()+"--------"+prev.getExecId()); // System.out.println("huanxingshijian="+result.getChangeOverTime()+"-------------------"+result.getOrderId()+"--------"+result.getExecId()+"---------"+prev.getOrderId()+"--------"+prev.getExecId());
if (islockMachineTime) if (islockMachineTime)
...@@ -2073,12 +2127,13 @@ public class GeneticDecoder { ...@@ -2073,12 +2127,13 @@ public class GeneticDecoder {
private GAScheduleResult CreateResult(Entry operation,long machineId private GAScheduleResult CreateResult(Entry operation,long machineId
,int startTime,int endTime,double processingTime ,int startTime,int endTime,double processingTime
,int setupTime,int preTime,int teardownTime,int bomtime ,int setupTime,int preTime,int teardownTime,int bomtime
,CopyOnWriteArrayList<ScheduleResultDetail> geneDetails,GAScheduleResult existingResult ) ,CopyOnWriteArrayList<ScheduleResultDetail> geneDetails,GAScheduleResult existingResult,String capacityTypeName,boolean isJit )
{ {
GAScheduleResult result=new GAScheduleResult(); GAScheduleResult result=new GAScheduleResult();
result.setGroupId(operation.getGroupId()); result.setGroupId(operation.getGroupId());
result.setOperationId(operation.getId()); result.setOperationId(operation.getId());
result.setIsJit(isJit);
result.setExecId(operation.getExecId()); result.setExecId(operation.getExecId());
result.setOrderId(operation.getOrderId()); result.setOrderId(operation.getOrderId());
result.setOrderCode(operation.getOrderCode()); result.setOrderCode(operation.getOrderCode());
...@@ -2089,6 +2144,7 @@ public class GeneticDecoder { ...@@ -2089,6 +2144,7 @@ public class GeneticDecoder {
? null ? null
: new ArrayList<>(operation.getTargetFinishedOperationId())); : new ArrayList<>(operation.getTargetFinishedOperationId()));
result.setMachineId(machineId); result.setMachineId(machineId);
result.setCapacityTypeName(capacityTypeName);
result.setStartTime(startTime); result.setStartTime(startTime);
result.setEndTime(endTime); result.setEndTime(endTime);
result.setOneTime(processingTime); result.setOneTime(processingTime);
...@@ -3681,8 +3737,8 @@ if(geneDetails!=null&&geneDetails.size()>0) ...@@ -3681,8 +3737,8 @@ if(geneDetails!=null&&geneDetails.size()>0)
if (scheduledCount == 0) { if (scheduledCount == 0) {
continue; continue;
} }
List<Integer> removeOp= clearOrderSchedulingForForwardFallback(chromosome, finishedId, List<Integer> removeOp = clearOrderSchedulingForForwardFallback(chromosome, finishedId,
machineTasksCache, scheduleIndexById); machineTasksCache, scheduleIndexById,entryIndexById,null);
int forwardEndTime1 = scheduleOrderForwardFallback(finishedId,removeOp,forwardEndTime, int forwardEndTime1 = scheduleOrderForwardFallback(finishedId,removeOp,forwardEndTime,
chromosome,entrysBygroupId, machineIdMap, machineTasksCache, chromosome,entrysBygroupId, machineIdMap, machineTasksCache,
...@@ -3700,4 +3756,105 @@ if(geneDetails!=null&&geneDetails.size()>0) ...@@ -3700,4 +3756,105 @@ if(geneDetails!=null&&geneDetails.size()>0)
reForwardFinishedOrderIds.clear(); reForwardFinishedOrderIds.clear();
} }
/**
* 物料扣减记录:区分库存扣减(useStock)和在途扣减(useTransit)
*/
private static class MaterialDeduction {
double useStock; // 占用库存(回滚时还原到 materialStocks)
double useTransit; // 占用在途(回滚时还原到 InTransit)
}
// 读工序扣减的库存记录:materialId → 扣减明细(含库存 + 在途 + 替换料)
private Map<String, MaterialDeduction> readOperationStockDeductions(Entry op) {
Map<String, MaterialDeduction> result = new HashMap<>();
List<OrderMaterialRequirement> requirements = op.getMaterialRequirements();
if (requirements != null) {
for (OrderMaterialRequirement req : requirements) {
// 替换料
double replaceStock=0;
double replaceTransit=0;
List<OrderMaterialRequirement> replaceMaterials = req.getReplaceMaterial();
if (replaceMaterials != null) {
for (OrderMaterialRequirement rep : replaceMaterials) {
replaceStock+=rep.getUseStock();
replaceTransit+=rep.getUseTransit();
mergeRequirementIntoDeduction(result, rep,0,0);
}
}
mergeRequirementIntoDeduction(result, req,replaceStock,replaceTransit);
}
}
return result;
}
private void mergeRequirementIntoDeduction(Map<String, MaterialDeduction> map,
OrderMaterialRequirement req,double replaceStock,double replaceTransit) {
double useStock = req.getUseStock()-replaceStock;
double useTransit = req.getUseTransit()-replaceTransit;
if (useStock <= 0 && useTransit <= 0) return;
MaterialDeduction ded = map.computeIfAbsent(req.getMaterialId(),
k -> new MaterialDeduction());
ded.useStock += useStock;
ded.useTransit += useTransit;
}
// 回滚已扣库存(含库存 + 在途)
private void rollbackOperationStockDeduction(Chromosome chromosome,
Map<String, MaterialDeduction> deductions) {
TreeMap<String, Material> materials = chromosome.getMaterials();
for (Map.Entry<String, MaterialDeduction> entry : deductions.entrySet()) {
String materialId = entry.getKey();
MaterialDeduction deduction = entry.getValue();
Material material = materials.get(materialId);
if (material == null) continue;
// 回滚库存:还原 materialStocks.usedInventory
if (deduction.useStock > 0) {
List<Stock> stocks = material.getMaterialStocks().stream()
.filter(t -> t.getUsedInventory() > 0)
.collect(Collectors.toList());
double remaining = deduction.useStock;
for (Stock s : stocks) {
double rollback1 = Math.min(remaining, s.getUsedInventory());
s.setUsedInventory(s.getUsedInventory() - rollback1);
remaining -= rollback1;
if (remaining <= 0) break;
}
if (remaining > 0) {
FileHelper.writeLogFile("[StockRollback] 物料" + material.getCode()
+ " 库存回滚不足,剩余=" + remaining);
}
}
// 回滚在途:还原 InTransit(MaterialSupply).Quantity
if (deduction.useTransit > 0) {
List<MaterialSupply> inTransit = material.getInTransit();
if (inTransit != null && !inTransit.isEmpty()) {
// 按到货时间顺序回滚(先到先回滚)
List<MaterialSupply> sorted = inTransit.stream()
.sorted(Comparator.comparing(MaterialSupply::getArrivalTime,
Comparator.nullsLast(Comparator.naturalOrder())))
.collect(Collectors.toList());
double remaining = deduction.useTransit;
for (MaterialSupply supply : sorted) {
double rollback1 = remaining;
supply.setQuantity(supply.getQuantity() + rollback1);
remaining -= rollback1;
if (remaining <= 0) break;
}
if (remaining > 0) {
FileHelper.writeLogFile("[StockRollback] 物料" + material.getCode()
+ " 在途回滚不足,剩余=" + remaining);
}
} else {
FileHelper.writeLogFile("[StockRollback] 物料" + material.getCode()
+ " 在途列表为空,无法回滚 useTransit=" + deduction.useTransit);
}
}
}
}
} }
...@@ -190,7 +190,7 @@ public class PlanResultService { ...@@ -190,7 +190,7 @@ public class PlanResultService {
try { try {
ScheduleParams param = InitScheduleParams(); ScheduleParams param = InitScheduleParams();
// param.setBaseTime(LocalDateTime.of(2026, 5, 20, 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