Commit 78d8bf59 authored by Tong Li's avatar Tong Li

倒排

parent 78d5f5e4
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;
private int anchorTimeSecond = 0;
private transient boolean backwardFailed = false;
private transient boolean scheduled = false;
private transient Integer actualFinishTime;
public enum SchedulingMode {
FORWARD, BACKWARD
}
......
......@@ -67,6 +67,16 @@ public class Material {
*/
private Long CkeckLeadTime;
/**
* 最小生产量
*/
private BigDecimal minProduction;
/**
* 最大生产量
*/
private BigDecimal maxProduction;
@Override
public String toString() {
return "Material{" +
......
......@@ -385,4 +385,113 @@ if(isJit)
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;
}
}
......@@ -540,13 +540,20 @@ public class MachineCalculator {
double e= (double)processingTime/slot.getEfficiency();
LocalDateTime endCandidate = startCandidate.plusSeconds((int)Math.ceil(e));
LocalDateTime endCandidate=null;
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();
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.setOneTime(oneTime);
time.setQuantity(quantity);
......
......@@ -1250,7 +1250,7 @@ if(demand==null)
}
}
}
FileHelper.writeLogFile("BOM:"+material.getCode());
// FileHelper.writeLogFile("BOM:"+material.getCode());
if (needed <= 0) {
orderMaterial.setYpQty(allneeded - needed);
orderMaterial.setQjQty(needed);
......@@ -1285,11 +1285,11 @@ if(demand==null)
for (RoutingSupportingReplace rsr : routingsupportingreplaces2) {
Material material1 = materials.get(rsr.getTargetmaterialid());
FileHelper.writeLogFile("RoutingSupportingReplace:"+material1.getCode());
// FileHelper.writeLogFile("RoutingSupportingReplace:"+material1.getCode());
if (material1 == null) {
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);
if (orderMaterial1 != null) {
......@@ -1297,7 +1297,7 @@ if(demand==null)
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.getReplaceMaterial().add(orderMaterial1);
if (needed <= 0) {
......
......@@ -2014,6 +2014,12 @@ public class PlanResultService {
.sorted(Comparator.comparingInt(GAScheduleResult::getOperationId))
.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) {
StringBuilder sb = new StringBuilder();
String TargetFinishedOperationIds="";
......@@ -2023,14 +2029,16 @@ public class PlanResultService {
.map(String::valueOf) // 把每个Integer转成String
.collect(Collectors.joining(","));
}
Order order=orders.get(job.getGroupId());
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.getEndTime(),
ConvertTime(job.getStartTime()),
ConvertTime(job.getEndTime()),
job.getGroupId(),
job.getOrderId(),
order.getDueDate().format(DateTimeFormatter.ofPattern("YYYY-MM-dd HH:mm:ss")),
job.getMachineId(),
job.getOperationId(),
job.getQuantity(),
......@@ -2414,6 +2422,9 @@ if(job.getGeneDetails()!=null)
material.setMaterialTypeName(m.getMaterialTypeName());
material.setCode(m.getCode());
material.setName(m.getName());
material.setMaxProduction(m.getMaxProduction());
material.setMinProduction(m.getMinProduction());
// material.setCkeckLeadTime(m.getInspectDuration());
// 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