Commit 2f7a699b authored by DESKTOP-VKRD9QF\Administration's avatar DESKTOP-VKRD9QF\Administration
parents f3011df8 813959ca
package com.aps.entity.Algorithm;
/**
* 作者:佟礼
* 时间:2026-05-27
*/
public class DraftScheduleResult {
private int operationId;
private int idealStartTime;
private int idealEndTime;
private Long selectedMachineId;
private double processTime;
private int groupId;
private int sequence;
public DraftScheduleResult(int operationId, int idealStartTime, int idealEndTime,
Long selectedMachineId, double processTime, int groupId, int sequence) {
this.operationId = operationId;
this.idealStartTime = idealStartTime;
this.idealEndTime = idealEndTime;
this.selectedMachineId = selectedMachineId;
this.processTime = processTime;
this.groupId = groupId;
this.sequence = sequence;
}
public int getOperationId() { return operationId; }
public int getIdealStartTime() { return idealStartTime; }
public int getIdealEndTime() { return idealEndTime; }
public Long getSelectedMachineId() { return selectedMachineId; }
public double getProcessTime() { return processTime; }
public int getGroupId() { return groupId; }
public int getSequence() { return sequence; }
}
...@@ -175,6 +175,12 @@ private Long isInterrupt = 1l; ...@@ -175,6 +175,12 @@ private Long isInterrupt = 1l;
private int anchorTimeSecond = 0; private int anchorTimeSecond = 0;
private transient boolean backwardFailed = false;
private transient boolean scheduled = false;
private transient Integer actualFinishTime;
public enum SchedulingMode { public enum SchedulingMode {
FORWARD, BACKWARD FORWARD, BACKWARD
} }
......
...@@ -67,6 +67,16 @@ public class Material { ...@@ -67,6 +67,16 @@ public class Material {
*/ */
private Long CkeckLeadTime; private Long CkeckLeadTime;
/**
* 最小生产量
*/
private BigDecimal minProduction;
/**
* 最大生产量
*/
private BigDecimal maxProduction;
@Override @Override
public String toString() { public String toString() {
return "Material{" + return "Material{" +
......
...@@ -385,4 +385,113 @@ if(isJit) ...@@ -385,4 +385,113 @@ if(isJit)
return Math.max(estimatedStartTime, rawTime); return Math.max(estimatedStartTime, rawTime);
} }
/**
* 半成品锚点计算(JIT倒排模式:成品先于半成品,直接取成品已排的开始时间)
* 返回 -1 触发正排+标记成品重排,>=0 作为半成品倒排锚点(半成品最晚完成时间)
*/
public int computeHybridSemiAnchor(GeneticDecoder decoder,int semiOrderId,
Map<Integer, List<Entry>> entrysBygroupId,
Map<String, OpMachine> opMachineKeyMap,
Chromosome chromosome,
Map<Integer, GAScheduleResult> scheduleIndexById,
Map<Long, CopyOnWriteArrayList<GAScheduleResult>> machineTasksCache,
Map<Long, Machine> machineIdMap,
Map<Integer, Entry> entryIndexById,
Set<Integer> reForwardFinishedOrderIds,GlobalParam _globalParam,Order order) {
List<Entry> sfOps = entrysBygroupId.get(semiOrderId);
if (sfOps == null || sfOps.isEmpty()) return 0;
Entry firstSfOp = sfOps.stream().min(Comparator.comparing(Entry::getSequence)).orElse(null);
if (firstSfOp == null) return 0;
List<Integer> targetFinishedOpIds = firstSfOp.getTargetFinishedOperationId();
if (targetFinishedOpIds == null || targetFinishedOpIds.isEmpty()) {
return 0;
}
// 找关联的成品订单
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);
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 semiTotalTime = 0;
for (Entry op : sfOps) {
String key = semiOrderId + "_" + op.getSequence();
OpMachine opt = opMachineKeyMap.get(key);
if (opt != null) semiTotalTime += calculateOperationProcessingTime(op, opt,_globalParam);
}
Material material= chromosome.getMaterials().get(order.getMaterialId());
int ckeckLeadTime=0;
if(material.getCkeckLeadTime()!=null)
{
ckeckLeadTime=(material.getCkeckLeadTime().intValue()*24*60*60);
}
semiTotalTime+=ckeckLeadTime;
if (semiLatestEndTime - semiTotalTime < 0) {
FileHelper.writeLogFile("[HybridSemi] 半成品" + semiOrderId +
" 倒排开工<0,正排+成品" + finishedOrderId + "重排");
reForwardFinishedOrderIds.add(finishedOrderId);
return -1;
}
FileHelper.writeLogFile("[HybridSemi] 半成品" + semiOrderId +
" 锚点=" + semiLatestEndTime + " (成品" + finishedOrderId +
"开始=" + finishedFirstResult.getStartTime() + ")");
return semiLatestEndTime-ckeckLeadTime;
} else {
// 成品正排了 → 半成品也正排
FileHelper.writeLogFile("[HybridSemi] 成品" + finishedOrderId +
"已正排,半成品" + semiOrderId + "也正排");
reForwardFinishedOrderIds.add(finishedOrderId);
return -1;
}
}
private int calculateOperationProcessingTime(Entry op, OpMachine machineOption,GlobalParam _globalParam) {
int total = 0;
if (op.getConstTime() == 1)//常数时间
{
total = (int) Math.ceil(machineOption.getRuntime().doubleValue());
} else {
double t = machineOption.getRuntime().doubleValue() / machineOption.getSingleOut().doubleValue() * (op.getQuantity());
total = (int) Math.ceil(t);
}
if (op.getSetupTime() != null) total += op.getSetupTime().intValue();
total += op.getTeardownTime();
if ( !_globalParam.is_smoothSetup()) {
total += op.getPreTime();
}
return total;
}
} }
...@@ -85,7 +85,9 @@ public class HybridAlgorithm { ...@@ -85,7 +85,9 @@ public class HybridAlgorithm {
{ {
throw new RuntimeException("没有待排产工单"); throw new RuntimeException("没有待排产工单");
} }
if (_GlobalParam.isIsMultipleMachine()) {
allOperations = OperationSplitService.splitMultiMachineOperations(allOperations, _GlobalParam, machines, _entryRel);
}
// if(materials!=null&&materials.size()>0) { // if(materials!=null&&materials.size()>0) {
// //
// materialRequirementService.init(materials, orders, allOperations, _entryRel, machineScheduler, machines,_GlobalParam); // materialRequirementService.init(materials, orders, allOperations, _entryRel, machineScheduler, machines,_GlobalParam);
...@@ -433,6 +435,7 @@ public class HybridAlgorithm { ...@@ -433,6 +435,7 @@ public class HybridAlgorithm {
chromosome.setMaterials(ProductionDeepCopyUtil.deepCopyTreeMap(materials, String.class, Material.class)); // 简单拷贝,实际可能需要深拷贝 chromosome.setMaterials(ProductionDeepCopyUtil.deepCopyTreeMap(materials, String.class, Material.class)); // 简单拷贝,实际可能需要深拷贝
chromosome.setAllOperations(ProductionDeepCopyUtil.deepCopyList(new CopyOnWriteArrayList<>(allOperations), Entry.class) ); // 简单拷贝,实际可能需要深拷贝 chromosome.setAllOperations(ProductionDeepCopyUtil.deepCopyList(new CopyOnWriteArrayList<>(allOperations), Entry.class) ); // 简单拷贝,实际可能需要深拷贝
chromosome.setGlobalOpList(ProductionDeepCopyUtil.deepCopyList(globalOpList, GlobalOperationInfo.class) ); // 简单拷贝,实际可能需要深拷贝 chromosome.setGlobalOpList(ProductionDeepCopyUtil.deepCopyList(globalOpList, GlobalOperationInfo.class) ); // 简单拷贝,实际可能需要深拷贝
//chromosome.setObjectiveWeights(_objectiveWeights); //chromosome.setObjectiveWeights(_objectiveWeights);
chromosome.setBaseTime(param.getBaseTime()); chromosome.setBaseTime(param.getBaseTime());
...@@ -490,8 +493,9 @@ public class HybridAlgorithm { ...@@ -490,8 +493,9 @@ public class HybridAlgorithm {
chromosome.setMaterials(ProductionDeepCopyUtil.deepCopyTreeMap(materials, String.class, Material.class)); // 简单拷贝,实际可能需要深拷贝 chromosome.setMaterials(ProductionDeepCopyUtil.deepCopyTreeMap(materials, String.class, Material.class)); // 简单拷贝,实际可能需要深拷贝
chromosome.setAllOperations(ProductionDeepCopyUtil.deepCopyList(new CopyOnWriteArrayList<>(allOperations), Entry.class) ); // 简单拷贝,实际可能需要深拷贝 if (chromosome.getAllOperations() == null || chromosome.getAllOperations().isEmpty()) {
// chromosome.setGlobalOpList(ProductionDeepCopyUtil.deepCopyList(globalOpList, GlobalOperationInfo.class) ); // 简单拷贝,实际可能需要深拷贝 chromosome.setAllOperations(ProductionDeepCopyUtil.deepCopyList(new CopyOnWriteArrayList<>(allOperations), Entry.class) );
} // chromosome.setGlobalOpList(ProductionDeepCopyUtil.deepCopyList(globalOpList, GlobalOperationInfo.class) ); // 简单拷贝,实际可能需要深拷贝
//chromosome.setObjectiveWeights(_objectiveWeights); //chromosome.setObjectiveWeights(_objectiveWeights);
chromosome.setBaseTime(param.getBaseTime()); chromosome.setBaseTime(param.getBaseTime());
// chromosome.setInitMachines(ProductionDeepCopyUtil.deepCopyList(machines,Machine.class)); // 简单拷贝,实际可能需要深拷贝 // chromosome.setInitMachines(ProductionDeepCopyUtil.deepCopyList(machines,Machine.class)); // 简单拷贝,实际可能需要深拷贝
......
...@@ -478,7 +478,10 @@ public class Initialization { ...@@ -478,7 +478,10 @@ public class Initialization {
.thenComparing(randomIds::get)); .thenComparing(randomIds::get));
} }
} }
if (_globalParam.isIsMultipleMachine()) {
sortedOps = OperationSplitService.splitOpsForHeuristic(sortedOps, rnd);
chromosome.setAllOperations(new CopyOnWriteArrayList<>(sortedOps));
}
int globalOpId = 0; int globalOpId = 0;
// 为每个工序选择机器 // 为每个工序选择机器
...@@ -583,7 +586,10 @@ public class Initialization { ...@@ -583,7 +586,10 @@ public class Initialization {
.thenComparing(randomIds::get)); .thenComparing(randomIds::get));
} }
if (_globalParam.isIsMultipleMachine()) {
sortedOps = OperationSplitService.splitOpsForHeuristic(sortedOps, rnd);
chromosome.setAllOperations(new CopyOnWriteArrayList<>(sortedOps));
}
int globalOpId = 0; int globalOpId = 0;
// 为每个工序选择机器 // 为每个工序选择机器
for (Entry op : sortedOps) { for (Entry op : sortedOps) {
...@@ -672,6 +678,10 @@ public class Initialization { ...@@ -672,6 +678,10 @@ public class Initialization {
.thenComparing(op -> op.getMachineOptions().get(0).getProcessingTime() * op.getQuantity()) .thenComparing(op -> op.getMachineOptions().get(0).getProcessingTime() * op.getQuantity())
.thenComparing(randomIds::get)); .thenComparing(randomIds::get));
if (_globalParam.isIsMultipleMachine()) {
sortedOps = OperationSplitService.splitOpsForHeuristic(sortedOps, rnd);
chromosome.setAllOperations(new CopyOnWriteArrayList<>(sortedOps));
}
int globalOpId = 0; int globalOpId = 0;
for (Entry op : sortedOps) { for (Entry op : sortedOps) {
...@@ -817,7 +827,10 @@ public class Initialization { ...@@ -817,7 +827,10 @@ public class Initialization {
}) })
.thenComparing(randomIds::get)); .thenComparing(randomIds::get));
} }
if (_globalParam.isIsMultipleMachine()) {
sortedOps = OperationSplitService.splitOpsForHeuristic(sortedOps, rnd);
chromosome.setAllOperations(new CopyOnWriteArrayList<>(sortedOps));
}
int globalOpId = 0; int globalOpId = 0;
for (Entry op : sortedOps) { for (Entry op : sortedOps) {
int groupId = op.getGroupId(); int groupId = op.getGroupId();
...@@ -907,7 +920,10 @@ public class Initialization { ...@@ -907,7 +920,10 @@ public class Initialization {
}) })
.thenComparing(op -> op.getProductId() != null ? op.getProductId() : "") .thenComparing(op -> op.getProductId() != null ? op.getProductId() : "")
.thenComparing(randomIds::get)); .thenComparing(randomIds::get));
if (_globalParam.isIsMultipleMachine()) {
sortedOps = OperationSplitService.splitOpsForHeuristic(sortedOps, rnd);
chromosome.setAllOperations(new CopyOnWriteArrayList<>(sortedOps));
}
int globalOpId = 0; int globalOpId = 0;
for (Entry op : sortedOps) { for (Entry op : sortedOps) {
int groupId = op.getGroupId(); int groupId = op.getGroupId();
...@@ -971,7 +987,10 @@ public class Initialization { ...@@ -971,7 +987,10 @@ public class Initialization {
.thenComparing(op -> op.getProductId() != null ? op.getProductId() : "") // 相同物料排在一起,减少换型 .thenComparing(op -> op.getProductId() != null ? op.getProductId() : "") // 相同物料排在一起,减少换型
.thenComparing(randomIds::get)); .thenComparing(randomIds::get));
if (_globalParam.isIsMultipleMachine()) {
sortedOps = OperationSplitService.splitOpsForHeuristic(sortedOps, rnd);
chromosome.setAllOperations(new CopyOnWriteArrayList<>(sortedOps));
}
int globalOpId = 0; int globalOpId = 0;
......
...@@ -540,13 +540,20 @@ public class MachineCalculator { ...@@ -540,13 +540,20 @@ public class MachineCalculator {
double e= (double)processingTime/slot.getEfficiency(); double e= (double)processingTime/slot.getEfficiency();
LocalDateTime endCandidate=null;
LocalDateTime endCandidate = startCandidate.plusSeconds((int)Math.ceil(e)); LocalDateTime startCandidate1 = null;
if(isJit)
{
endCandidate = endCandidate1;
startCandidate1=endCandidate.plusSeconds(-(int) Math.ceil(e));;
}else {
endCandidate = startCandidate.plusSeconds((int) Math.ceil(e));
startCandidate1=startCandidate;
}
ScheduleResultDetail time = new ScheduleResultDetail(); ScheduleResultDetail time = new ScheduleResultDetail();
time.setKey(slot.getKey()); time.setKey(slot.getKey());
time.setStartTime((int) ChronoUnit.SECONDS.between(baseTime, startCandidate)); time.setStartTime((int) ChronoUnit.SECONDS.between(baseTime, startCandidate1));
time.setEndTime((int) ChronoUnit.SECONDS.between(baseTime, endCandidate)); time.setEndTime((int) ChronoUnit.SECONDS.between(baseTime, endCandidate));
time.setOneTime(oneTime); time.setOneTime(oneTime);
time.setQuantity(quantity); time.setQuantity(quantity);
......
...@@ -1250,7 +1250,7 @@ if(demand==null) ...@@ -1250,7 +1250,7 @@ if(demand==null)
} }
} }
} }
FileHelper.writeLogFile("BOM:"+material.getCode()); // FileHelper.writeLogFile("BOM:"+material.getCode());
if (needed <= 0) { if (needed <= 0) {
orderMaterial.setYpQty(allneeded - needed); orderMaterial.setYpQty(allneeded - needed);
orderMaterial.setQjQty(needed); orderMaterial.setQjQty(needed);
...@@ -1285,11 +1285,11 @@ if(demand==null) ...@@ -1285,11 +1285,11 @@ if(demand==null)
for (RoutingSupportingReplace rsr : routingsupportingreplaces2) { for (RoutingSupportingReplace rsr : routingsupportingreplaces2) {
Material material1 = materials.get(rsr.getTargetmaterialid()); Material material1 = materials.get(rsr.getTargetmaterialid());
FileHelper.writeLogFile("RoutingSupportingReplace:"+material1.getCode()); // FileHelper.writeLogFile("RoutingSupportingReplace:"+material1.getCode());
if (material1 == null) { if (material1 == null) {
break; break;
} }
FileHelper.writeLogFile("RoutingSupportingReplace: "+(commitChanges?"1":"0")+" " +material1.getCode()+": "+useStock); // FileHelper.writeLogFile("RoutingSupportingReplace: "+(commitChanges?"1":"0")+" " +material1.getCode()+": "+useStock);
OrderMaterialRequirement orderMaterial1 = MaterialStock(material1, rsr.getTargetmaterialid(), orderMaterial.getOrderId(), orderMaterial.getChildOrderId(), operationId, allneeded, needed, earliestStartTime, commitChanges); OrderMaterialRequirement orderMaterial1 = MaterialStock(material1, rsr.getTargetmaterialid(), orderMaterial.getOrderId(), orderMaterial.getChildOrderId(), operationId, allneeded, needed, earliestStartTime, commitChanges);
if (orderMaterial1 != null) { if (orderMaterial1 != null) {
...@@ -1297,7 +1297,7 @@ if(demand==null) ...@@ -1297,7 +1297,7 @@ if(demand==null)
needed -= useStock; needed -= useStock;
FileHelper.writeLogFile("RoutingSupportingReplace: "+(commitChanges?"1":"0")+" " +material1.getCode()+": "+useStock); // FileHelper.writeLogFile("RoutingSupportingReplace: "+(commitChanges?"1":"0")+" " +material1.getCode()+": "+useStock);
orderMaterial.setUseStock(orderMaterial.getUseStock() + useStock); orderMaterial.setUseStock(orderMaterial.getUseStock() + useStock);
orderMaterial.getReplaceMaterial().add(orderMaterial1); orderMaterial.getReplaceMaterial().add(orderMaterial1);
if (needed <= 0) { if (needed <= 0) {
......
...@@ -2069,6 +2069,12 @@ public class PlanResultService { ...@@ -2069,6 +2069,12 @@ public class PlanResultService {
.sorted(Comparator.comparingInt(GAScheduleResult::getOperationId)) .sorted(Comparator.comparingInt(GAScheduleResult::getOperationId))
.collect(Collectors.toList()); .collect(Collectors.toList());
Map<Integer, Order> orders = schedule.getOrders().stream()
.collect(Collectors.toMap(
Order::getId,
// 2. Value映射:Material → Material
order -> order
));
for (GAScheduleResult job : sortedJobs) { for (GAScheduleResult job : sortedJobs) {
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
String TargetFinishedOperationIds=""; String TargetFinishedOperationIds="";
...@@ -2078,14 +2084,16 @@ public class PlanResultService { ...@@ -2078,14 +2084,16 @@ public class PlanResultService {
.map(String::valueOf) // 把每个Integer转成String .map(String::valueOf) // 把每个Integer转成String
.collect(Collectors.joining(",")); .collect(Collectors.joining(","));
} }
Order order=orders.get(job.getGroupId());
sb.append(String.format( sb.append(String.format(
"[%d-%d]:[%s-%s] Order %d,OrderID %s, Machine %d, Operation %d, Quantity %.1f, processingTime %.1f, 前处理 %d, 后处理 %d, 离散参数 %d, bomtime %s,TargetOperationId %s", "[%d-%d]:[%s-%s] Order %d,OrderID %s,OrderDueDate %s, Machine %d, Operation %d, Quantity %.1f, processingTime %.1f, 前处理 %d, 后处理 %d, 离散参数 %d, bomtime %s,TargetOperationId %s",
job.getStartTime(), job.getStartTime(),
job.getEndTime(), job.getEndTime(),
ConvertTime(job.getStartTime()), ConvertTime(job.getStartTime()),
ConvertTime(job.getEndTime()), ConvertTime(job.getEndTime()),
job.getGroupId(), job.getGroupId(),
job.getOrderId(), job.getOrderId(),
order.getDueDate().format(DateTimeFormatter.ofPattern("YYYY-MM-dd HH:mm:ss")),
job.getMachineId(), job.getMachineId(),
job.getOperationId(), job.getOperationId(),
job.getQuantity(), job.getQuantity(),
...@@ -2469,6 +2477,9 @@ if(job.getGeneDetails()!=null) ...@@ -2469,6 +2477,9 @@ if(job.getGeneDetails()!=null)
material.setMaterialTypeName(m.getMaterialTypeName()); material.setMaterialTypeName(m.getMaterialTypeName());
material.setCode(m.getCode()); material.setCode(m.getCode());
material.setName(m.getName()); material.setName(m.getName());
material.setMaxProduction(m.getMaxProduction());
material.setMinProduction(m.getMinProduction());
// material.setCkeckLeadTime(m.getInspectDuration()); // material.setCkeckLeadTime(m.getInspectDuration());
// material.setPurchaseLeadTime(m.getPurchaseDuration()); // material.setPurchaseLeadTime(m.getPurchaseDuration());
......
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