物料配套

parent 40085732
...@@ -193,7 +193,7 @@ public class Chromosome { ...@@ -193,7 +193,7 @@ public class Chromosome {
/// 交付期延迟时间 /// 交付期延迟时间
/// </summary> /// </summary>
private double DelayTime; private double DelayTime;
private double SemiJitSlack;
private String ScenarioID; private String ScenarioID;
......
...@@ -7,10 +7,10 @@ package com.aps.entity.Algorithm; ...@@ -7,10 +7,10 @@ package com.aps.entity.Algorithm;
*/ */
public class ObjectiveWeights { public class ObjectiveWeights {
/** /**
* 目标权重(默认值:[0.3, 0.2, 0.15, 0.2, 0.15]) * 目标权重(默认值:[0.3, 0.2, 0.15, 0.2, 0.15, 0.01])
* 对应:完工时间、总流程时间、总换型时间、机器负载标准差、延迟时间 * 对应:完工时间、总流程时间、总换型时间、机器负载标准差、延迟时间、半成品JIT
*/ */
private double[] weights = new double[] { 0.3, 0.2, 0.15, 0.2, 0.15 }; private double[] weights = new double[] { 0.3, 0.2, 0.15, 0.2, 0.15, 0.01 };
/** /**
* NSGA-II模式:true=纯帕累托(无视权重),false=加权帕累托 * NSGA-II模式:true=纯帕累托(无视权重),false=加权帕累托
......
...@@ -160,4 +160,8 @@ private Long isInterrupt = 1l; ...@@ -160,4 +160,8 @@ private Long isInterrupt = 1l;
@Schema(description = "指定开始时间") @Schema(description = "指定开始时间")
@JsonInclude(JsonInclude.Include.ALWAYS) @JsonInclude(JsonInclude.Include.ALWAYS)
private LocalDateTime designatedStartTime; private LocalDateTime designatedStartTime;
private LocalDateTime jitPreferredStartTime;
private boolean jitTemporary = false;
} }
...@@ -14,7 +14,6 @@ public class GlobalParam { ...@@ -14,7 +14,6 @@ public class GlobalParam {
/// 是否可以打破优先级 /// 是否可以打破优先级
/// </summary> /// </summary>
private boolean IsBreakPriority = false; private boolean IsBreakPriority = false;
/// <summary> /// <summary>
/// 是否多台设备 /// 是否多台设备
/// </summary> /// </summary>
...@@ -51,6 +50,16 @@ public class GlobalParam { ...@@ -51,6 +50,16 @@ public class GlobalParam {
*/ */
private boolean pureNSGAIIMode = true; private boolean pureNSGAIIMode = true;
/**
* 半成品JIT缓冲时间(分钟)
*/
private int semiJitBufferMinutes = 0;
/**
* 物料/设备固定点求解最大迭代次数
*/
private int materialSolveMaxIterations = 8;
/// <summary> /// <summary>
...@@ -66,6 +75,7 @@ public class GlobalParam { ...@@ -66,6 +75,7 @@ public class GlobalParam {
public static final String OBJECTIVE_SETUP_TIME = "setupTime"; // 总换型时间 public static final String OBJECTIVE_SETUP_TIME = "setupTime"; // 总换型时间
public static final String OBJECTIVE_MACHINE_LOAD = "machineLoad"; // 机器负载均衡 public static final String OBJECTIVE_MACHINE_LOAD = "machineLoad"; // 机器负载均衡
public static final String OBJECTIVE_TARDINESS = "tardiness"; // 延迟时间 public static final String OBJECTIVE_TARDINESS = "tardiness"; // 延迟时间
public static final String OBJECTIVE_SEMI_JIT = "semiJitSlack"; // 半成品提前完工惩罚
/// <summary> /// <summary>
/// 构造函数,初始化默认值 /// 构造函数,初始化默认值
...@@ -73,15 +83,22 @@ public class GlobalParam { ...@@ -73,15 +83,22 @@ public class GlobalParam {
public GlobalParam() { public GlobalParam() {
// 初始化默认目标值配置 // 初始化默认目标值配置
//完工时间、总流程时间、总换型时间、机器负载标准差、延迟时间 //完工时间、总流程时间、总换型时间、机器负载标准差、延迟时间
objectiveConfigs.add(new ObjectiveConfig(OBJECTIVE_MAKESPAN, true, 1, 0.3)); objectiveConfigs.add(createMinimizeObjectiveConfig(OBJECTIVE_MAKESPAN, 1, 0.3));
objectiveConfigs.add(new ObjectiveConfig(OBJECTIVE_FLOW_TIME, true, 2, 0.1)); objectiveConfigs.add(createMinimizeObjectiveConfig(OBJECTIVE_FLOW_TIME, 2, 0.2));
objectiveConfigs.add(new ObjectiveConfig(OBJECTIVE_SETUP_TIME, true, 2, 0.1)); objectiveConfigs.add(createMinimizeObjectiveConfig(OBJECTIVE_SETUP_TIME, 2, 0.15));
objectiveConfigs.add(new ObjectiveConfig(OBJECTIVE_MACHINE_LOAD, true, 1, 0.1)); objectiveConfigs.add(createMinimizeObjectiveConfig(OBJECTIVE_MACHINE_LOAD, 1, 0.2));
objectiveConfigs.add(new ObjectiveConfig(OBJECTIVE_TARDINESS, true, 1, 0.6)); objectiveConfigs.add(createMinimizeObjectiveConfig(OBJECTIVE_TARDINESS, 1, 0.15));
objectiveConfigs.add(createMinimizeObjectiveConfig(OBJECTIVE_SEMI_JIT, 2, 0.01));
objectiveConfigs.sort(Comparator.comparing((ObjectiveConfig op) -> op.getLevel())); objectiveConfigs.sort(Comparator.comparing((ObjectiveConfig op) -> op.getLevel()));
} }
private ObjectiveConfig createMinimizeObjectiveConfig(String name, int level, double weight) {
ObjectiveConfig config = new ObjectiveConfig(name, true, level, weight);
config.setMinimize(true);
return config;
}
/// <summary> /// <summary>
/// 获取目标值启用状态 /// 获取目标值启用状态
/// </summary> /// </summary>
......
...@@ -58,6 +58,7 @@ public class GeneticDecoder { ...@@ -58,6 +58,7 @@ public class GeneticDecoder {
private DiscreteParameterMatrixService discreteParameterMatrixService; private DiscreteParameterMatrixService discreteParameterMatrixService;
private String sceneId; private String sceneId;
private boolean rebuildStructureForCurrentDecode = true;
...@@ -388,12 +389,24 @@ public class GeneticDecoder { ...@@ -388,12 +389,24 @@ public class GeneticDecoder {
/** /**
* 染色体解码为调度方案 * 染色体解码为调度方案
*/ */
public void decode(Chromosome chromosome, boolean isParallel, boolean rebuildStructure) {
boolean previousFlag = this.rebuildStructureForCurrentDecode;
this.rebuildStructureForCurrentDecode = rebuildStructure;
try {
decode(chromosome, isParallel);
} finally {
this.rebuildStructureForCurrentDecode = previousFlag;
}
}
public void serialDecode(Chromosome chromosome) { public void serialDecode(Chromosome chromosome) {
List<OrderMaterialRequirement> orderMaterials = materialRequirementService.buildMultiLevelRequirementNetwork(chromosome, sceneId, baseTime,_globalParam); if (rebuildStructureForCurrentDecode) {
materialRequirementService.buildMultiLevelRequirementNetwork(chromosome, sceneId, baseTime,_globalParam);
}
chromosome.setScenarioID(sceneId); chromosome.setScenarioID(sceneId);
if(_globalParam.isIsCheckSf()) { if(rebuildStructureForCurrentDecode && _globalParam.isIsCheckSf()) {
int isnew= generateGlobalOpList(chromosome); int isnew= generateGlobalOpList(chromosome);
if(isnew==1) { if(isnew==1) {
...@@ -403,6 +416,7 @@ public class GeneticDecoder { ...@@ -403,6 +416,7 @@ public class GeneticDecoder {
List<GlobalOperationInfo> globalOpList=chromosome.getGlobalOpList(); List<GlobalOperationInfo> globalOpList=chromosome.getGlobalOpList();
List<Entry> allOperations=chromosome.getAllOperations(); List<Entry> allOperations=chromosome.getAllOperations();
allOperations.forEach(t -> t.setLatestCompletionTime(null));
...@@ -1008,10 +1022,7 @@ public class GeneticDecoder { ...@@ -1008,10 +1022,7 @@ public class GeneticDecoder {
prevtime= CalPrevtime( prevtime, currentOp, chromosome, processTime, targetMachine,entryIndexById, scheduleIndexById); prevtime= CalPrevtime( prevtime, currentOp, chromosome, processTime, targetMachine,entryIndexById, scheduleIndexById);
} }
int bomtime = getOperationBOMTime(currentOp,chromosome);
int prevendtime=prevtime; int prevendtime=prevtime;
prevtime = Math.max(prevtime, bomtime);
Machine machine = machineIdMap.get(machineId); Machine machine = machineIdMap.get(machineId);
int actualEndTime = processWithSingleMachine(currentOp, machine, processTime, prevtime,machineOption, chromosome,false,prevendtime,machineTasksCache,entryIndexById, scheduleIndexById); int actualEndTime = processWithSingleMachine(currentOp, machine, processTime, prevtime,machineOption, chromosome,false,prevendtime,machineTasksCache,entryIndexById, scheduleIndexById);
return actualEndTime; return actualEndTime;
...@@ -1066,41 +1077,92 @@ public class GeneticDecoder { ...@@ -1066,41 +1077,92 @@ public class GeneticDecoder {
// 工序的前处理不能提前,则要在前处理完成后才能开工,所以要在前一工序的结束时间基础上+前处理 // 工序的前处理不能提前,则要在前处理完成后才能开工,所以要在前一工序的结束时间基础上+前处理
earliestStartTime+=preTime; earliestStartTime+=preTime;
} }
GAScheduleResult existingResult = chromosome.getResultOld().stream().filter(r-> r.getOperationId() == operation.getId()).findFirst().orElse(null); int operationId = operation.getId();
GAScheduleResult existingResult = chromosome.getResultOld().stream().filter(r-> r.getOperationId() == operationId).findFirst().orElse(null);
if(existingResult!=null) if(existingResult!=null)
{ {
earliestStartTime = Math.max(earliestStartTime,existingResult.getDesignatedStartTime()); earliestStartTime = Math.max(earliestStartTime,existingResult.getDesignatedStartTime());
} }
if (operation.isJitTemporary() && operation.getJitPreferredStartTime() != null) {
int setupTime=0; int jitPreferredStartTime = (int) ChronoUnit.SECONDS.between(baseTime, operation.getJitPreferredStartTime());
CopyOnWriteArrayList<GAScheduleResult> machineTasks; earliestStartTime = Math.max(earliestStartTime, jitPreferredStartTime);
if (machineTasksCache.containsKey(machine.getId())) {
machineTasks = machineTasksCache.get(machine.getId());
} else {
machineTasks = chromosome.getResult().stream()
.filter(t -> t.getMachineId() == machine.getId())
.sorted(Comparator.comparingInt(GAScheduleResult::getStartTime))
.collect(Collectors.toCollection(CopyOnWriteArrayList::new));
machineTasksCache.put(machine.getId(), machineTasks);
}
GAScheduleResult lastGeneOnMachine = null;
if(machineTasks!=null&&machineTasks.size()>0)
{
lastGeneOnMachine=machineTasks.get(machineTasks.size()-1);
}
if(lastGeneOnMachine!=null&&_globalParam.is_smoothChangeOver())
{
earliestStartTime = Math.max(earliestStartTime,lastGeneOnMachine.getEndTime());
} }
// _globalParam.set_smoothChangeOver(false); int setupTime=0;
CopyOnWriteArrayList<ScheduleResultDetail> geneDetails=new CopyOnWriteArrayList<>(); long machineId = machine.getId();
boolean needMaterialCheck = (operation.getMaterialRequirements()!=null&&operation.getTargetFinishedOperationId()==null)||calbom;
boolean commitMaterialCheck = needMaterialCheck;
int baseEarliestStartTime = earliestStartTime;
int candidateStartTime = earliestStartTime;
int bomtime=0; int bomtime=0;
int maxSolveIterations = Math.max(1, _globalParam.getMaterialSolveMaxIterations());
boolean converged = !needMaterialCheck;
Entry scheduledOperation = operation;
Machine scheduledMachine = machine;
CopyOnWriteArrayList<GAScheduleResult> machineTasks = getMachineTasks(machineId, chromosome, machineTasksCache);
GAScheduleResult lastGeneOnMachine = getLastMachineTask(machineTasks);
MachineSchedulePreview machinePreview = null;
CopyOnWriteArrayList<ScheduleResultDetail> geneDetails=new CopyOnWriteArrayList<>();
if(needMaterialCheck) {
for (int iteration = 0; iteration < maxSolveIterations; iteration++) {
Entry refreshedOperation = entryIndexById.get(operationId);
if (refreshedOperation != null) {
scheduledOperation = refreshedOperation;
}
Machine refreshedMachine = getMachineById(chromosome, machineId);
if (refreshedMachine != null) {
scheduledMachine = refreshedMachine;
}
machineTasks = getMachineTasks(machineId, chromosome, machineTasksCache);
lastGeneOnMachine = getLastMachineTask(machineTasks);
if(lastGeneOnMachine!=null&&_globalParam.is_smoothChangeOver())
{
candidateStartTime = Math.max(candidateStartTime,lastGeneOnMachine.getEndTime());
}
machinePreview = buildMachinePreview(scheduledOperation, scheduledMachine, processingTime, processingTimeTotal,
candidateStartTime, lastGeneOnMachine, machineTasks, chromosome);
try {
bomtime = EditOperationBOMTime(scheduledOperation,chromosome,machinePreview.getStartTime(),machineTasksCache, entryIndexById, scheduleIndexById, false);
} finally {
Machine liveMachineAfterTrial = getMachineById(chromosome, machineId);
if (liveMachineAfterTrial != null) {
AddMachineAvailable(liveMachineAfterTrial, machinePreview.getGeneDetails());
} else {
AddMachineAvailable(scheduledMachine, machinePreview.getGeneDetails());
}
}
int nextCandidateStartTime = Math.max(baseEarliestStartTime, bomtime);
if (nextCandidateStartTime <= machinePreview.getStartTime()) {
converged = true;
candidateStartTime = nextCandidateStartTime;
break;
}
candidateStartTime = nextCandidateStartTime;
}
earliestStartTime = candidateStartTime;
Entry refreshedOperation = entryIndexById.get(operationId);
if (refreshedOperation != null) {
scheduledOperation = refreshedOperation;
operation = refreshedOperation;
}
Machine refreshedMachine = getMachineById(chromosome, machineId);
if (refreshedMachine != null) {
scheduledMachine = refreshedMachine;
machine = refreshedMachine;
}
machineTasks = getMachineTasks(machineId, chromosome, machineTasksCache);
lastGeneOnMachine = getLastMachineTask(machineTasks);
needMaterialCheck = false;
}
if((operation.getMaterialRequirements()!=null&&operation.getTargetFinishedOperationId()==null)||calbom) { if(needMaterialCheck) {
int earliestStartTimeold=earliestStartTime; int earliestStartTimeold=earliestStartTime;
if (_globalParam.is_smoothChangeOver()) { if (_globalParam.is_smoothChangeOver()) {
...@@ -1121,13 +1183,10 @@ public class GeneticDecoder { ...@@ -1121,13 +1183,10 @@ public class GeneticDecoder {
: earliestStartTime; : earliestStartTime;
} }
bomtime= EditOperationBOMTime(operation,chromosome,earliestStartTime,machineTasksCache, entryIndexById, scheduleIndexById); bomtime= EditOperationBOMTime(operation,chromosome,earliestStartTime,machineTasksCache, entryIndexById, scheduleIndexById, false);
if(bomtime>prevendtime&&bomtime<earliestStartTimeold) earliestStartTime = Math.max(earliestStartTime, bomtime);
{
earliestStartTime=bomtime;
}
} }
...@@ -1214,6 +1273,20 @@ public class GeneticDecoder { ...@@ -1214,6 +1273,20 @@ public class GeneticDecoder {
// 准备工时 加入到加工时间里 // 准备工时 加入到加工时间里
// 后处理时间 相同任务的前一工序的结束时间+后处理时间 =当前工序最早开工时间 // 后处理时间 相同任务的前一工序的结束时间+后处理时间 =当前工序最早开工时间
if (commitMaterialCheck) {
int committedBomTime = EditOperationBOMTime(operation,chromosome,startTime,machineTasksCache, entryIndexById, scheduleIndexById, true);
bomtime = Math.max(bomtime, committedBomTime);
if (committedBomTime > startTime) {
throw new IllegalStateException(String.format(
"工序固定点求解未收敛,operationId=%d, groupId=%d, startTime=%d, bomTime=%d, maxIterations=%d",
operation.getId(),
operation.getGroupId(),
startTime,
committedBomTime,
maxSolveIterations));
}
}
GAScheduleResult result=new GAScheduleResult(); GAScheduleResult result=new GAScheduleResult();
...@@ -1228,7 +1301,9 @@ public class GeneticDecoder { ...@@ -1228,7 +1301,9 @@ public class GeneticDecoder {
result.setProductId(operation.getProductId()); result.setProductId(operation.getProductId());
result.setProductName(operation.getProductName()); result.setProductName(operation.getProductName());
result.setProductCode(operation.getProductCode()); result.setProductCode(operation.getProductCode());
result.setTargetFinishedOperationId(operation.getTargetFinishedOperationId()); result.setTargetFinishedOperationId(operation.getTargetFinishedOperationId() == null
? null
: new ArrayList<>(operation.getTargetFinishedOperationId()));
result.setMachineId(machine.getId()); result.setMachineId(machine.getId());
result.setStartTime(startTime); result.setStartTime(startTime);
result.setEndTime(endTime); result.setEndTime(endTime);
...@@ -1276,10 +1351,146 @@ public class GeneticDecoder { ...@@ -1276,10 +1351,146 @@ public class GeneticDecoder {
if (machineTasks != null) { if (machineTasks != null) {
machineTasks.add(result); machineTasks.add(result);
} }
updateSemiJitTargets(operation, startTime, chromosome);
scheduleIndexById.put(operation.getId(),result); scheduleIndexById.put(operation.getId(),result);
return endTime; return endTime;
} }
private void updateSemiJitTargets(Entry parentOperation, int parentStartTime, Chromosome chromosome) {
if (parentOperation.getDependentOnOrderIds() == null || parentOperation.getDependentOnOrderIds().isEmpty()) {
return;
}
LocalDateTime targetTime = baseTime.plusSeconds(parentStartTime)
.minusMinutes(Math.max(0, _globalParam.getSemiJitBufferMinutes()));
if (targetTime.isBefore(baseTime)) {
targetTime = baseTime;
}
for (Integer childGroupId : parentOperation.getDependentOnOrderIds()) {
List<Entry> childOperations = chromosome.getAllOperations().stream()
.filter(t -> t.getGroupId() == childGroupId)
.collect(Collectors.toList());
if (childOperations.isEmpty()) {
continue;
}
int maxSequence = childOperations.stream().mapToInt(Entry::getSequence).max().orElse(Integer.MIN_VALUE);
for (Entry childOperation : childOperations) {
if (childOperation.getSequence() != maxSequence) {
continue;
}
if (childOperation.getLatestCompletionTime() == null || targetTime.isBefore(childOperation.getLatestCompletionTime())) {
childOperation.setLatestCompletionTime(targetTime);
}
if (childOperation.getTargetFinishedOperationId() == null) {
childOperation.setTargetFinishedOperationId(new ArrayList<>());
}
if (!childOperation.getTargetFinishedOperationId().contains(parentOperation.getId())) {
childOperation.getTargetFinishedOperationId().add(parentOperation.getId());
}
}
}
}
private MachineSchedulePreview buildMachinePreview(Entry operation, Machine machine, double processingTime, int processingTimeTotal,
int earliestStartTime, GAScheduleResult lastGeneOnMachine,
CopyOnWriteArrayList<GAScheduleResult> machineTasks, Chromosome chromosome) {
int setupTime = 0;
int previewStart = earliestStartTime;
int previewProcessingTotal = processingTimeTotal;
CopyOnWriteArrayList<ScheduleResultDetail> geneDetails;
if (_globalParam.is_smoothChangeOver()) {
Map<Integer,Object> reslte = calculateSetupTime(lastGeneOnMachine, operation, machine, previewStart, previewProcessingTotal, _globalParam.is_smoothChangeOverInWeek(),chromosome.getAllOperations());
setupTime=(int)reslte.get(1);
int setupStartTime=(int)reslte.get(2);
previewStart=(int)reslte.get(4);
previewProcessingTotal=(int)reslte.get(5);
if(setupTime==0)
{
geneDetails = machineCalculator.getNextAvailableTime(machine, previewStart, -1,
previewProcessingTotal, machineTasks, operation.getIsInterrupt()!=1, true,processingTime, operation.getQuantity(), true);
}else {
CopyOnWriteArrayList<TimeSegment> AvailableTimeSegment = (CopyOnWriteArrayList<TimeSegment>) reslte.get(6);
Map<Integer,Object> result = machineCalculator.CreateScheduleResult(machine, previewProcessingTotal, previewStart,
AvailableTimeSegment, processingTime, operation.getQuantity(), operation.getIsInterrupt() != 1, setupTime, _globalParam.is_smoothChangeOverInWeek(), setupStartTime);
setupTime=(int)result.get(1);
geneDetails=(CopyOnWriteArrayList<ScheduleResultDetail>) result.get(2);
}
}else {
geneDetails = machineCalculator.getNextAvailableTime(machine, previewStart, -1,
previewProcessingTotal, machineTasks, operation.getIsInterrupt()!=1, true,processingTime, operation.getQuantity(), true);
}
int startTime = geneDetails.stream()
.mapToInt(ScheduleResultDetail::getStartTime)
.min()
.orElse(0);
int endTime = geneDetails.stream()
.mapToInt(ScheduleResultDetail::getEndTime)
.max()
.orElse(0);
return new MachineSchedulePreview(startTime, endTime, setupTime, geneDetails);
}
private CopyOnWriteArrayList<GAScheduleResult> getMachineTasks(long machineId, Chromosome chromosome,
Map<Long, CopyOnWriteArrayList<GAScheduleResult>> machineTasksCache) {
if (machineTasksCache.containsKey(machineId)) {
return machineTasksCache.get(machineId);
}
CopyOnWriteArrayList<GAScheduleResult> machineTasks = chromosome.getResult().stream()
.filter(t -> t.getMachineId() == machineId)
.sorted(Comparator.comparingInt(GAScheduleResult::getStartTime))
.collect(Collectors.toCollection(CopyOnWriteArrayList::new));
machineTasksCache.put(machineId, machineTasks);
return machineTasks;
}
private GAScheduleResult getLastMachineTask(CopyOnWriteArrayList<GAScheduleResult> machineTasks) {
if(machineTasks!=null&&machineTasks.size()>0)
{
return machineTasks.get(machineTasks.size()-1);
}
return null;
}
private Machine getMachineById(Chromosome chromosome, long machineId) {
return chromosome.getMachines().stream()
.filter(m -> m.getId() == machineId)
.findFirst()
.orElse(null);
}
private static class MachineSchedulePreview {
private final int startTime;
private final int endTime;
private final int setupTime;
private final CopyOnWriteArrayList<ScheduleResultDetail> geneDetails;
private MachineSchedulePreview(int startTime, int endTime, int setupTime, CopyOnWriteArrayList<ScheduleResultDetail> geneDetails) {
this.startTime = startTime;
this.endTime = endTime;
this.setupTime = setupTime;
this.geneDetails = geneDetails;
}
public int getStartTime() {
return startTime;
}
public int getEndTime() {
return endTime;
}
public int getSetupTime() {
return setupTime;
}
public CopyOnWriteArrayList<ScheduleResultDetail> getGeneDetails() {
return geneDetails;
}
}
/** /**
* 计算前序结束时间 * 计算前序结束时间
* @param prevtime * @param prevtime
...@@ -1415,8 +1626,9 @@ public class GeneticDecoder { ...@@ -1415,8 +1626,9 @@ public class GeneticDecoder {
// 计算RawTime // 计算RawTime
Optional<LocalDateTime> rawDateOpt = opboms.stream() Optional<LocalDateTime> rawDateOpt = opboms.stream()
.filter(t -> t.getMaterialTypeName().equals("MP")) .filter(t -> "MP".equals(t.getMaterialTypeName()))
.map(OrderMaterialRequirement::getUseTime) .map(OrderMaterialRequirement::getUseTime)
.filter(Objects::nonNull)
.max(LocalDateTime::compareTo); .max(LocalDateTime::compareTo);
if (rawDateOpt.isPresent()) { if (rawDateOpt.isPresent()) {
rawTime = (int) Duration.between(baseTime, rawDateOpt.get()).getSeconds(); rawTime = (int) Duration.between(baseTime, rawDateOpt.get()).getSeconds();
...@@ -1426,7 +1638,7 @@ public class GeneticDecoder { ...@@ -1426,7 +1638,7 @@ public class GeneticDecoder {
// 计算SFTime // 计算SFTime
List<OrderMaterialRequirement> sfBoms = opboms.stream() List<OrderMaterialRequirement> sfBoms = opboms.stream()
.filter(t -> !t.getMaterialTypeName().equals("MP") .filter(t -> !"MP".equals(t.getMaterialTypeName())
&& t.getProductOrderID() != null && !t.getProductOrderID().isEmpty()) && t.getProductOrderID() != null && !t.getProductOrderID().isEmpty())
.collect(Collectors.toList()); .collect(Collectors.toList());
...@@ -1455,8 +1667,9 @@ public class GeneticDecoder { ...@@ -1455,8 +1667,9 @@ public class GeneticDecoder {
} }
} }
Optional<LocalDateTime> sfDateOpt = opboms.stream() Optional<LocalDateTime> sfDateOpt = opboms.stream()
.filter(t -> !t.getMaterialTypeName().equals("MP")&&(t.getProductOrderID() == null || t.getProductOrderID().isEmpty())) .filter(t -> !"MP".equals(t.getMaterialTypeName())&&(t.getProductOrderID() == null || t.getProductOrderID().isEmpty()))
.map(OrderMaterialRequirement::getUseTime) .map(OrderMaterialRequirement::getUseTime)
.filter(Objects::nonNull)
.max(LocalDateTime::compareTo); .max(LocalDateTime::compareTo);
if (sfDateOpt.isPresent()) { if (sfDateOpt.isPresent()) {
sfTime =Math.max(sfTime, (int) Duration.between(baseTime, sfDateOpt.get()).getSeconds()); sfTime =Math.max(sfTime, (int) Duration.between(baseTime, sfDateOpt.get()).getSeconds());
...@@ -1467,17 +1680,73 @@ public class GeneticDecoder { ...@@ -1467,17 +1680,73 @@ public class GeneticDecoder {
} }
private int EditOperationBOMTime(Entry currentOp, Chromosome chromosome,int earliestStartTime,Map<Long, CopyOnWriteArrayList<GAScheduleResult>> machineTasksCache,Map<Integer, Entry> entryIndexById,Map<Integer, GAScheduleResult> scheduleIndexById) { private int EditOperationBOMTime(Entry currentOp, Chromosome chromosome,int earliestStartTime,Map<Long, CopyOnWriteArrayList<GAScheduleResult>> machineTasksCache,Map<Integer, Entry> entryIndexById,Map<Integer, GAScheduleResult> scheduleIndexById) {
return EditOperationBOMTime(currentOp, chromosome, earliestStartTime, machineTasksCache, entryIndexById, scheduleIndexById, true);
}
private int EditOperationBOMTime(Entry currentOp, Chromosome chromosome,int earliestStartTime,Map<Long, CopyOnWriteArrayList<GAScheduleResult>> machineTasksCache,Map<Integer, Entry> entryIndexById,Map<Integer, GAScheduleResult> scheduleIndexById, boolean commitChanges) {
List<OrderMaterialRequirement> opboms= currentOp.getMaterialRequirements(); List<OrderMaterialRequirement> opboms= currentOp.getMaterialRequirements();
if(opboms==null) if(opboms==null)
{ {
return 0; return 0;
} }
LocalDateTime earliestStartTime1=baseTime.plusSeconds(earliestStartTime); LocalDateTime earliestStartTime1=baseTime.plusSeconds(earliestStartTime);
materialRequirementService.EditOperationBOM(currentOp,chromosome,earliestStartTime1,this,machineTasksCache, entryIndexById, scheduleIndexById, baseTime); if(commitChanges) {
return getOperationBOMTime(currentOp, chromosome); materialRequirementService.EditOperationBOM(currentOp,chromosome,earliestStartTime1,this,machineTasksCache, entryIndexById, scheduleIndexById, baseTime, true);
return getOperationBOMTime(currentOp, chromosome);
}
TrialDecodeSnapshot snapshot = createTrialDecodeSnapshot(chromosome);
try {
materialRequirementService.EditOperationBOM(currentOp,chromosome,earliestStartTime1,this,machineTasksCache, entryIndexById, scheduleIndexById, baseTime, true);
return getOperationBOMTime(currentOp, chromosome);
} finally {
restoreTrialDecodeSnapshot(snapshot, chromosome, machineTasksCache, entryIndexById, scheduleIndexById);
}
}
private TrialDecodeSnapshot createTrialDecodeSnapshot(Chromosome chromosome) {
TrialDecodeSnapshot snapshot = new TrialDecodeSnapshot();
snapshot.machines = ProductionDeepCopyUtil.deepCopyList(chromosome.getMachines(), Machine.class);
snapshot.orders = ProductionDeepCopyUtil.deepCopyList(chromosome.getOrders(), Order.class);
snapshot.materials = ProductionDeepCopyUtil.deepCopyList(chromosome.getMaterials(), Material.class);
snapshot.allOperations = ProductionDeepCopyUtil.deepCopyList(chromosome.getAllOperations(), Entry.class);
snapshot.results = ProductionDeepCopyUtil.deepCopyList(chromosome.getResult(), GAScheduleResult.class);
snapshot.reOrderIds = new ArrayList<>(chromosome.getReOrderids());
return snapshot;
}
private void restoreTrialDecodeSnapshot(TrialDecodeSnapshot snapshot, Chromosome chromosome,
Map<Long, CopyOnWriteArrayList<GAScheduleResult>> machineTasksCache,
Map<Integer, Entry> entryIndexById,
Map<Integer, GAScheduleResult> scheduleIndexById) {
chromosome.setMachines(snapshot.machines);
chromosome.setOrders(snapshot.orders);
chromosome.setMaterials(snapshot.materials);
chromosome.setAllOperations(snapshot.allOperations);
chromosome.setResult(snapshot.results);
chromosome.setReOrderids(snapshot.reOrderIds);
machineTasksCache.clear();
entryIndexById.clear();
for (Entry entry : chromosome.getAllOperations()) {
entryIndexById.put(entry.getId(), entry);
}
scheduleIndexById.clear();
for (GAScheduleResult scheduleResult : chromosome.getResult()) {
scheduleIndexById.put(scheduleResult.getOperationId(), scheduleResult);
machineTasksCache.computeIfAbsent(scheduleResult.getMachineId(), key -> new CopyOnWriteArrayList<>()).add(scheduleResult);
}
}
private static class TrialDecodeSnapshot {
private List<Machine> machines;
private CopyOnWriteArrayList<Order> orders;
private List<Material> materials;
private CopyOnWriteArrayList<Entry> allOperations;
private CopyOnWriteArrayList<GAScheduleResult> results;
private List<Integer> reOrderIds;
} }
public void EditorderOperation(Chromosome chromosome, int groupId,double needed,Map<Long, CopyOnWriteArrayList<GAScheduleResult>> machineTasksCache,Map<Integer, Entry> entryIndexById,Map<Integer, GAScheduleResult> scheduleIndexById){ public void EditorderOperation(Chromosome chromosome, int groupId,double needed,Map<Long, CopyOnWriteArrayList<GAScheduleResult>> machineTasksCache,Map<Integer, Entry> entryIndexById,Map<Integer, GAScheduleResult> scheduleIndexById){
...@@ -1530,9 +1799,7 @@ public class GeneticDecoder { ...@@ -1530,9 +1799,7 @@ public class GeneticDecoder {
// 上个离散参数 // 上个离散参数
// String lastDiscreteParameter = machineState.get(machineId); // String lastDiscreteParameter = machineState.get(machineId);
int bomtime = getOperationBOMTime(currentOp,chromosome);
int prevendtime=prevtime; int prevendtime=prevtime;
prevtime = Math.max(prevtime, bomtime);
Machine machine = chromosome.getMachines().stream() Machine machine = chromosome.getMachines().stream()
.filter(m -> m.getId() == machineId) .filter(m -> m.getId() == machineId)
...@@ -2301,7 +2568,7 @@ public class GeneticDecoder { ...@@ -2301,7 +2568,7 @@ public class GeneticDecoder {
int i = 0; int i = 0;
for (ObjectiveConfig config : _globalParam.getObjectiveConfigs()) { for (ObjectiveConfig config : _globalParam.getObjectiveConfigs()) {
if (config.isEnabled()) { if (config.isEnabled()) {
if (config.getName() == GlobalParam.OBJECTIVE_MAKESPAN) { if (GlobalParam.OBJECTIVE_MAKESPAN.equals(config.getName())) {
// 1. 最早完工时间(最小化) // 1. 最早完工时间(最小化)
double makespan = chromosome.getResult().stream() double makespan = chromosome.getResult().stream()
.mapToInt(GAScheduleResult::getEndTime) .mapToInt(GAScheduleResult::getEndTime)
...@@ -2310,7 +2577,7 @@ public class GeneticDecoder { ...@@ -2310,7 +2577,7 @@ public class GeneticDecoder {
Objectives[i] = makespan; Objectives[i] = makespan;
chromosome.setMakespan(makespan); chromosome.setMakespan(makespan);
} }
if (config.getName() == GlobalParam.OBJECTIVE_TARDINESS) { if (GlobalParam.OBJECTIVE_TARDINESS.equals(config.getName())) {
// 2. 交付期满足情况(最小化延迟) // 2. 交付期满足情况(最小化延迟)
double tardiness = 0; double tardiness = 0;
...@@ -2353,24 +2620,29 @@ public class GeneticDecoder { ...@@ -2353,24 +2620,29 @@ public class GeneticDecoder {
Objectives[i] = tardiness; Objectives[i] = tardiness;
chromosome.setDelayTime(tardiness); chromosome.setDelayTime(tardiness);
} }
if (config.getName() == GlobalParam.OBJECTIVE_SETUP_TIME) { if (GlobalParam.OBJECTIVE_SETUP_TIME.equals(config.getName())) {
// 3. 最小总换型时间 // 3. 最小总换型时间
double totalSetupTime = calculateTotalSetupTime(chromosome); double totalSetupTime = calculateTotalSetupTime(chromosome);
chromosome.setTotalChangeoverTime(totalSetupTime); chromosome.setTotalChangeoverTime(totalSetupTime);
Objectives[i] = totalSetupTime; Objectives[i] = totalSetupTime;
} }
if (config.getName() == GlobalParam.OBJECTIVE_FLOW_TIME) { if (GlobalParam.OBJECTIVE_FLOW_TIME.equals(config.getName())) {
// 4. 最小化总流程时间 所有工序加工时间的总和 // 4. 最小化总流程时间 所有工序加工时间的总和
double totalFlowTime = calculateTotalFlowTime(chromosome); double totalFlowTime = calculateTotalFlowTime(chromosome);
chromosome.setTotalFlowTime(totalFlowTime); chromosome.setTotalFlowTime(totalFlowTime);
Objectives[i] = totalFlowTime; Objectives[i] = totalFlowTime;
} }
if (config.getName() == GlobalParam.OBJECTIVE_MACHINE_LOAD) { if (GlobalParam.OBJECTIVE_MACHINE_LOAD.equals(config.getName())) {
// 5. 机器负载均衡 // 5. 机器负载均衡
double machineLoadBalance = calculateMachineLoadBalance(chromosome); double machineLoadBalance = calculateMachineLoadBalance(chromosome);
chromosome.setMachineLoadStd(machineLoadBalance); chromosome.setMachineLoadStd(machineLoadBalance);
Objectives[i] = machineLoadBalance; Objectives[i] = machineLoadBalance;
} }
if (GlobalParam.OBJECTIVE_SEMI_JIT.equals(config.getName())) {
double semiJitSlack = calculateSemiJitSlack(chromosome);
chromosome.setSemiJitSlack(semiJitSlack);
Objectives[i] = semiJitSlack;
}
i++; i++;
} }
} }
...@@ -2429,6 +2701,27 @@ public class GeneticDecoder { ...@@ -2429,6 +2701,27 @@ public class GeneticDecoder {
// 标准差与平均值的比值衡量负载离散程度,值越小说明均衡度越高 // 标准差与平均值的比值衡量负载离散程度,值越小说明均衡度越高
return Math.sqrt(variance)/avgUtilization ; return Math.sqrt(variance)/avgUtilization ;
} }
private double calculateSemiJitSlack(Chromosome chromosome) {
Map<Integer, GAScheduleResult> resultByOperation = chromosome.getResult().stream()
.collect(Collectors.toMap(GAScheduleResult::getOperationId, t -> t, (left, right) -> left));
double semiJitSlack = 0;
for (Entry operation : chromosome.getAllOperations()) {
if (operation.getLatestCompletionTime() == null) {
continue;
}
GAScheduleResult result = resultByOperation.get(operation.getId());
if (result == null) {
continue;
}
LocalDateTime completionTime = baseTime.plusSeconds(result.getEndTime());
if (completionTime.isBefore(operation.getLatestCompletionTime())) {
semiJitSlack += ChronoUnit.MINUTES.between(completionTime, operation.getLatestCompletionTime());
}
}
return semiJitSlack;
}
/** /**
* 补全:创建缓存键(核心逻辑,需与原 C# CreateCacheKey 一致) * 补全:创建缓存键(核心逻辑,需与原 C# CreateCacheKey 一致)
* 思路:将染色体的核心特征(机器选择+工序排序)拼接为字符串,确保相同染色体生成相同键 * 思路:将染色体的核心特征(机器选择+工序排序)拼接为字符串,确保相同染色体生成相同键
......
...@@ -133,6 +133,9 @@ int opcount=allOperations.size(); ...@@ -133,6 +133,9 @@ int opcount=allOperations.size();
FileHelper.writeLogFile("按Objectives去重-----------开始-------" + population.size()); FileHelper.writeLogFile("按Objectives去重-----------开始-------" + population.size());
population = chromosomeDistinctByObjectives(population); population = chromosomeDistinctByObjectives(population);
FileHelper.writeLogFile("按Objectives去重-----------结束-------" + population.size()); FileHelper.writeLogFile("按Objectives去重-----------结束-------" + population.size());
if (population == null || population.isEmpty()) {
throw new RuntimeException("初始种群为空,请检查 populationSize、种群初始化和解码结果");
}
// if(1==1) // if(1==1)
// return getBestChromosome(population.get(0), param.getBaseTime(), starttime); // return getBestChromosome(population.get(0), param.getBaseTime(), starttime);
// 步骤2:对初始种群进行爬山法局部优化 // 步骤2:对初始种群进行爬山法局部优化
......
...@@ -1046,7 +1046,7 @@ public class MaterialRequirementService { ...@@ -1046,7 +1046,7 @@ public class MaterialRequirementService {
return new BOMBuildResult(materialRequirements, _childorders,_newEntrys); return new BOMBuildResult(materialRequirements, _childorders,_newEntrys);
} }
private OrderMaterialRequirement MaterialStock(Material material,String materialId,String orderId, String childorderId, Entry operation,double allneeded, double needed,LocalDateTime earliestStartTime ) { private OrderMaterialRequirement MaterialStock(Material material,String materialId,String orderId, String childorderId, Entry operation,double allneeded, double needed,LocalDateTime earliestStartTime, boolean commitChanges ) {
OrderMaterialRequirement orderMaterial = new OrderMaterialRequirement(); OrderMaterialRequirement orderMaterial = new OrderMaterialRequirement();
orderMaterial.setOrderId(orderId); orderMaterial.setOrderId(orderId);
...@@ -1054,16 +1054,16 @@ public class MaterialRequirementService { ...@@ -1054,16 +1054,16 @@ public class MaterialRequirementService {
orderMaterial.setChildOrderId(StringUtils.isBlank(childorderId) ? orderId : childorderId); orderMaterial.setChildOrderId(StringUtils.isBlank(childorderId) ? orderId : childorderId);
orderMaterial.setRequiredQuantity(allneeded); orderMaterial.setRequiredQuantity(allneeded);
orderMaterial.setQjQty(allneeded); orderMaterial.setQjQty(allneeded);
double availableNow = material.getCurrentStock();
orderMaterial.setMaterialCode(material.getCode()); orderMaterial.setMaterialCode(material.getCode());
orderMaterial.setMaterialName(material.getName()); orderMaterial.setMaterialName(material.getName());
orderMaterial.setMaterialTypeName(material.getMaterialTypeName()); orderMaterial.setMaterialTypeName(material.getMaterialTypeName());
orderMaterial.setMaterialId(material.getId()); orderMaterial.setMaterialId(material.getId());
// orderMaterial.setCheckLeadTime(material.getCkeckLeadTime());
double useStock=0; double useStock=0;
// 扣减现有库存 // 扣减现有库存
List<Stock> stocks= material.getMaterialStocks().stream() List<Stock> stocks= material.getMaterialStocks().stream()
.filter(t->t.getExpiryDate().compareTo(earliestStartTime)>=0&&t.getAvailableInventory()>0) .filter(t -> isStockValid(t, earliestStartTime) && t.getAvailableInventory() > 0)
.sorted(Comparator.comparing(Stock::getExpiryDate, Comparator.nullsLast(LocalDateTime::compareTo))
.thenComparing(Stock::getWarehousingDate, Comparator.nullsLast(LocalDateTime::compareTo)))
.collect(Collectors.toList()); .collect(Collectors.toList());
if(stocks!=null) if(stocks!=null)
{ {
...@@ -1071,7 +1071,9 @@ public class MaterialRequirementService { ...@@ -1071,7 +1071,9 @@ public class MaterialRequirementService {
double useStock1 = Math.min(needed,s.getAvailableInventory()); double useStock1 = Math.min(needed,s.getAvailableInventory());
needed -=useStock1; needed -=useStock1;
useStock+=useStock1; useStock+=useStock1;
s.setUsedInventory(s.getUsedInventory()+useStock1); if(commitChanges) {
s.setUsedInventory(s.getUsedInventory()+useStock1);
}
if(needed==0) if(needed==0)
{ {
break; break;
...@@ -1086,6 +1088,29 @@ public class MaterialRequirementService { ...@@ -1086,6 +1088,29 @@ public class MaterialRequirementService {
return orderMaterial; return orderMaterial;
} }
private boolean isStockValid(Stock stock, LocalDateTime demandTime) {
return stock.getExpiryDate() == null || !stock.getExpiryDate().isBefore(demandTime);
}
private void resetRequirementCalc(OrderMaterialRequirement orderMaterial) {
orderMaterial.setUseStock(0);
orderMaterial.setUseTransit(0);
orderMaterial.setArrivalTime(null);
orderMaterial.setPurchaseStartTime(null);
orderMaterial.setPurchaseEndTime(null);
orderMaterial.setUseTime(null);
if (orderMaterial.getReplaceMaterial() != null && !orderMaterial.getReplaceMaterial().isEmpty()) {
for (OrderMaterialRequirement replace : orderMaterial.getReplaceMaterial()) {
replace.setUseStock(0);
replace.setUseTransit(0);
replace.setArrivalTime(null);
replace.setPurchaseStartTime(null);
replace.setPurchaseEndTime(null);
replace.setUseTime(null);
}
}
}
private OrderMaterialRequirement CreateMaterialRequirement(Material material,String orderId, String childorderId, Entry operation,double need,double spentQty,double mainQty,double qty, LocalDateTime baseTime) { private OrderMaterialRequirement CreateMaterialRequirement(Material material,String orderId, String childorderId, Entry operation,double need,double spentQty,double mainQty,double qty, LocalDateTime baseTime) {
...@@ -1122,8 +1147,8 @@ public class MaterialRequirementService { ...@@ -1122,8 +1147,8 @@ public class MaterialRequirementService {
if (maxItem.isPresent()) { if (maxItem.isPresent()) {
MaterialPurchase result = maxItem.get(); MaterialPurchase result = maxItem.get();
orderMaterial.setCheckLeadTime(result.getPurchaseCycle()); orderMaterial.setPurchaseTime(result.getPurchaseCycle());
orderMaterial.setPurchaseTime(result.getInspectionCycle()); orderMaterial.setCheckLeadTime(result.getInspectionCycle());
} }
} }
orderMaterial.setUseTime(baseTime.plusDays(orderMaterial.getPurchaseTime()+orderMaterial.getCheckLeadTime())); orderMaterial.setUseTime(baseTime.plusDays(orderMaterial.getPurchaseTime()+orderMaterial.getCheckLeadTime()));
...@@ -1139,6 +1164,10 @@ public class MaterialRequirementService { ...@@ -1139,6 +1164,10 @@ public class MaterialRequirementService {
* @return 包含物料需求列表和子订单列表的结果对象(替代C#的out参数) * @return 包含物料需求列表和子订单列表的结果对象(替代C#的out参数)
*/ */
public void EditOperationBOM(Entry operation,Chromosome chromosome,LocalDateTime earliestStartTime,GeneticDecoder coder,Map<Long, CopyOnWriteArrayList<GAScheduleResult>> machineTasksCache,Map<Integer, Entry> entryIndexById,Map<Integer, GAScheduleResult> scheduleIndexById, LocalDateTime baseTime) { public void EditOperationBOM(Entry operation,Chromosome chromosome,LocalDateTime earliestStartTime,GeneticDecoder coder,Map<Long, CopyOnWriteArrayList<GAScheduleResult>> machineTasksCache,Map<Integer, Entry> entryIndexById,Map<Integer, GAScheduleResult> scheduleIndexById, LocalDateTime baseTime) {
EditOperationBOM(operation, chromosome, earliestStartTime, coder, machineTasksCache, entryIndexById, scheduleIndexById, baseTime, true);
}
public void EditOperationBOM(Entry operation,Chromosome chromosome,LocalDateTime earliestStartTime,GeneticDecoder coder,Map<Long, CopyOnWriteArrayList<GAScheduleResult>> machineTasksCache,Map<Integer, Entry> entryIndexById,Map<Integer, GAScheduleResult> scheduleIndexById, LocalDateTime baseTime, boolean commitChanges) {
List<OrderMaterialRequirement> materialRequirements = new ArrayList<>(); List<OrderMaterialRequirement> materialRequirements = new ArrayList<>();
String sceneId=chromosome.getScenarioID(); String sceneId=chromosome.getScenarioID();
...@@ -1169,6 +1198,7 @@ public class MaterialRequirementService { ...@@ -1169,6 +1198,7 @@ public class MaterialRequirementService {
double allneeded = orderMaterial.getSpentQty()/ orderMaterial.getMainQty() * operation.getQuantity(); double allneeded = orderMaterial.getSpentQty()/ orderMaterial.getMainQty() * operation.getQuantity();
double needed = allneeded; double needed = allneeded;
resetRequirementCalc(orderMaterial);
orderMaterial.setRequiredQuantity(needed); orderMaterial.setRequiredQuantity(needed);
orderMaterial.setQjQty(needed); orderMaterial.setQjQty(needed);
// 查找物料(流式处理替代First) // 查找物料(流式处理替代First)
...@@ -1183,7 +1213,9 @@ public class MaterialRequirementService { ...@@ -1183,7 +1213,9 @@ public class MaterialRequirementService {
double useStock=0; double useStock=0;
List<Stock> stocks= material.getMaterialStocks().stream() List<Stock> stocks= material.getMaterialStocks().stream()
.filter(t->t.getExpiryDate().compareTo(earliestStartTime)>=0&&t.getAvailableInventory()>0) .filter(t -> isStockValid(t, earliestStartTime) && t.getAvailableInventory() > 0)
.sorted(Comparator.comparing(Stock::getExpiryDate, Comparator.nullsLast(LocalDateTime::compareTo))
.thenComparing(Stock::getWarehousingDate, Comparator.nullsLast(LocalDateTime::compareTo)))
.collect(Collectors.toList()); .collect(Collectors.toList());
if(stocks!=null) if(stocks!=null)
{ {
...@@ -1191,7 +1223,9 @@ public class MaterialRequirementService { ...@@ -1191,7 +1223,9 @@ public class MaterialRequirementService {
double useStock1 = Math.min(needed,s.getAvailableInventory()); double useStock1 = Math.min(needed,s.getAvailableInventory());
needed -=useStock1; needed -=useStock1;
useStock+=useStock1; useStock+=useStock1;
s.setUsedInventory(s.getUsedInventory()+useStock1); if(commitChanges) {
s.setUsedInventory(s.getUsedInventory()+useStock1);
}
if(needed==0) if(needed==0)
{ {
break; break;
...@@ -1202,7 +1236,9 @@ public class MaterialRequirementService { ...@@ -1202,7 +1236,9 @@ public class MaterialRequirementService {
if (needed <= 0) { if (needed <= 0) {
orderMaterial.setYpQty(allneeded - needed); orderMaterial.setYpQty(allneeded - needed);
orderMaterial.setQjQty(needed); orderMaterial.setQjQty(needed);
remove.add(orderMaterial); if(commitChanges) {
remove.add(orderMaterial);
}
continue; continue;
} }
List<RoutingSupportingReplace> routingsupportingreplaces= GetRoutingSupportingReplaces(sceneId); List<RoutingSupportingReplace> routingsupportingreplaces= GetRoutingSupportingReplaces(sceneId);
...@@ -1222,7 +1258,7 @@ public class MaterialRequirementService { ...@@ -1222,7 +1258,7 @@ public class MaterialRequirementService {
if (material1 == null) { if (material1 == null) {
break; break;
} }
OrderMaterialRequirement orderMaterial1 = MaterialStock(material1, rsr.getTargetmaterialid(), orderMaterial.getOrderId(), orderMaterial.getChildOrderId(), operation, allneeded, needed, earliestStartTime); OrderMaterialRequirement orderMaterial1 = MaterialStock(material1, rsr.getTargetmaterialid(), orderMaterial.getOrderId(), orderMaterial.getChildOrderId(), operation, allneeded, needed, earliestStartTime, commitChanges);
if (orderMaterial1 != null) { if (orderMaterial1 != null) {
useStock = orderMaterial1.getUseStock(); useStock = orderMaterial1.getUseStock();
...@@ -1241,11 +1277,13 @@ public class MaterialRequirementService { ...@@ -1241,11 +1277,13 @@ public class MaterialRequirementService {
if (needed <= 0) { if (needed <= 0) {
orderMaterial.setYpQty(allneeded - needed); orderMaterial.setYpQty(allneeded - needed);
orderMaterial.setQjQty(needed); orderMaterial.setQjQty(needed);
remove.add(orderMaterial); if(commitChanges) {
remove.add(orderMaterial);
}
continue; continue;
} }
MaterialInTransit(material,"",orderMaterial,needed,earliestStartTime, materials); MaterialInTransit(material,"",orderMaterial,needed,earliestStartTime, materials, commitChanges);
needed -= orderMaterial.getUseTransit(); needed -= orderMaterial.getUseTransit();
...@@ -1266,7 +1304,7 @@ public class MaterialRequirementService { ...@@ -1266,7 +1304,7 @@ public class MaterialRequirementService {
break; break;
} }
MaterialInTransit(material1,rsr.getMaterialid(),orderMaterial1,needed,earliestStartTime, materials); MaterialInTransit(material1,rsr.getMaterialid(),orderMaterial1,needed,earliestStartTime, materials, commitChanges);
needed -= orderMaterial1.getUseTransit(); needed -= orderMaterial1.getUseTransit();
...@@ -1283,7 +1321,9 @@ public class MaterialRequirementService { ...@@ -1283,7 +1321,9 @@ public class MaterialRequirementService {
if (needed <= 0) { if (needed <= 0) {
orderMaterial.setYpQty(allneeded - needed); orderMaterial.setYpQty(allneeded - needed);
orderMaterial.setQjQty(needed); orderMaterial.setQjQty(needed);
remove.add(orderMaterial); if(commitChanges) {
remove.add(orderMaterial);
}
continue; continue;
} }
if (needed > 0) { if (needed > 0) {
...@@ -1303,8 +1343,8 @@ public class MaterialRequirementService { ...@@ -1303,8 +1343,8 @@ public class MaterialRequirementService {
MaterialPurchase result = materialPurchaseList.get(randomSeq); MaterialPurchase result = materialPurchaseList.get(randomSeq);
orderMaterial.setCheckLeadTime(result.getPurchaseCycle()); orderMaterial.setPurchaseTime(result.getPurchaseCycle());
orderMaterial.setPurchaseTime(result.getInspectionCycle()); orderMaterial.setCheckLeadTime(result.getInspectionCycle());
LocalDateTime purchaseEndTime = baseTime.plusDays(orderMaterial.getPurchaseTime() + orderMaterial.getCheckLeadTime()); LocalDateTime purchaseEndTime = baseTime.plusDays(orderMaterial.getPurchaseTime() + orderMaterial.getCheckLeadTime());
orderMaterial.setPurchaseEndTime(purchaseEndTime); orderMaterial.setPurchaseEndTime(purchaseEndTime);
} }
...@@ -1315,9 +1355,11 @@ public class MaterialRequirementService { ...@@ -1315,9 +1355,11 @@ public class MaterialRequirementService {
List<Integer> orderids= orderMaterial.getProductOrderID(); List<Integer> orderids= orderMaterial.getProductOrderID();
if(orderids!=null&&orderids.size()>0) { if(orderids!=null&&orderids.size()>0) {
for (Integer orderid : orderids) { if(commitChanges) {
coder.ClearorderOperationResult(chromosome, orderid); for (Integer orderid : orderids) {
coder.EditorderOperation(chromosome, orderid, needed,machineTasksCache, entryIndexById, scheduleIndexById); coder.ClearorderOperationResult(chromosome, orderid);
coder.EditorderOperation(chromosome, orderid, needed,machineTasksCache, entryIndexById, scheduleIndexById);
}
} }
}else { }else {
...@@ -1328,14 +1370,16 @@ public class MaterialRequirementService { ...@@ -1328,14 +1370,16 @@ public class MaterialRequirementService {
MaterialPurchase result = materialPurchaseList.get(randomSeq); MaterialPurchase result = materialPurchaseList.get(randomSeq);
orderMaterial.setCheckLeadTime(result.getPurchaseCycle()); orderMaterial.setPurchaseTime(result.getPurchaseCycle());
orderMaterial.setPurchaseTime(result.getInspectionCycle()); orderMaterial.setCheckLeadTime(result.getInspectionCycle());
LocalDateTime purchaseEndTime = baseTime.plusDays(orderMaterial.getPurchaseTime() + orderMaterial.getCheckLeadTime()); LocalDateTime purchaseEndTime = baseTime.plusDays(orderMaterial.getPurchaseTime() + orderMaterial.getCheckLeadTime());
orderMaterial.setPurchaseEndTime(purchaseEndTime); orderMaterial.setPurchaseEndTime(purchaseEndTime);
} }
} }
} }
orderMaterial.getReplaceMaterial().removeIf(t->t.getUseStock()==0&&t.getUseTransit()==0); if(commitChanges) {
orderMaterial.getReplaceMaterial().removeIf(t->t.getUseStock()==0&&t.getUseTransit()==0);
}
} }
// 计算预计可用时间 // 计算预计可用时间
...@@ -1357,7 +1401,7 @@ public class MaterialRequirementService { ...@@ -1357,7 +1401,7 @@ public class MaterialRequirementService {
} }
if (remove != null&&remove.size()>0) { if (commitChanges && remove != null&&remove.size()>0) {
//删除先删排产结果,然后记录orderID,到排产方案里,最后一起删除 //删除先删排产结果,然后记录orderID,到排产方案里,最后一起删除
for (OrderMaterialRequirement mr:remove) { for (OrderMaterialRequirement mr:remove) {
List<Integer> orderids= mr.getProductOrderID(); List<Integer> orderids= mr.getProductOrderID();
...@@ -1374,11 +1418,10 @@ public class MaterialRequirementService { ...@@ -1374,11 +1418,10 @@ public class MaterialRequirementService {
private void MaterialInTransit(Material material,String materialId, OrderMaterialRequirement orderMaterial, double needed,LocalDateTime earliestStartTime, List<Material> materials ){ private void MaterialInTransit(Material material,String materialId, OrderMaterialRequirement orderMaterial, double needed,LocalDateTime earliestStartTime, List<Material> materials, boolean commitChanges ){
// 处理在途物料 // 处理在途物料
double accumulated = 0; LocalDateTime earliestTime = null;
LocalDateTime earliestTime = LocalDateTime.of(2000,1,1,0,0,0);
double useTransit = 0; double useTransit = 0;
if (material == null) { if (material == null) {
material = materials.stream() material = materials.stream()
...@@ -1390,18 +1433,24 @@ public class MaterialRequirementService { ...@@ -1390,18 +1433,24 @@ public class MaterialRequirementService {
} }
} }
// 按到货时间排序在途物料 // 按到货时间排序在途物料
Long CkeckLeadTime= material.getCkeckLeadTime();
List<MaterialSupply> sortedInTransit = material.getInTransit().stream() List<MaterialSupply> sortedInTransit = material.getInTransit().stream()
.filter(t -> t.getQuantity() > 0&&t.getArrivalTime().compareTo(earliestStartTime)<=0 ) .filter(t -> t.getQuantity() > 0)
.sorted(Comparator.comparing(MaterialSupply::getArrivalTime).reversed()) .sorted(Comparator.comparing(MaterialSupply::getArrivalTime, Comparator.nullsLast(LocalDateTime::compareTo)))
.collect(Collectors.toList()); .collect(Collectors.toList());
for (MaterialSupply supply : sortedInTransit) { for (MaterialSupply supply : sortedInTransit) {
double useq = Math.min(needed, supply.getQuantity()); double useq = Math.min(needed, supply.getQuantity());
if (useq <= 0) {
continue;
}
useTransit += useq; useTransit += useq;
needed -= useq; needed -= useq;
supply.setQuantity(supply.getQuantity() - useq); if(commitChanges) {
earliestTime=earliestTime.compareTo(supply.getArrivalTime())>0?earliestTime:supply.getArrivalTime(); supply.setQuantity(supply.getQuantity() - useq);
}
if (earliestTime == null || (supply.getArrivalTime() != null && supply.getArrivalTime().isAfter(earliestTime))) {
earliestTime = supply.getArrivalTime();
}
if (needed <= 0) { if (needed <= 0) {
break; break;
} }
......
...@@ -19,7 +19,7 @@ public class NSGAIIUtils { ...@@ -19,7 +19,7 @@ public class NSGAIIUtils {
private int taskCount; // 并行任务数(默认=CPU核心数) private int taskCount; // 并行任务数(默认=CPU核心数)
private GlobalParam globalParam; // 全局参数配置 private GlobalParam globalParam; // 全局参数配置
// true 越小越好 // true 越小越好
private boolean[] isMinimize = {true, true, true, true, true}; private boolean[] isMinimize = {true, true, true, true, true, true};
...@@ -627,7 +627,8 @@ public class NSGAIIUtils { ...@@ -627,7 +627,8 @@ public class NSGAIIUtils {
for (int i = 0; i < kpisize; i++) { for (int i = 0; i < kpisize; i++) {
final int idx = i; final int idx = i;
if(isMinimize[i]) boolean minimize = i >= isMinimize.length || isMinimize[i];
if(minimize)
{ {
idealPoint[i] = front.stream().mapToDouble(c -> c.getObjectives()[idx]).min().orElse(0); idealPoint[i] = front.stream().mapToDouble(c -> c.getObjectives()[idx]).min().orElse(0);
......
package com.aps.service.Algorithm;
import com.aps.entity.Algorithm.Chromosome;
import com.aps.entity.Algorithm.GAScheduleResult;
import com.aps.entity.Algorithm.OrderMaterialRequirement;
import com.aps.entity.basic.Entry;
import com.aps.entity.basic.GlobalParam;
import com.aps.entity.basic.Material;
import com.aps.entity.Stock;
import java.time.LocalDateTime;
import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
import java.util.ArrayDeque;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;
/**
* 缂栬緫鍚庣殑缁熶竴 JIT 鍚庡鐞嗭細
* 鍏堜繚璇佸彲琛岋紝鍐嶆妸鍙楀奖鍝嶇殑鍗婃垚鍝佸皬鑼冨洿寰€鍚庢媺锛屽敖閲忚创杩戞柊鐨勭墿鏂欓渶姹傚伐搴忓紑宸ユ椂闂淬€?
*/
public class PostEditJitService {
public boolean applyPostEditJitBias(Chromosome chromosome, GlobalParam globalParam) {
clearTemporaryJitBias(chromosome);
if (chromosome == null
|| chromosome.getAllOperations() == null
|| chromosome.getAllOperations().isEmpty()
|| chromosome.getResult() == null
|| chromosome.getResult().isEmpty()) {
return false;
}
Map<Integer, GAScheduleResult> currentResults = chromosome.getResult().stream()
.collect(Collectors.toMap(GAScheduleResult::getOperationId, r -> r, (left, right) -> right));
Map<Integer, GAScheduleResult> previousResults = chromosome.getResultOld() == null
? Collections.emptyMap()
: chromosome.getResultOld().stream()
.collect(Collectors.toMap(GAScheduleResult::getOperationId, r -> r, (left, right) -> right));
Map<Integer, List<Entry>> operationsByGroup = chromosome.getAllOperations().stream()
.collect(Collectors.groupingBy(Entry::getGroupId));
Map<String, Material> materialsById = chromosome.getMaterials() == null
? Collections.emptyMap()
: chromosome.getMaterials().stream()
.collect(Collectors.toMap(Material::getId, m -> m, (left, right) -> left));
Map<Integer, Set<Integer>> childGroupsByParentOp = buildChildGroupIndex(chromosome.getAllOperations());
if (childGroupsByParentOp.isEmpty()) {
return false;
}
int bufferSeconds = Math.max(0, globalParam.getSemiJitBufferMinutes()) * 60;
Map<Integer, Integer> pendingParentStarts = new HashMap<>();
ArrayDeque<Integer> queue = new ArrayDeque<>();
for (Map.Entry<Integer, GAScheduleResult> entry : currentResults.entrySet()) {
int operationId = entry.getKey();
if (!isOperationChanged(entry.getValue(), previousResults.get(operationId))) {
continue;
}
if (!childGroupsByParentOp.containsKey(operationId) || childGroupsByParentOp.get(operationId).isEmpty()) {
continue;
}
pendingParentStarts.put(operationId, entry.getValue().getStartTime());
queue.offer(operationId);
}
if (queue.isEmpty()) {
return false;
}
boolean updated = false;
while (!queue.isEmpty()) {
Integer parentOperationId = queue.poll();
Integer parentStartTime = pendingParentStarts.get(parentOperationId);
if (parentStartTime == null) {
continue;
}
Set<Integer> childGroupIds = childGroupsByParentOp.get(parentOperationId);
if (childGroupIds == null || childGroupIds.isEmpty()) {
continue;
}
for (Integer childGroupId : childGroupIds) {
List<Entry> childOperations = operationsByGroup.get(childGroupId);
if (childOperations == null || childOperations.isEmpty()) {
continue;
}
int currentGroupStart = Integer.MAX_VALUE;
int currentGroupEnd = Integer.MIN_VALUE;
boolean allScheduled = true;
for (Entry childOperation : childOperations) {
GAScheduleResult childResult = currentResults.get(childOperation.getId());
if (childResult == null) {
allScheduled = false;
break;
}
currentGroupStart = Math.min(currentGroupStart, childResult.getStartTime());
currentGroupEnd = Math.max(currentGroupEnd, childResult.getEndTime());
}
if (!allScheduled || currentGroupEnd < currentGroupStart) {
continue;
}
Entry firstChildOperation = childOperations.stream()
.min(Comparator.comparingInt(Entry::getSequence))
.orElse(null);
if (firstChildOperation == null) {
continue;
}
GAScheduleResult firstChildResult = currentResults.get(firstChildOperation.getId());
if (firstChildResult != null
&& (firstChildResult.isIsLocked() || firstChildResult.getLockStartTime() == 1)) {
continue;
}
int groupSpan = currentGroupEnd - currentGroupStart;
int preferredStartTime = Math.max(0, parentStartTime - bufferSeconds - groupSpan);
int effectivePreferredStart = preferredStartTime;
Integer latestStockBackedStart = resolveLatestStockBackedGroupStart(
childOperations, currentResults, materialsById, chromosome.getBaseTime(), currentGroupStart);
if (latestStockBackedStart != null) {
effectivePreferredStart = Math.min(effectivePreferredStart, latestStockBackedStart);
}
if (firstChildOperation.isJitTemporary() && firstChildOperation.getJitPreferredStartTime() != null) {
int existingPreferredStart = (int) ChronoUnit.SECONDS.between(
chromosome.getBaseTime(), firstChildOperation.getJitPreferredStartTime());
effectivePreferredStart = Math.min(existingPreferredStart, preferredStartTime);
if (latestStockBackedStart != null) {
effectivePreferredStart = Math.min(effectivePreferredStart, latestStockBackedStart);
}
}
if (effectivePreferredStart <= currentGroupStart) {
continue;
}
firstChildOperation.setJitPreferredStartTime(chromosome.getBaseTime().plusSeconds(effectivePreferredStart));
firstChildOperation.setJitTemporary(true);
updated = true;
int groupShift = effectivePreferredStart - currentGroupStart;
if (groupShift <= 0) {
continue;
}
for (Entry childOperation : childOperations) {
if (!childGroupsByParentOp.containsKey(childOperation.getId())
|| childGroupsByParentOp.get(childOperation.getId()).isEmpty()) {
continue;
}
GAScheduleResult childResult = currentResults.get(childOperation.getId());
if (childResult == null) {
continue;
}
int shiftedParentStart = childResult.getStartTime() + groupShift;
Integer existingTarget = pendingParentStarts.get(childOperation.getId());
if (existingTarget == null || shiftedParentStart > existingTarget) {
pendingParentStarts.put(childOperation.getId(), shiftedParentStart);
queue.offer(childOperation.getId());
}
}
}
}
return updated;
}
public void clearTemporaryJitBias(Chromosome chromosome) {
if (chromosome == null || chromosome.getAllOperations() == null) {
return;
}
for (Entry operation : chromosome.getAllOperations()) {
operation.setJitPreferredStartTime(null);
operation.setJitTemporary(false);
}
}
private boolean isOperationChanged(GAScheduleResult current, GAScheduleResult previous) {
if (current == null) {
return false;
}
if (previous == null) {
return true;
}
return current.getStartTime() != previous.getStartTime()
|| current.getEndTime() != previous.getEndTime()
|| current.getMachineId() != previous.getMachineId();
}
private Integer resolveLatestStockBackedGroupStart(List<Entry> childOperations,
Map<Integer, GAScheduleResult> currentResults,
Map<String, Material> materialsById,
LocalDateTime baseTime,
int currentGroupStart) {
Integer latestGroupStart = null;
for (Entry childOperation : childOperations) {
GAScheduleResult childResult = currentResults.get(childOperation.getId());
if (childResult == null || childOperation.getMaterialRequirements() == null || childOperation.getMaterialRequirements().isEmpty()) {
continue;
}
int opOffset = childResult.getStartTime() - currentGroupStart;
for (OrderMaterialRequirement requirement : childOperation.getMaterialRequirements()) {
if (requirement == null || requirement.getUseStock() <= 0 || !"MP".equals(requirement.getMaterialTypeName())) {
continue;
}
Material material = materialsById.get(requirement.getMaterialId());
Integer latestOpStart = resolveLatestStockBackedOperationStart(material, requirement.getUseStock(), baseTime);
if (latestOpStart == null) {
continue;
}
int candidateGroupStart = latestOpStart - opOffset;
latestGroupStart = latestGroupStart == null
? candidateGroupStart
: Math.min(latestGroupStart, candidateGroupStart);
}
}
return latestGroupStart;
}
private Integer resolveLatestStockBackedOperationStart(Material material, double useStockQty, LocalDateTime baseTime) {
if (material == null || material.getMaterialStocks() == null || material.getMaterialStocks().isEmpty() || useStockQty <= 0) {
return null;
}
double remaining = useStockQty;
LocalDateTime earliestUsedExpiry = null;
List<Stock> stocks = material.getMaterialStocks().stream()
.filter(stock -> stock != null && stock.getTotal() - stock.getTotalLock() > 0)
.sorted(Comparator.comparing(Stock::getExpiryDate, Comparator.nullsLast(LocalDateTime::compareTo))
.thenComparing(Stock::getWarehousingDate, Comparator.nullsLast(LocalDateTime::compareTo)))
.collect(Collectors.toList());
for (Stock stock : stocks) {
double usableQty = stock.getTotal() - stock.getTotalLock();
if (usableQty <= 0) {
continue;
}
double consumeQty = Math.min(remaining, usableQty);
if (consumeQty <= 0) {
continue;
}
if (stock.getExpiryDate() != null) {
earliestUsedExpiry = earliestUsedExpiry == null || stock.getExpiryDate().isBefore(earliestUsedExpiry)
? stock.getExpiryDate()
: earliestUsedExpiry;
}
remaining -= consumeQty;
if (remaining <= 0) {
break;
}
}
if (earliestUsedExpiry == null) {
return null;
}
return (int) ChronoUnit.SECONDS.between(baseTime, earliestUsedExpiry);
}
private Map<Integer, Set<Integer>> buildChildGroupIndex(Collection<Entry> operations) {
Map<Integer, Set<Integer>> childGroupsByParentOp = new HashMap<>();
for (Entry operation : operations) {
if (operation.getDependentOnOrderIds() != null) {
for (Integer childGroupId : operation.getDependentOnOrderIds()) {
if (childGroupId != null) {
childGroupsByParentOp
.computeIfAbsent(operation.getId(), key -> new HashSet<>())
.add(childGroupId);
}
}
}
if (operation.getTargetFinishedOperationId() != null) {
for (Integer parentOperationId : operation.getTargetFinishedOperationId()) {
if (parentOperationId != null) {
childGroupsByParentOp
.computeIfAbsent(parentOperationId, key -> new HashSet<>())
.add(operation.getGroupId());
}
}
}
}
return childGroupsByParentOp.entrySet().stream()
.filter(entry -> entry.getValue() != null && !entry.getValue().isEmpty())
.collect(Collectors.toMap(Map.Entry::getKey, entry -> entry.getValue().stream()
.filter(Objects::nonNull)
.collect(Collectors.toSet())));
}
}
...@@ -1851,42 +1851,23 @@ if(targetOp.getSequence()>1) { ...@@ -1851,42 +1851,23 @@ if(targetOp.getSequence()>1) {
*/ */
public void redecode(Chromosome chromosome,LocalDateTime baseTime, GlobalParam globalParam) public void redecode(Chromosome chromosome,LocalDateTime baseTime, GlobalParam globalParam)
{ {
List<Material> baseMaterialsSnapshot = resolveDecodeMaterials(chromosome);
List<Material> UseMaterials= materialRequirementService.GetMaterials(chromosome.getScenarioID());
chromosome.setMaterials(new ArrayList<>());
if(UseMaterials==null) {
if (chromosome.getMaterialIds() != null && chromosome.getMaterialIds().size() > 0) {
List<Material> Materials = planResultService.InitMaterial();
UseMaterials = Materials.stream()
.filter(t -> chromosome.getMaterialIds()
.contains(t.getId())).collect(Collectors.toList());
chromosome.setMaterials(UseMaterials);
materialRequirementService.SetMaterials(chromosome.getScenarioID(),UseMaterials);
}
}else {
chromosome.setMaterials(UseMaterials);
}
DelOrder(chromosome);
MachineSchedulerService machineScheduler = new MachineSchedulerService(baseTime);
chromosome.setMachines(ProductionDeepCopyUtil.deepCopyList(chromosome.getInitMachines(),Machine.class) );
GeneticDecoder decoder = new GeneticDecoder(globalParam,baseTime, chromosome.getMachines(),
chromosome.getOrders(), null, machineScheduler,materialRequirementService,chromosome.getScenarioID());
chromosome.setResultOld(ProductionDeepCopyUtil.deepCopyList(chromosome.getResult(),GAScheduleResult.class)); chromosome.setResultOld(ProductionDeepCopyUtil.deepCopyList(chromosome.getResult(),GAScheduleResult.class));
chromosome.getResult().clear(); GeneticDecoder decoder = prepareDecodePass(chromosome, baseTime, globalParam, baseMaterialsSnapshot, true);
CopyOnWriteArrayList<GAScheduleResult> Resultlock= chromosome.getResult().stream()
.filter(o -> o.isIsLocked() == true)
.collect(Collectors.toCollection(CopyOnWriteArrayList::new));
chromosome.setResult(ProductionDeepCopyUtil.deepCopyList(Resultlock,GAScheduleResult.class));
decoder.decode(chromosome,false); decoder.decode(chromosome,false);
PostEditJitService postEditJitService = new PostEditJitService();
try {
if (postEditJitService.applyPostEditJitBias(chromosome, globalParam)) {
chromosome.setResultOld(ProductionDeepCopyUtil.deepCopyList(chromosome.getResult(),GAScheduleResult.class));
decoder = prepareDecodePass(chromosome, baseTime, globalParam, baseMaterialsSnapshot, false);
decoder.decode(chromosome,false, false);
}
} finally {
postEditJitService.clearTemporaryJitBias(chromosome);
}
KpiCalculator kpiCalculator=new KpiCalculator(chromosome); KpiCalculator kpiCalculator=new KpiCalculator(chromosome);
kpiCalculator.calculatekpi(); kpiCalculator.calculatekpi();
...@@ -1907,6 +1888,47 @@ if(targetOp.getSequence()>1) { ...@@ -1907,6 +1888,47 @@ if(targetOp.getSequence()>1) {
} }
private GeneticDecoder prepareDecodePass(Chromosome chromosome, LocalDateTime baseTime, GlobalParam globalParam,
List<Material> baseMaterialsSnapshot, boolean removeGeneratedOrders) {
if (removeGeneratedOrders) {
DelOrder(chromosome);
}
if (chromosome.getOrders() != null) {
chromosome.getOrders().forEach(order -> order.setCreateBom(false));
}
resetDecodeMaterials(chromosome, baseMaterialsSnapshot);
MachineSchedulerService machineScheduler = new MachineSchedulerService(baseTime);
chromosome.setMachines(ProductionDeepCopyUtil.deepCopyList(chromosome.getInitMachines(),Machine.class) );
chromosome.getResult().clear();
chromosome.setResult(new CopyOnWriteArrayList<>());
return new GeneticDecoder(globalParam,baseTime, chromosome.getMachines(),
chromosome.getOrders(), null, machineScheduler,materialRequirementService,chromosome.getScenarioID());
}
private List<Material> resolveDecodeMaterials(Chromosome chromosome) {
List<Material> useMaterials = materialRequirementService.GetMaterials(chromosome.getScenarioID());
if (useMaterials == null && chromosome.getMaterialIds() != null && chromosome.getMaterialIds().size() > 0) {
List<Material> materials = planResultService.InitMaterial();
useMaterials = materials.stream()
.filter(t -> chromosome.getMaterialIds().contains(t.getId()))
.collect(Collectors.toList());
}
if (useMaterials == null) {
useMaterials = new ArrayList<>();
}
return ProductionDeepCopyUtil.deepCopyList(useMaterials, Material.class);
}
private void resetDecodeMaterials(Chromosome chromosome, List<Material> baseMaterialsSnapshot) {
List<Material> materialsForDecode = ProductionDeepCopyUtil.deepCopyList(baseMaterialsSnapshot, Material.class);
chromosome.setMaterials(materialsForDecode);
materialRequirementService.SetMaterials(chromosome.getScenarioID(), materialsForDecode);
}
public void DelOrder(Chromosome chromosome) { public void DelOrder(Chromosome chromosome) {
List<Entry> allOperations = chromosome.getAllOperations(); List<Entry> allOperations = chromosome.getAllOperations();
List<GlobalOperationInfo> globalOpList= chromosome.getGlobalOpList(); List<GlobalOperationInfo> globalOpList= chromosome.getGlobalOpList();
...@@ -1914,7 +1936,7 @@ if(targetOp.getSequence()>1) { ...@@ -1914,7 +1936,7 @@ if(targetOp.getSequence()>1) {
List<Integer> OperationSequencing= chromosome.getOperationSequencing(); List<Integer> OperationSequencing= chromosome.getOperationSequencing();
List<GAScheduleResult> ScheduleResults = chromosome.getResult(); List<GAScheduleResult> ScheduleResults = chromosome.getResult();
List<Integer> newoorderids= orders.stream() List<Integer> newoorderids= orders.stream()
.filter(t->t.isNewCreate()) .filter(t -> t.isNewCreate() || t.isNewSfCreate())
.map(Order::getId) .map(Order::getId)
.sorted(Comparator.reverseOrder()) .sorted(Comparator.reverseOrder())
.collect(Collectors.toList()); .collect(Collectors.toList());
......
...@@ -1867,6 +1867,7 @@ public class PlanResultService { ...@@ -1867,6 +1867,7 @@ public class PlanResultService {
FileHelper.writeLogFile(String.format("Setup Time: %f minutes", schedule.getTotalChangeoverTime())); FileHelper.writeLogFile(String.format("Setup Time: %f minutes", schedule.getTotalChangeoverTime()));
FileHelper.writeLogFile(String.format("Flow Time: %f minutes", schedule.getTotalFlowTime())); FileHelper.writeLogFile(String.format("Flow Time: %f minutes", schedule.getTotalFlowTime()));
FileHelper.writeLogFile(String.format("Machine Load Balance: %.2f%%", schedule.getMachineLoadStd() * 100)); FileHelper.writeLogFile(String.format("Machine Load Balance: %.2f%%", schedule.getMachineLoadStd() * 100));
FileHelper.writeLogFile(String.format("Semi JIT Slack: %f minutes", schedule.getSemiJitSlack()));
FileHelper.writeLogFile("-------------------------"); FileHelper.writeLogFile("-------------------------");
// 按订单分组写入 // 按订单分组写入
......
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