Commit f1998b61 authored by Tong Li's avatar Tong Li

变邻域+模拟退火+禁忌搜索

parent 8a7de711
...@@ -156,6 +156,11 @@ public class Order { ...@@ -156,6 +156,11 @@ public class Order {
* 是否新创建,默认值:false * 是否新创建,默认值:false
*/ */
private boolean newCreate = false; private boolean newCreate = false;
/**
* 是否新创建半成品,默认值:false
*/
private boolean newSfCreate = false;
/** /**
* 是否创建BOM,默认值:false * 是否创建BOM,默认值:false
......
...@@ -35,13 +35,13 @@ import java.util.stream.IntStream; ...@@ -35,13 +35,13 @@ import java.util.stream.IntStream;
public class GeneticDecoder { public class GeneticDecoder {
// private final Map<String, Chromosome> decodingCache = new HashMap<>(); // private final Map<String, Chromosome> decodingCache = new HashMap<>();
private final ConcurrentHashMap<String, Chromosome> decodingCache = new ConcurrentHashMap<>(); private final ConcurrentHashMap<String, Chromosome> decodingCache = new ConcurrentHashMap<>();
// 缓存大小限制 // 缓存大小限制
private static final int MAX_CACHE_SIZE = 3000; private static final int MAX_CACHE_SIZE = 3000;
// 线程安全锁:避免多线程下缓存操作冲突(可选,若单线程可移除) // 线程安全锁:避免多线程下缓存操作冲突(可选,若单线程可移除)
// private final ReentrantLock cacheLock = new ReentrantLock(); // private final ReentrantLock cacheLock = new ReentrantLock();
private LocalDateTime baseTime; private LocalDateTime baseTime;
private final List<Machine> machines; private final List<Machine> machines;
private final MachineSchedulerService machineScheduler; private final MachineSchedulerService machineScheduler;
...@@ -70,10 +70,10 @@ public class GeneticDecoder { ...@@ -70,10 +70,10 @@ public class GeneticDecoder {
this.materials = materials; this.materials = materials;
this.machineScheduler = machineScheduler; this.machineScheduler = machineScheduler;
_globalParam=globalParam; _globalParam=globalParam;
machineCalculator=new MachineCalculator(baseTime,machines,machineScheduler); machineCalculator=new MachineCalculator(baseTime,machines,machineScheduler);
materialRequirementService=_materialRequirementService; materialRequirementService=_materialRequirementService;
sceneId=_sceneId; sceneId=_sceneId;
// this.orderMaxID = orders.stream().mapToInt(Order::getId).max().orElse(0); // this.orderMaxID = orders.stream().mapToInt(Order::getId).max().orElse(0);
} }
private final ExecutorService decodeExecutor = new ThreadPoolExecutor( private final ExecutorService decodeExecutor = new ThreadPoolExecutor(
...@@ -266,7 +266,7 @@ public class GeneticDecoder { ...@@ -266,7 +266,7 @@ public class GeneticDecoder {
Initialization initialization=new Initialization(); Initialization initialization=new Initialization();
initialization.generateInitialSFPopulation(chromosome,globalOpList); initialization.generateInitialSFPopulation(chromosome,globalOpList);
chromosome.getGlobalOpList().addAll(globalOpList); chromosome.getGlobalOpList().addAll(globalOpList);
return 1; return 1;
} }
private void CreateNewOpSequence(Chromosome chromosome) private void CreateNewOpSequence(Chromosome chromosome)
...@@ -279,10 +279,10 @@ return 1; ...@@ -279,10 +279,10 @@ return 1;
.distinct() .distinct()
.collect(Collectors.toList()); .collect(Collectors.toList());
if(finishedOrder==null||finishedOrder.size()==0) if(finishedOrder==null||finishedOrder.size()==0)
{ {
return; return;
} }
List<Integer> oldSequence=chromosome.getOperationSequencing(); List<Integer> oldSequence=chromosome.getOperationSequencing();
List<Integer> finalSequence = new ArrayList<>(); List<Integer> finalSequence = new ArrayList<>();
...@@ -359,7 +359,7 @@ if(finishedOrder==null||finishedOrder.size()==0) ...@@ -359,7 +359,7 @@ if(finishedOrder==null||finishedOrder.size()==0)
} }
finalSequence.add(orderid); finalSequence.add(orderid);
}else { }else {
int insertPos = Math.max(0, finalSequence.size()); int insertPos = Math.max(0, finalSequence.size());
// int insertPos = Math.max(0, finalSequence.size() - rnd.nextInt(2)); // int insertPos = Math.max(0, finalSequence.size() - rnd.nextInt(2));
finalSequence.add(insertPos,orderid); finalSequence.add(insertPos,orderid);
...@@ -373,10 +373,10 @@ if(finishedOrder==null||finishedOrder.size()==0) ...@@ -373,10 +373,10 @@ if(finishedOrder==null||finishedOrder.size()==0)
// // 根据工序数量和CPU核心数决定是否使用内部并行 // // 根据工序数量和CPU核心数决定是否使用内部并行
if (isParallel) { if (isParallel) {
// 使用设备并行处理 // 使用设备并行处理
// FileHelper.writeLogFile("使用并行处理 _s"); // FileHelper.writeLogFile("使用并行处理 _s");
parallelDecodeByMachine(chromosome); parallelDecodeByMachine(chromosome);
// FileHelper.writeLogFile("使用并行处理 _e"); // FileHelper.writeLogFile("使用并行处理 _e");
} }
else { else {
// 使用串行处理 // 使用串行处理
// FileHelper.writeLogFile("使用串行处理 _s"); // FileHelper.writeLogFile("使用串行处理 _s");
...@@ -391,14 +391,14 @@ if(finishedOrder==null||finishedOrder.size()==0) ...@@ -391,14 +391,14 @@ if(finishedOrder==null||finishedOrder.size()==0)
public void serialDecode(Chromosome chromosome) { public void serialDecode(Chromosome chromosome) {
// List<OrderMaterialRequirement> orderMaterials = materialRequirementService.buildMultiLevelRequirementNetwork(chromosome, sceneId, baseTime,_globalParam); List<OrderMaterialRequirement> orderMaterials = materialRequirementService.buildMultiLevelRequirementNetwork(chromosome, sceneId, baseTime,_globalParam);
chromosome.setScenarioID(sceneId); chromosome.setScenarioID(sceneId);
if(_globalParam.isIsCheckSf()) { if(_globalParam.isIsCheckSf()) {
int isnew= generateGlobalOpList(chromosome); int isnew= generateGlobalOpList(chromosome);
if(isnew==1) { if(isnew==1) {
CreateNewOpSequence(chromosome); CreateNewOpSequence(chromosome);
} }
} }
List<GlobalOperationInfo> globalOpList=chromosome.getGlobalOpList(); List<GlobalOperationInfo> globalOpList=chromosome.getGlobalOpList();
...@@ -486,7 +486,7 @@ if(finishedOrder==null||finishedOrder.size()==0) ...@@ -486,7 +486,7 @@ if(finishedOrder==null||finishedOrder.size()==0)
// Map<Long, String> machineState = chromosome.getMachines().stream() // Map<Long, String> machineState = chromosome.getMachines().stream()
// .collect(Collectors.toMap(Machine::getId, m -> "")); // .collect(Collectors.toMap(Machine::getId, m -> ""));
// List<Entry> allScheduledOps = new ArrayList<>(); // List<Entry> allScheduledOps = new ArrayList<>();
// 缓存机器任务 // 缓存机器任务
Map<Long, CopyOnWriteArrayList<GAScheduleResult>> machineTasksCache = new HashMap<>(); Map<Long, CopyOnWriteArrayList<GAScheduleResult>> machineTasksCache = new HashMap<>();
...@@ -541,26 +541,26 @@ if(finishedOrder==null||finishedOrder.size()==0) ...@@ -541,26 +541,26 @@ if(finishedOrder==null||finishedOrder.size()==0)
// } // }
// 上个离散参数 // 上个离散参数
// String lastDiscreteParameter = machineState.get(machineId); // String lastDiscreteParameter = machineState.get(machineId);
// int bomtime = getOperationBOMTime(currentOp,chromosome); // int bomtime = getOperationBOMTime(currentOp,chromosome);
// int prevendtime=prevtime; // int prevendtime=prevtime;
// prevtime = Math.max(prevtime, bomtime); // 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)
// .findFirst() // .findFirst()
// .orElse(null); // .orElse(null);
// Machine machine = machineIdMap.get(machineId); // Machine machine = machineIdMap.get(machineId);
// int changeoverTime =0; //(lastDiscreteParameter.isEmpty() || // int changeoverTime =0; //(lastDiscreteParameter.isEmpty() ||
// lastDiscreteParameter.equals(currentOp.getDiscreteParameter())) ? 0 : 0; // lastDiscreteParameter.equals(currentOp.getDiscreteParameter())) ? 0 : 0;
int actualEndTime = processOperation(currentOp,machineId,processTime,machineOption,chromosome,machineIdMap,machineTasksCache,entryIndexById,scheduleIndexById); int actualEndTime = processOperation(currentOp,machineId,processTime,machineOption,chromosome,machineIdMap,machineTasksCache,entryIndexById,scheduleIndexById);
// int actualEndTime = processWithSingleMachine(currentOp, machine, processTime, prevtime,machineOption, chromosome,false,prevendtime,machineTasksCache); // int actualEndTime = processWithSingleMachine(currentOp, machine, processTime, prevtime,machineOption, chromosome,false,prevendtime,machineTasksCache);
orderProcessCounter.put(groupId, orderProcessCounter.get(groupId) + 1); orderProcessCounter.put(groupId, orderProcessCounter.get(groupId) + 1);
orderLastEndTime.put(groupId, actualEndTime); orderLastEndTime.put(groupId, actualEndTime);
// machineState.put(machineId, currentOp.getDiscreteParameter()); // machineState.put(machineId, currentOp.getDiscreteParameter());
} }
if(chromosome.getReOrderids()!=null&&chromosome.getReOrderids().size()>0) { if(chromosome.getReOrderids()!=null&&chromosome.getReOrderids().size()>0) {
chromosome.getOperationSequencing().removeIf(t -> chromosome.getReOrderids().contains(t)); chromosome.getOperationSequencing().removeIf(t -> chromosome.getReOrderids().contains(t));
...@@ -837,17 +837,17 @@ if(finishedOrder==null||finishedOrder.size()==0) ...@@ -837,17 +837,17 @@ if(finishedOrder==null||finishedOrder.size()==0)
double processTime = machineOption.getProcessingTime(); double processTime = machineOption.getProcessingTime();
// 处理当前工序 // 处理当前工序
// long processStartTime = System.currentTimeMillis(); // long processStartTime = System.currentTimeMillis();
int actualEndTime = processOperation(op,machineId,processTime,machineOption,chromosome,machineIdMap,machineTasksCache, entryIndexById,scheduleIndexById); int actualEndTime = processOperation(op,machineId,processTime,machineOption,chromosome,machineIdMap,machineTasksCache, entryIndexById,scheduleIndexById);
// long processEndTime = System.currentTimeMillis(); // long processEndTime = System.currentTimeMillis();
// 标记工序完成 // 标记工序完成
synchronized (lock) { synchronized (lock) {
opCompleted.put(opId, true); opCompleted.put(opId, true);
} }
// long opEndTime = System.currentTimeMillis(); // long opEndTime = System.currentTimeMillis();
// if (i % 100 == 0 || i == ops.size() - 1) { // if (i % 100 == 0 || i == ops.size() - 1) {
// FileHelper.writeLogFile("设备 " + machineId + " 工序 " + i + "/" + ops.size() + // FileHelper.writeLogFile("设备 " + machineId + " 工序 " + i + "/" + ops.size() +
// " 完成,总耗时:" + (opEndTime - machineStartTime) + "ms,本工序耗时:" + (opEndTime - opStartTime) + "ms"); // " 完成,总耗时:" + (opEndTime - machineStartTime) + "ms,本工序耗时:" + (opEndTime - opStartTime) + "ms");
...@@ -973,8 +973,8 @@ if(finishedOrder==null||finishedOrder.size()==0) ...@@ -973,8 +973,8 @@ if(finishedOrder==null||finishedOrder.size()==0)
return result; return result;
} }
/** /**
* 构建工序ID索引:opId -> Entry(O(1)查找) * 构建工序ID索引:opId -> Entry(O(1)查找)
*/ */
private Map<Integer, Entry> buildOpIdIndex(Chromosome chromosome) { private Map<Integer, Entry> buildOpIdIndex(Chromosome chromosome) {
Map<Integer, Entry> index = new HashMap<>(); Map<Integer, Entry> index = new HashMap<>();
for (Entry op : chromosome.getAllOperations()) { for (Entry op : chromosome.getAllOperations()) {
...@@ -1014,7 +1014,7 @@ if(finishedOrder==null||finishedOrder.size()==0) ...@@ -1014,7 +1014,7 @@ if(finishedOrder==null||finishedOrder.size()==0)
prevtime = Math.max(prevtime, bomtime); 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;
} }
...@@ -1037,7 +1037,7 @@ return actualEndTime; ...@@ -1037,7 +1037,7 @@ return actualEndTime;
} }
if(machine==null||operation.getMachineOptions()==null) if(machine==null||operation.getMachineOptions()==null)
{ {
return 0; return 0;
} }
// MachineOption machineOption= operation.getMachineOptions().stream() // MachineOption machineOption= operation.getMachineOptions().stream()
...@@ -1063,7 +1063,7 @@ return actualEndTime; ...@@ -1063,7 +1063,7 @@ return actualEndTime;
//前处理,是否可以在相同任务前序未完工就开始设置时间, //前处理,是否可以在相同任务前序未完工就开始设置时间,
// 就是 最早开工时间是否+前处理时间,总的加工工时不考虑前处理 // 就是 最早开工时间是否+前处理时间,总的加工工时不考虑前处理
if (!_globalParam.is_smoothSetup()) { if (!_globalParam.is_smoothSetup()) {
// 工序的前处理不能提前,则要在前处理完成后才能开工,所以要在前一工序的结束时间基础上+前处理 // 工序的前处理不能提前,则要在前处理完成后才能开工,所以要在前一工序的结束时间基础上+前处理
earliestStartTime+=preTime; earliestStartTime+=preTime;
} }
GAScheduleResult existingResult = chromosome.getResultOld().stream().filter(r-> r.getOperationId() == operation.getId()).findFirst().orElse(null); GAScheduleResult existingResult = chromosome.getResultOld().stream().filter(r-> r.getOperationId() == operation.getId()).findFirst().orElse(null);
...@@ -1077,18 +1077,18 @@ return actualEndTime; ...@@ -1077,18 +1077,18 @@ return actualEndTime;
if (machineTasksCache.containsKey(machine.getId())) { if (machineTasksCache.containsKey(machine.getId())) {
machineTasks = machineTasksCache.get(machine.getId()); machineTasks = machineTasksCache.get(machine.getId());
} else { } else {
machineTasks = chromosome.getResult().stream() machineTasks = chromosome.getResult().stream()
.filter(t -> t.getMachineId() == machine.getId()) .filter(t -> t.getMachineId() == machine.getId())
.sorted(Comparator.comparingInt(GAScheduleResult::getStartTime)) .sorted(Comparator.comparingInt(GAScheduleResult::getStartTime))
.collect(Collectors.toCollection(CopyOnWriteArrayList::new)); .collect(Collectors.toCollection(CopyOnWriteArrayList::new));
machineTasksCache.put(machine.getId(), machineTasks); machineTasksCache.put(machine.getId(), machineTasks);
} }
GAScheduleResult lastGeneOnMachine = null; GAScheduleResult lastGeneOnMachine = null;
if(machineTasks!=null&&machineTasks.size()>0) if(machineTasks!=null&&machineTasks.size()>0)
{ {
lastGeneOnMachine=machineTasks.get(machineTasks.size()-1); lastGeneOnMachine=machineTasks.get(machineTasks.size()-1);
} }
if(lastGeneOnMachine!=null&&_globalParam.is_smoothChangeOver()) if(lastGeneOnMachine!=null&&_globalParam.is_smoothChangeOver())
{ {
earliestStartTime = Math.max(earliestStartTime,lastGeneOnMachine.getEndTime()); earliestStartTime = Math.max(earliestStartTime,lastGeneOnMachine.getEndTime());
...@@ -1105,8 +1105,8 @@ return actualEndTime; ...@@ -1105,8 +1105,8 @@ return actualEndTime;
if (_globalParam.is_smoothChangeOver()) { if (_globalParam.is_smoothChangeOver()) {
Map<Integer, Object> reslte = calculateSetupTime(lastGeneOnMachine, operation, machine, earliestStartTime, processingTimeTotal, _globalParam.is_smoothChangeOverInWeek(), chromosome.getAllOperations()); Map<Integer, Object> reslte = calculateSetupTime(lastGeneOnMachine, operation, machine, earliestStartTime, processingTimeTotal, _globalParam.is_smoothChangeOverInWeek(), chromosome.getAllOperations());
// setupTime = (int) reslte.get(1);//换型时间 // setupTime = (int) reslte.get(1);//换型时间
// int setupStartTime = (int) reslte.get(2);//换型开始时间 // int setupStartTime = (int) reslte.get(2);//换型开始时间
//earliestStartTime=(int)reslte.get(3);//上个任务的结束时间 //earliestStartTime=(int)reslte.get(3);//上个任务的结束时间
earliestStartTime = (int) reslte.get(4);//最早开工时间 earliestStartTime = (int) reslte.get(4);//最早开工时间
} }
...@@ -1121,7 +1121,7 @@ return actualEndTime; ...@@ -1121,7 +1121,7 @@ return actualEndTime;
: earliestStartTime; : earliestStartTime;
} }
bomtime= EditOperationBOMTime(operation,chromosome,earliestStartTime,machineTasksCache, entryIndexById, scheduleIndexById); bomtime= EditOperationBOMTime(operation,chromosome,earliestStartTime,machineTasksCache, entryIndexById, scheduleIndexById);
if(bomtime>prevendtime&&bomtime<earliestStartTimeold) if(bomtime>prevendtime&&bomtime<earliestStartTimeold)
...@@ -1211,9 +1211,9 @@ return actualEndTime; ...@@ -1211,9 +1211,9 @@ return actualEndTime;
//开工时间需往后延 2小时 //开工时间需往后延 2小时
// 准备工时 加入到加工时间里 // 准备工时 加入到加工时间里
// 后处理时间 相同任务的前一工序的结束时间+后处理时间 =当前工序最早开工时间 // 后处理时间 相同任务的前一工序的结束时间+后处理时间 =当前工序最早开工时间
GAScheduleResult result=new GAScheduleResult(); GAScheduleResult result=new GAScheduleResult();
...@@ -1250,17 +1250,17 @@ return actualEndTime; ...@@ -1250,17 +1250,17 @@ return actualEndTime;
processingTimeTotal1=(int) geneDetails.stream().filter(t->t.getUsedSegment()==null).mapToDouble(ScheduleResultDetail::getProcessingTime) // 替换为实际字段名 processingTimeTotal1=(int) geneDetails.stream().filter(t->t.getUsedSegment()==null).mapToDouble(ScheduleResultDetail::getProcessingTime) // 替换为实际字段名
.sum(); .sum();
List<TimeSegment> UsedSegments=geneDetails.stream(). List<TimeSegment> UsedSegments=geneDetails.stream().
filter(t->t.getUsedSegment()!=null) filter(t->t.getUsedSegment()!=null)
.map(ScheduleResultDetail::getUsedSegment).flatMap(List::stream) .map(ScheduleResultDetail::getUsedSegment).flatMap(List::stream)
// 收集为最终的 List // 收集为最终的 List
.collect(Collectors.toList()); .collect(Collectors.toList());
if(UsedSegments!=null&&UsedSegments.size()>0) if(UsedSegments!=null&&UsedSegments.size()>0)
{ {
processingTimeTotal1+=(int)UsedSegments.stream().mapToDouble(TimeSegment::getProcessingTime) // 替换为实际字段名 processingTimeTotal1+=(int)UsedSegments.stream().mapToDouble(TimeSegment::getProcessingTime) // 替换为实际字段名
.sum(); .sum();
} }
result.setProcessingTime(processingTimeTotal1); result.setProcessingTime(processingTimeTotal1);
...@@ -1268,15 +1268,15 @@ return actualEndTime; ...@@ -1268,15 +1268,15 @@ return actualEndTime;
// System.out.println("huanxingshijian="+result.getChangeOverTime()+"-------------------"+result.getOrderId()+"--------"+result.getExecId()+"---------"+prev.getOrderId()+"--------"+prev.getExecId()); // System.out.println("huanxingshijian="+result.getChangeOverTime()+"-------------------"+result.getOrderId()+"--------"+result.getExecId()+"---------"+prev.getOrderId()+"--------"+prev.getExecId());
chromosome.getResult().add(result); chromosome.getResult().add(result);
machine.setLastGene(result); machine.setLastGene(result);
// FileHelper.writeLogFile(" 结束 "+ConvertTime(startTime)+"--"+ConvertTime(endTime)+" "+operation.getGroupId()+" : "+operation.getId()+",处理时间: " + processingTime + ", 后处理: " + teardownTime + // FileHelper.writeLogFile(" 结束 "+ConvertTime(startTime)+"--"+ConvertTime(endTime)+" "+operation.getGroupId()+" : "+operation.getId()+",处理时间: " + processingTime + ", 后处理: " + teardownTime +
// ", 前处理: " + preTime + ", 换型: " + setupTime+ ", 数量: " + operation.getQuantity()+ ", 设备: "+machine.getId()+ ", 是否可中断: "+operation.getIsInterrupt()); // ", 前处理: " + preTime + ", 换型: " + setupTime+ ", 数量: " + operation.getQuantity()+ ", 设备: "+machine.getId()+ ", 是否可中断: "+operation.getIsInterrupt());
if (machineTasks != null) { if (machineTasks != null) {
machineTasks.add(result); machineTasks.add(result);
} }
scheduleIndexById.put(operation.getId(),result); scheduleIndexById.put(operation.getId(),result);
return endTime; return endTime;
} }
...@@ -1297,7 +1297,7 @@ return actualEndTime; ...@@ -1297,7 +1297,7 @@ return actualEndTime;
// .filter(t -> t.getOperationId() == opid.getPrevOperationId()) // .filter(t -> t.getOperationId() == opid.getPrevOperationId())
// .collect(Collectors.toList());// // .collect(Collectors.toList());//
GAScheduleResult prevOp= scheduleIndexById.get(opid.getPrevOperationId()); GAScheduleResult prevOp= scheduleIndexById.get(opid.getPrevOperationId());
// for (GAScheduleResult prevOp : prevOperations) { // for (GAScheduleResult prevOp : prevOperations) {
if(prevOp!=null){ if(prevOp!=null){
//加上后处理时间 //加上后处理时间
prevtime = Math.max(prevtime, prevOp.getEndTime() + currentOp.getTeardownTime()); prevtime = Math.max(prevtime, prevOp.getEndTime() + currentOp.getTeardownTime());
...@@ -1320,14 +1320,14 @@ return actualEndTime; ...@@ -1320,14 +1320,14 @@ return actualEndTime;
// .collect(Collectors.toList());//多台 // .collect(Collectors.toList());//多台
GAScheduleResult prevOp= scheduleIndexById.get(opid.getPrevOperationId()); GAScheduleResult prevOp= scheduleIndexById.get(opid.getPrevOperationId());
// for (GAScheduleResult prevOp : prevOperations) { // for (GAScheduleResult prevOp : prevOperations) {
if(prevOp!=null){ if(prevOp!=null){
newScheduleResult.add(prevOp); newScheduleResult.add(prevOp);
newScheduleResultDetails.addAll(prevOp.getGeneDetails()); newScheduleResultDetails.addAll(prevOp.getGeneDetails());
} }
if(j==SSOperations.size()-1) if(j==SSOperations.size()-1)
{ {
int prevtime1 = CalSSPrevtime(newScheduleResult,newScheduleResultDetails, prevtime, currentOp, chromosome, processTime, machine); int prevtime1 = CalSSPrevtime(newScheduleResult,newScheduleResultDetails, prevtime, currentOp, chromosome, processTime, machine);
prevtime = Math.max(prevtime, prevtime1); prevtime = Math.max(prevtime, prevtime1);
}else { }else {
...@@ -1344,7 +1344,7 @@ return actualEndTime; ...@@ -1344,7 +1344,7 @@ return actualEndTime;
if(entry!=null&&entry1!=null&&entry.getRoutingDetailId()!=entry1.getRoutingDetailId()) if(entry!=null&&entry1!=null&&entry.getRoutingDetailId()!=entry1.getRoutingDetailId())
{ {
int prevtime1 = CalSSPrevtime(newScheduleResult,newScheduleResultDetails, prevtime, currentOp, chromosome, processTime, machine); int prevtime1 = CalSSPrevtime(newScheduleResult,newScheduleResultDetails, prevtime, currentOp, chromosome, processTime, machine);
prevtime = Math.max(prevtime, prevtime1); prevtime = Math.max(prevtime, prevtime1);
newScheduleResult.clear(); newScheduleResult.clear();
...@@ -1414,13 +1414,13 @@ return actualEndTime; ...@@ -1414,13 +1414,13 @@ return actualEndTime;
if (opboms != null && !opboms.isEmpty()) { if (opboms != null && !opboms.isEmpty()) {
// 计算RawTime // 计算RawTime
Optional<LocalDateTime> rawDateOpt = opboms.stream() Optional<LocalDateTime> rawDateOpt = opboms.stream()
.filter(t -> t.getMaterialTypeName().equals("MP")) .filter(t -> t.getMaterialTypeName().equals("MP"))
.map(OrderMaterialRequirement::getUseTime) .map(OrderMaterialRequirement::getUseTime)
.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();
} }
...@@ -1474,9 +1474,9 @@ return actualEndTime; ...@@ -1474,9 +1474,9 @@ return actualEndTime;
{ {
return 0; return 0;
} }
LocalDateTime earliestStartTime1=baseTime.plusSeconds(earliestStartTime); LocalDateTime earliestStartTime1=baseTime.plusSeconds(earliestStartTime);
materialRequirementService.EditOperationBOM(currentOp,chromosome,earliestStartTime1,this,machineTasksCache, entryIndexById, scheduleIndexById); materialRequirementService.EditOperationBOM(currentOp,chromosome,earliestStartTime1,this,machineTasksCache, entryIndexById, scheduleIndexById, baseTime);
return getOperationBOMTime(currentOp, chromosome); return getOperationBOMTime(currentOp, chromosome);
} }
...@@ -1574,12 +1574,12 @@ return getOperationBOMTime(currentOp, chromosome); ...@@ -1574,12 +1574,12 @@ return getOperationBOMTime(currentOp, chromosome);
List<OrderMaterialRequirement> MaterialRequirements = currentOp.getMaterialRequirements().stream() List<OrderMaterialRequirement> MaterialRequirements = currentOp.getMaterialRequirements().stream()
.filter(t->!"MP".equals(t.getMaterialTypeName()) .filter(t->!"MP".equals(t.getMaterialTypeName())
&& t.getProductOrderID() != null && !t.getProductOrderID().isEmpty() && t.getProductOrderID() != null && !t.getProductOrderID().isEmpty()
) )
.collect(Collectors.toList()); .collect(Collectors.toList());
if(MaterialRequirements==null||MaterialRequirements.size()==0) if(MaterialRequirements==null||MaterialRequirements.size()==0)
{ {
continue; continue;
} }
for (OrderMaterialRequirement orderMaterial:MaterialRequirements) { for (OrderMaterialRequirement orderMaterial:MaterialRequirements) {
List<Integer> orderids= orderMaterial.getProductOrderID(); List<Integer> orderids= orderMaterial.getProductOrderID();
if(orderids!=null&&orderids.size()>0) { if(orderids!=null&&orderids.size()>0) {
...@@ -1619,7 +1619,7 @@ if(MaterialRequirements==null||MaterialRequirements.size()==0) ...@@ -1619,7 +1619,7 @@ if(MaterialRequirements==null||MaterialRequirements.size()==0)
} }
List<OrderMaterialRequirement> orderMaterialRequirements= entry.getMaterialRequirements().stream().filter(t-> !"MP".equals(t.getMaterialTypeName()) List<OrderMaterialRequirement> orderMaterialRequirements= entry.getMaterialRequirements().stream().filter(t-> !"MP".equals(t.getMaterialTypeName())
&& t.getProductOrderID() != null && !t.getProductOrderID().isEmpty() && t.getProductOrderID() != null && !t.getProductOrderID().isEmpty()
).collect(Collectors.toList()); ).collect(Collectors.toList());
for (OrderMaterialRequirement mr:orderMaterialRequirements) { for (OrderMaterialRequirement mr:orderMaterialRequirements) {
List<Integer> orderids= mr.getProductOrderID(); List<Integer> orderids= mr.getProductOrderID();
if(orderids!=null&&orderids.size()>0) { if(orderids!=null&&orderids.size()>0) {
...@@ -1683,7 +1683,7 @@ if(MaterialRequirements==null||MaterialRequirements.size()==0) ...@@ -1683,7 +1683,7 @@ if(MaterialRequirements==null||MaterialRequirements.size()==0)
* @return 可开工时间 * @return 可开工时间
*/ */
private int calculateNextOperationStartTime(List<GAScheduleResult> results,List<ScheduleResultDetail> details, int startindex, double time2) { private int calculateNextOperationStartTime(List<GAScheduleResult> results,List<ScheduleResultDetail> details, int startindex, double time2) {
double qty= results.stream().mapToDouble(GAScheduleResult::getQuantity) // 替换为实际字段名 double qty= results.stream().mapToDouble(GAScheduleResult::getQuantity) // 替换为实际字段名
.sum(); .sum();
double time1 = 0.0; double time1 = 0.0;
...@@ -1705,7 +1705,7 @@ if(MaterialRequirements==null||MaterialRequirements.size()==0) ...@@ -1705,7 +1705,7 @@ if(MaterialRequirements==null||MaterialRequirements.size()==0)
} }
if(results.size()>1) {//多前置工序 if(results.size()>1) {//多前置工序
calculateWithMoreMachine(details, leadCount); calculateWithMoreMachine(details, leadCount);
} }
// 单设备时使用原逻辑 // 单设备时使用原逻辑
return (int)calculateWithSingleMachine(details, leadCount, time1); return (int)calculateWithSingleMachine(details, leadCount, time1);
} }
...@@ -1762,10 +1762,10 @@ if(MaterialRequirements==null||MaterialRequirements.size()==0) ...@@ -1762,10 +1762,10 @@ if(MaterialRequirements==null||MaterialRequirements.size()==0)
// //
// int minEndTimeForContinuity = prevEndTime - (int) ((qty - leadCount) * prevTimePerUnit); // int minEndTimeForContinuity = prevEndTime - (int) ((qty - leadCount) * prevTimePerUnit);
// int adjustedStartTime = Math.max(productionTimeForLeadCount, minEndTimeForContinuity); // int adjustedStartTime = Math.max(productionTimeForLeadCount, minEndTimeForContinuity);
// int adjustedStartTime = Math.max(productionTimeForLeadCount, prevtime); // int adjustedStartTime = Math.max(productionTimeForLeadCount, prevtime);
// int totalProcessingTime = (int) (currentTimePerUnit * qty); // int totalProcessingTime = (int) (currentTimePerUnit * qty);
// int continuityAdjustedTime = ensureContinuousProduction(machine, adjustedStartTime, // int continuityAdjustedTime = ensureContinuousProduction(machine, adjustedStartTime,
// totalProcessingTime, currentOp); // totalProcessingTime, currentOp);
...@@ -1849,7 +1849,7 @@ if(MaterialRequirements==null||MaterialRequirements.size()==0) ...@@ -1849,7 +1849,7 @@ if(MaterialRequirements==null||MaterialRequirements.size()==0)
} }
} }
alldetails.stream().sorted(Comparator.comparingInt(ScheduleResultDetail::getStartTime)); alldetails.stream().sorted(Comparator.comparingInt(ScheduleResultDetail::getStartTime));
int EndTime=0; int EndTime=0;
double accumulatedQty = 0.0; double accumulatedQty = 0.0;
for (ScheduleResultDetail detail : alldetails) { for (ScheduleResultDetail detail : alldetails) {
...@@ -1878,7 +1878,7 @@ if(MaterialRequirements==null||MaterialRequirements.size()==0) ...@@ -1878,7 +1878,7 @@ if(MaterialRequirements==null||MaterialRequirements.size()==0)
return EndTime; return EndTime;
} }
/** /**
* 多设备并行时计算满足提前量的最早时间 * 多设备并行时计算满足提前量的最早时间
*/ */
private int calculateWithParallelMachines(List<ScheduleResultDetail> details, int leadCount, int time1) { private int calculateWithParallelMachines(List<ScheduleResultDetail> details, int leadCount, int time1) {
...@@ -2097,12 +2097,12 @@ if(MaterialRequirements==null||MaterialRequirements.size()==0) ...@@ -2097,12 +2097,12 @@ if(MaterialRequirements==null||MaterialRequirements.size()==0)
} }
//01 16:00 +20 -01 16:00 02 12:00 08:00 -18:00 01 16:18 02 08:00-12:00 //01 16:00 +20 -01 16:00 02 12:00 08:00 -18:00 01 16:18 02 08:00-12:00
//01 16:00 +10 -01 16:00 换型10:00 08:00 //01 16:00 +10 -01 16:00 换型10:00 08:00
//01 18:00 +10 -02 08:00<0 换型 休息时间满足 //01 18:00 +10 -02 08:00<0 换型 休息时间满足
//01 18:00 +20 -02 08:00>0 //01 18:00 +20 -02 08:00>0
//01 18:00 +10 -02 00:00>0 //01 18:00 +10 -02 00:00>0
return reslte; return reslte;
}else { }else {
//开始时间加上设置时间重新算 //开始时间加上设置时间重新算
//如果是前提供任务是相同的则跳出 //如果是前提供任务是相同的则跳出
...@@ -2141,7 +2141,7 @@ if(MaterialRequirements==null||MaterialRequirements.size()==0) ...@@ -2141,7 +2141,7 @@ if(MaterialRequirements==null||MaterialRequirements.size()==0)
{ {
return reslte; return reslte;
} }
// LocalDateTime startTime = baseTime.plus(earliestStartTime, ChronoUnit.SECONDS); // LocalDateTime startTime = baseTime.plus(earliestStartTime, ChronoUnit.SECONDS);
GAScheduleResult lastGeneOnMachine=machineTasks.get(machineTasks.size()-1); GAScheduleResult lastGeneOnMachine=machineTasks.get(machineTasks.size()-1);
...@@ -2155,7 +2155,7 @@ if(MaterialRequirements==null||MaterialRequirements.size()==0) ...@@ -2155,7 +2155,7 @@ if(MaterialRequirements==null||MaterialRequirements.size()==0)
if(AvailableTimeSegment!=null) { if(AvailableTimeSegment!=null) {
reslte.put(6,AvailableTimeSegment); reslte.put(6,AvailableTimeSegment);
int start= (int) ChronoUnit.SECONDS.between(baseTime, AvailableTimeSegment.get(0).getStart()); int start= (int) ChronoUnit.SECONDS.between(baseTime, AvailableTimeSegment.get(0).getStart());
earliestStartTime= earliestStartTime>start ?earliestStartTime:start; earliestStartTime= earliestStartTime>start ?earliestStartTime:start;
int earliestStartTime1=earliestStartTime; int earliestStartTime1=earliestStartTime;
...@@ -2196,14 +2196,14 @@ if(MaterialRequirements==null||MaterialRequirements.size()==0) ...@@ -2196,14 +2196,14 @@ if(MaterialRequirements==null||MaterialRequirements.size()==0)
} }
Entry prev= _allOperations.stream(). Entry prev= _allOperations.stream().
filter(t->t.getExecId().equals(ExecId)) filter(t->t.getExecId().equals(ExecId))
.findFirst().orElse(null); .findFirst().orElse(null);
int setupTime=0; int setupTime=0;
if(prev!=null) if(prev!=null)
{ {
//离散参数 //离散参数
// prev.getDiscreteParameter() // prev.getDiscreteParameter()
// setupTime = (prev.getProductId() != operation.getProductId()) // setupTime = (prev.getProductId() != operation.getProductId())
// ? (int) discreteParameterMatrixService.getDiscreteParameterMatrixValue(prev, operation) // ? (int) discreteParameterMatrixService.getDiscreteParameterMatrixValue(prev, operation)
...@@ -2225,7 +2225,7 @@ if(MaterialRequirements==null||MaterialRequirements.size()==0) ...@@ -2225,7 +2225,7 @@ if(MaterialRequirements==null||MaterialRequirements.size()==0)
} }
// setupTime=20*3600; // setupTime=20*3600;
operation.setChangeLineTime(setupTime); operation.setChangeLineTime(setupTime);
if(setupTime==0) if(setupTime==0)
{ {
...@@ -2244,20 +2244,20 @@ if(MaterialRequirements==null||MaterialRequirements.size()==0) ...@@ -2244,20 +2244,20 @@ if(MaterialRequirements==null||MaterialRequirements.size()==0)
{ {
cha=cha+1;//加1是工序开始加工时间 cha=cha+1;//加1是工序开始加工时间
reslte.put(2,lastGeneOnMachine.getEndTime());//换型开始时间 reslte.put(2,lastGeneOnMachine.getEndTime());//换型开始时间
// reslte = calculateSetupTime(machineTasks, operation, machine,earliestStartTime+cha,processingTimeTotal, _globalParam.is_smoothChangeOverInWeek(), ExecId,reslte); // reslte = calculateSetupTime(machineTasks, operation, machine,earliestStartTime+cha,processingTimeTotal, _globalParam.is_smoothChangeOverInWeek(), ExecId,reslte);
} }
else { else {
reslte.put(2,earliestStartTime-setupTime);//换型开始时间 reslte.put(2,earliestStartTime-setupTime);//换型开始时间
//如果空余时间足够 //如果空余时间足够
//可能会往前或后暂用设备时间 //可能会往前或后暂用设备时间
return reslte; return reslte;
} }
}else { }else {
//开始时间加上设置时间重新算 //开始时间加上设置时间重新算
//如果是前提供任务是相同的则跳出 //如果是前提供任务是相同的则跳出
// reslte = calculateSetupTime(machineTasks, operation, machine,earliestStartTime,processingTimeTotal+setupTime, _globalParam.is_smoothChangeOverInWeek(),ExecId,reslte); // reslte = calculateSetupTime(machineTasks, operation, machine,earliestStartTime,processingTimeTotal+setupTime, _globalParam.is_smoothChangeOverInWeek(),ExecId,reslte);
} }
...@@ -2332,7 +2332,7 @@ if(MaterialRequirements==null||MaterialRequirements.size()==0) ...@@ -2332,7 +2332,7 @@ if(MaterialRequirements==null||MaterialRequirements.size()==0)
.filter(t -> orderIds.contains(t.getOrderId())) .filter(t -> orderIds.contains(t.getOrderId()))
.max(Comparator.comparing(Order::getDueDate)) .max(Comparator.comparing(Order::getDueDate))
.orElse(null); .orElse(null);
if (order.isNewCreate()) { if (order.isNewSfCreate()) {
continue; continue;
} }
LocalDateTime dueDateTime = order.getDueDate(); LocalDateTime dueDateTime = order.getDueDate();
...@@ -2438,13 +2438,13 @@ if(MaterialRequirements==null||MaterialRequirements.size()==0) ...@@ -2438,13 +2438,13 @@ if(MaterialRequirements==null||MaterialRequirements.size()==0)
return chromosome.getGeneStr(); return chromosome.getGeneStr();
// 拼接机器选择:用 "," 分隔(例:1,3,2,4) // 拼接机器选择:用 "," 分隔(例:1,3,2,4)
// String machineStr = chromosome.getMachineStr(); // String machineStr = chromosome.getMachineStr();
// 拼接工序排序:用 "|" 分隔(例:2|1|3|4) // 拼接工序排序:用 "|" 分隔(例:2|1|3|4)
// String operationStr = chromosome.getOperationStr(); // String operationStr = chromosome.getOperationStr();
// 组合最终键(用 "_" 分隔两部分,避免冲突) // 组合最终键(用 "_" 分隔两部分,避免冲突)
// return machineStr + "_" + operationStr; // return machineStr + "_" + operationStr;
} }
} }
...@@ -25,6 +25,10 @@ public class GeneticOperations { ...@@ -25,6 +25,10 @@ public class GeneticOperations {
private static ScheduleParams param; private static ScheduleParams param;
public GeneticOperations() {
}
public GeneticOperations(GlobalParam globalParam,List<Entry> _allOperations,ScheduleParams _param) { public GeneticOperations(GlobalParam globalParam,List<Entry> _allOperations,ScheduleParams _param) {
_GlobalParam=globalParam; _GlobalParam=globalParam;
allOperations = _allOperations; allOperations = _allOperations;
...@@ -424,10 +428,12 @@ public class GeneticOperations { ...@@ -424,10 +428,12 @@ public class GeneticOperations {
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();
if(chromosome.getOrders()==null||chromosome.getOrders().size()==0)
return;
List<Order> orders = chromosome.getOrders(); List<Order> orders = chromosome.getOrders();
List<Integer> OperationSequencing= chromosome.getOperationSequencing(); List<Integer> OperationSequencing= chromosome.getOperationSequencing();
List<Integer> newoorderids= orders.stream() List<Integer> newoorderids= orders.stream()
.filter(t->t.isNewCreate()) .filter(t->t.isNewSfCreate())
.map(Order::getId) .map(Order::getId)
.sorted(Comparator.reverseOrder()) .sorted(Comparator.reverseOrder())
.collect(Collectors.toList()); .collect(Collectors.toList());
......
...@@ -102,20 +102,20 @@ public class MaterialRequirementService { ...@@ -102,20 +102,20 @@ public class MaterialRequirementService {
.collect(Collectors.toList()); .collect(Collectors.toList());
List<RoutingHeader> routingHeaders=null; List<RoutingHeader> routingHeaders=null;
LambdaQueryWrapper<RoutingHeader> wrapper = new LambdaQueryWrapper<>(); LambdaQueryWrapper<RoutingHeader> wrapper = new LambdaQueryWrapper<>();
wrapper.in(RoutingHeader::getId, routingIds); wrapper.in(RoutingHeader::getId, routingIds);
// .eq(RoutingHeader::getIsDeleted, 0) // .eq(RoutingHeader::getIsDeleted, 0)
// .eq(RoutingHeader::getApprovalStatus, 1); // .eq(RoutingHeader::getApprovalStatus, 1);
routingHeaders = routingHeaderMapper.selectList(wrapper); routingHeaders = routingHeaderMapper.selectList(wrapper);
List<Routingsupporting> routingsupportings=null; List<Routingsupporting> routingsupportings=null;
// 查询并缓存Routingsupporting // 查询并缓存Routingsupporting
LambdaQueryWrapper<Routingsupporting> routingsupportingwrapper = new LambdaQueryWrapper<>(); LambdaQueryWrapper<Routingsupporting> routingsupportingwrapper = new LambdaQueryWrapper<>();
routingsupportingwrapper.in(Routingsupporting::getRoutingHeaderId, routingIds) routingsupportingwrapper.in(Routingsupporting::getRoutingHeaderId, routingIds)
.eq(Routingsupporting::getIsdeleted, 0); .eq(Routingsupporting::getIsdeleted, 0);
routingsupportings = routingsupportingMapper.selectList(routingsupportingwrapper); routingsupportings = routingsupportingMapper.selectList(routingsupportingwrapper);
// 查询并缓存RoutingSupportingReplace // 查询并缓存RoutingSupportingReplace
...@@ -126,10 +126,10 @@ public class MaterialRequirementService { ...@@ -126,10 +126,10 @@ public class MaterialRequirementService {
.distinct() .distinct()
.collect(Collectors.toList()); .collect(Collectors.toList());
LambdaQueryWrapper<RoutingSupportingReplace> routingsupportingreplacewrapper = new LambdaQueryWrapper<>(); LambdaQueryWrapper<RoutingSupportingReplace> routingsupportingreplacewrapper = new LambdaQueryWrapper<>();
routingsupportingreplacewrapper.in(RoutingSupportingReplace::getStrsupid, routingsupportingids) routingsupportingreplacewrapper.in(RoutingSupportingReplace::getStrsupid, routingsupportingids)
.eq(RoutingSupportingReplace::getIsdeleted, 0); .eq(RoutingSupportingReplace::getIsdeleted, 0);
replaces = routingSupportingReplaceMapper.selectList(routingsupportingreplacewrapper); replaces = routingSupportingReplaceMapper.selectList(routingsupportingreplacewrapper);
} }
List<Material> useMaterials=new ArrayList<>(); List<Material> useMaterials=new ArrayList<>();
...@@ -145,7 +145,7 @@ public class MaterialRequirementService { ...@@ -145,7 +145,7 @@ public class MaterialRequirementService {
.collect(Collectors.toList()); .collect(Collectors.toList());
String orderId= order.getOrderId(); String orderId= order.getOrderId();
if(MaterialRequirements!=null) if(MaterialRequirements!=null)
{ {
...@@ -174,12 +174,12 @@ public class MaterialRequirementService { ...@@ -174,12 +174,12 @@ public class MaterialRequirementService {
} }
if(component.getSpentQty()==null) if(component.getSpentQty()==null)
{ {
throw new RuntimeException("配套数据有问题,需求数量为空,请检查数据,"+component.getMaterialNumber()); throw new RuntimeException("配套数据有问题,需求数量为空,请检查数据,"+component.getMaterialNumber());
} }
double allneeded = component.getSpentQty().doubleValue()/ component.getMainQty().doubleValue() * operation.getQuantity(); double allneeded = component.getSpentQty().doubleValue()/ component.getMainQty().doubleValue() * operation.getQuantity();
OrderMaterialRequirement orderMaterialRequirement = CreateMaterialRequirement(material, orderId, "", operation, OrderMaterialRequirement orderMaterialRequirement = CreateMaterialRequirement(material, orderId, "", operation,
allneeded,component.getSpentQty().doubleValue(), component.getMainQty().doubleValue(),operation.getQuantity()); allneeded,component.getSpentQty().doubleValue(), component.getMainQty().doubleValue(),operation.getQuantity(),baseTime);
orderMaterialRequirement.setBomId(component.getStrId()); orderMaterialRequirement.setBomId(component.getStrId());
if (!material.getMaterialTypeName().equals("MP") && isIsCheckSf) { if (!material.getMaterialTypeName().equals("MP") && isIsCheckSf) {
materialIds.add(materialId);//半成品ID materialIds.add(materialId);//半成品ID
...@@ -276,76 +276,76 @@ public class MaterialRequirementService { ...@@ -276,76 +276,76 @@ public class MaterialRequirementService {
LambdaQueryWrapper<Routingsupporting> routingsupportingwrapper = new LambdaQueryWrapper<>(); LambdaQueryWrapper<Routingsupporting> routingsupportingwrapper = new LambdaQueryWrapper<>();
routingsupportingwrapper.in(Routingsupporting::getRoutingHeaderId, routingIds) routingsupportingwrapper.in(Routingsupporting::getRoutingHeaderId, routingIds)
.eq(Routingsupporting::getIsdeleted, 0); .eq(Routingsupporting::getIsdeleted, 0);
routingsupportings1 = routingsupportingMapper.selectList(routingsupportingwrapper); routingsupportings1 = routingsupportingMapper.selectList(routingsupportingwrapper);
if(routingsupportings1!=null&&routingsupportings1.size()>0) if(routingsupportings1!=null&&routingsupportings1.size()>0)
{ {
routingsupportings.addAll(routingsupportings1); routingsupportings.addAll(routingsupportings1);
List<String> routingsupportingids = routingsupportings1.stream() List<String> routingsupportingids = routingsupportings1.stream()
.map(Routingsupporting::getStrId) .map(Routingsupporting::getStrId)
.distinct() .distinct()
.collect(Collectors.toList()); .collect(Collectors.toList());
LambdaQueryWrapper<RoutingSupportingReplace> routingsupportingreplacewrapper = new LambdaQueryWrapper<>(); LambdaQueryWrapper<RoutingSupportingReplace> routingsupportingreplacewrapper = new LambdaQueryWrapper<>();
routingsupportingreplacewrapper.in(RoutingSupportingReplace::getStrsupid, routingsupportingids) routingsupportingreplacewrapper.in(RoutingSupportingReplace::getStrsupid, routingsupportingids)
.eq(RoutingSupportingReplace::getIsdeleted, 0); .eq(RoutingSupportingReplace::getIsdeleted, 0);
routingsupportingreplaces1 = routingSupportingReplaceMapper.selectList(routingsupportingreplacewrapper); routingsupportingreplaces1 = routingSupportingReplaceMapper.selectList(routingsupportingreplacewrapper);
routingsupportingreplaces.addAll(routingsupportingreplaces1); routingsupportingreplaces.addAll(routingsupportingreplaces1);
List<String> materialIds=new ArrayList<>(); List<String> materialIds=new ArrayList<>();
for (Routingsupporting routingsupporting:routingsupportings1) { for (Routingsupporting routingsupporting:routingsupportings1) {
String materialID1= routingsupporting.getMaterialId(); String materialID1= routingsupporting.getMaterialId();
Material material = _materials.stream()
.filter(m -> m.getId().equals(materialID1))
.findFirst()
.orElse(null);
if (material != null) {
if(!useMaterialids.contains(materialID1)) {
useMaterials.add(material);
useMaterialids.add(materialID1);
}
if(!material.getMaterialTypeName().equals("MP")) {
materialIds.add(materialID1);
}
}
}
for (RoutingSupportingReplace routingSupportingReplace:routingsupportingreplaces1) {
String materialID1= routingSupportingReplace.getMaterialid();
if(!useMaterialids.contains(materialID1)) {
Material material = _materials.stream() Material material = _materials.stream()
.filter(m -> m.getId().equals(materialID1)) .filter(m -> m.getId().equals(materialID1))
.findFirst() .findFirst()
.orElse(null); .orElse(null);
if (material != null) { if (material != null) {
useMaterials.add(material); if(!useMaterialids.contains(materialID1)) {
useMaterialids.add(materialID1); useMaterials.add(material);
useMaterialids.add(materialID1);
}
if(!material.getMaterialTypeName().equals("MP")) {
materialIds.add(materialID1);
}
} }
} }
} for (RoutingSupportingReplace routingSupportingReplace:routingsupportingreplaces1) {
String materialID1= routingSupportingReplace.getMaterialid();
Map<Integer,Object> r1=preloadSfRoutingBomCache(materialIds, headers, routingsupportings, routingsupportingreplaces);
List<Long> routingIds2=(List<Long>) r1.get(1);
List<Material> useMaterials2=( List<Material>) r1.get(2);
if(routingIds2!=null)
{
routingIds.addAll(routingIds2);
}
if(useMaterials2!=null&&useMaterials2.size()>0) {
for (Material m:useMaterials2) {
String materialID1= m.getId();
if(!useMaterialids.contains(materialID1)) { if(!useMaterialids.contains(materialID1)) {
useMaterials.add(m); Material material = _materials.stream()
useMaterialids.add(materialID1); .filter(m -> m.getId().equals(materialID1))
.findFirst()
.orElse(null);
if (material != null) {
useMaterials.add(material);
useMaterialids.add(materialID1);
}
}
}
Map<Integer,Object> r1=preloadSfRoutingBomCache(materialIds, headers, routingsupportings, routingsupportingreplaces);
List<Long> routingIds2=(List<Long>) r1.get(1);
List<Material> useMaterials2=( List<Material>) r1.get(2);
if(routingIds2!=null)
{
routingIds.addAll(routingIds2);
}
if(useMaterials2!=null&&useMaterials2.size()>0) {
for (Material m:useMaterials2) {
String materialID1= m.getId();
if(!useMaterialids.contains(materialID1)) {
useMaterials.add(m);
useMaterialids.add(materialID1);
}
} }
} }
} }
}
} }
if(routingIds1!=null) if(routingIds1!=null)
{ {
...@@ -392,7 +392,7 @@ public class MaterialRequirementService { ...@@ -392,7 +392,7 @@ public class MaterialRequirementService {
List<PlanResource> list =GetPlanResources(); List<PlanResource> list =GetPlanResources();
Map<Integer, PlanResource> planResourceByReferenceIdMap = list.stream() Map<Integer, PlanResource> planResourceByReferenceIdMap = list.stream()
.filter(pr -> pr.getReferenceId() != null) .filter(pr -> pr.getReferenceId() != null)
.collect(Collectors.toMap(PlanResource::getReferenceId, Function.identity())); .collect(Collectors.toMap(PlanResource::getReferenceId, Function.identity()));
...@@ -416,7 +416,7 @@ public class MaterialRequirementService { ...@@ -416,7 +416,7 @@ public class MaterialRequirementService {
List<Equipinfo> matchedEquipments = equipinfoByEquipTypeMap.get(machineId.intValue()); List<Equipinfo> matchedEquipments = equipinfoByEquipTypeMap.get(machineId.intValue());
if (matchedEquipments == null || matchedEquipments.isEmpty()) { if (matchedEquipments == null || matchedEquipments.isEmpty()) {
throw new RuntimeException(String.format("未找到machineId=%d对应的设备信息", machineId)); throw new RuntimeException(String.format("未找到machineId=%d对应的设备信息", machineId));
} }
...@@ -477,7 +477,7 @@ public class MaterialRequirementService { ...@@ -477,7 +477,7 @@ public class MaterialRequirementService {
.distinct() .distinct()
.collect(Collectors.toList()); .collect(Collectors.toList());
routingDiscreteParams = _routingDiscreteParamService.lambdaQuery() routingDiscreteParams = _routingDiscreteParamService.lambdaQuery()
.in(RoutingDiscreteParam::getRoutingDetailId, routingDetailIds) .in(RoutingDiscreteParam::getRoutingDetailId, routingDetailIds)
.eq(RoutingDiscreteParam::getIsDeleted, 0) .eq(RoutingDiscreteParam::getIsDeleted, 0)
.list(); .list();
...@@ -503,8 +503,6 @@ public class MaterialRequirementService { ...@@ -503,8 +503,6 @@ public class MaterialRequirementService {
* @return 所有物料需求列表 * @return 所有物料需求列表
*/ */
public List<OrderMaterialRequirement> buildMultiLevelRequirementNetwork(Chromosome chromosome,String sceneId, LocalDateTime _baseTime,GlobalParam _globalParam) { public List<OrderMaterialRequirement> buildMultiLevelRequirementNetwork(Chromosome chromosome,String sceneId, LocalDateTime _baseTime,GlobalParam _globalParam) {
baseTime=_baseTime;
globalParam=_globalParam;
List<OrderMaterialRequirement> allRequirements = new ArrayList<>(); List<OrderMaterialRequirement> allRequirements = new ArrayList<>();
List<Order> childorders = new ArrayList<>(); List<Order> childorders = new ArrayList<>();
List<Entry> _newEntrys = new ArrayList<>(); List<Entry> _newEntrys = new ArrayList<>();
...@@ -519,13 +517,13 @@ public class MaterialRequirementService { ...@@ -519,13 +517,13 @@ public class MaterialRequirementService {
.entrySet().stream() .entrySet().stream()
.collect(Collectors.toMap(Map.Entry::getKey, e -> 0)); .collect(Collectors.toMap(Map.Entry::getKey, e -> 0));
List<Integer> operationSequencing=chromosome.getOperationSequencing(); List<Integer> operationSequencing= new ArrayList<>(chromosome.getOperationSequencing());
orders.forEach(t->clearFinishOrder(t)); orders.forEach(t->clearFinishOrder(t));
for (Integer groupId : operationSequencing) for (Integer groupId : operationSequencing)
{ {
Order demand=orders.stream().filter(t->t.getId()==groupId).findFirst().orElse(null); Order demand=orders.stream().filter(t->t.getId()==groupId).findFirst().orElse(null);
if (demand.getFinishOrderId() != null && !demand.getFinishOrderId().isEmpty()) { if (demand.getFinishOrderId() != null && !demand.getFinishOrderId().isEmpty()) {
continue; continue;
...@@ -546,7 +544,7 @@ public class MaterialRequirementService { ...@@ -546,7 +544,7 @@ public class MaterialRequirementService {
// 调用BuildOperationBOM方法(返回结果对象替代out参数) // 调用BuildOperationBOM方法(返回结果对象替代out参数)
BOMBuildResult operationResult = buildOperationSFBOM(operation.getOrderId(), "", BOMBuildResult operationResult = buildOperationSFBOM(operation.getOrderId(), "",
operation.getQuantity(), operation, 1,demand,sceneId,chromosome); operation.getQuantity(), operation, 1,demand,sceneId,chromosome,_baseTime,_globalParam);
// // 合并物料需求和子订单 // // 合并物料需求和子订单
if(operationResult!=null) { if(operationResult!=null) {
allRequirements.addAll(operationResult.getMaterialRequirements()); allRequirements.addAll(operationResult.getMaterialRequirements());
...@@ -567,13 +565,13 @@ public class MaterialRequirementService { ...@@ -567,13 +565,13 @@ public class MaterialRequirementService {
return allRequirements; return allRequirements;
} }
private void clearFinishOrder (Order order) private void clearFinishOrder (Order order)
{ {
if (order.getFinishOrderId() == null) { if (order.getFinishOrderId() == null) {
order.setFinishOrderId(new ArrayList<>()); order.setFinishOrderId(new ArrayList<>());
order.setTargetFinishedOperationId(new ArrayList<>()); order.setTargetFinishedOperationId(new ArrayList<>());
}
} }
}
/** /**
* 构建订单BOM * 构建订单BOM
...@@ -586,10 +584,10 @@ private void clearFinishOrder (Order order) ...@@ -586,10 +584,10 @@ private void clearFinishOrder (Order order)
* @return 包含物料需求列表和子订单列表的结果对象 * @return 包含物料需求列表和子订单列表的结果对象
*/ */
public BOMBuildResult buildOrderBOM(String sceneId,int parent, String materialID, String mainorderId, public BOMBuildResult buildOrderBOM(String sceneId,int parent, String materialID, String mainorderId,
String childorderId, double parentQuantity, int level,Order forder,int finishOpertionID,Chromosome chromosome) { String childorderId, double parentQuantity, int level,Order forder,int finishOpertionID,Chromosome chromosome, LocalDateTime baseTime, GlobalParam globalParam) {
forder.setCreateBom(true); forder.setCreateBom(true);
List<RoutingHeader> headers=GetRoutingHeader(sceneId); List<RoutingHeader> headers=GetRoutingHeader(sceneId);
RoutingHeader routingHeaders= headers.stream() RoutingHeader routingHeaders= headers.stream()
.filter(t->t.getId()==parent|| t.getMaterialId().equals(materialID)) .filter(t->t.getId()==parent|| t.getMaterialId().equals(materialID))
.findFirst() .findFirst()
...@@ -604,7 +602,7 @@ private void clearFinishOrder (Order order) ...@@ -604,7 +602,7 @@ private void clearFinishOrder (Order order)
List<Order> childorders2 = new ArrayList<>(); List<Order> childorders2 = new ArrayList<>();
List<Entry> _newEntrys = new ArrayList<>(); List<Entry> _newEntrys = new ArrayList<>();
List<Machine> _newMachines = new ArrayList<>(); List<Machine> _newMachines = new ArrayList<>();
// 遍历产品的工序,递归构建工序BOM // 遍历产品的工序,递归构建工序BOM
List<Entry> _allOperations= chromosome.getAllOperations(); List<Entry> _allOperations= chromosome.getAllOperations();
...@@ -615,7 +613,7 @@ private void clearFinishOrder (Order order) ...@@ -615,7 +613,7 @@ private void clearFinishOrder (Order order)
if (Operations != null) { if (Operations != null) {
for (Entry operation : Operations) { for (Entry operation : Operations) {
if(finishOpertionID!=0) if(finishOpertionID!=0)
{ {
...@@ -627,7 +625,7 @@ private void clearFinishOrder (Order order) ...@@ -627,7 +625,7 @@ private void clearFinishOrder (Order order)
} }
// 调用BuildOperationBOM方法(返回结果对象替代out参数) // 调用BuildOperationBOM方法(返回结果对象替代out参数)
BOMBuildResult operationResult = buildOperationBOM(mainorderId, childorderId, BOMBuildResult operationResult = buildOperationBOM(mainorderId, childorderId,
parentQuantity, operation, level,forder,sceneId,chromosome); parentQuantity, operation, level,forder,sceneId,chromosome, baseTime, globalParam);
// // 合并物料需求和子订单 // // 合并物料需求和子订单
if(operationResult!=null) { if(operationResult!=null) {
materialRequirements.addAll(operationResult.getMaterialRequirements()); materialRequirements.addAll(operationResult.getMaterialRequirements());
...@@ -650,7 +648,7 @@ private void clearFinishOrder (Order order) ...@@ -650,7 +648,7 @@ private void clearFinishOrder (Order order)
* @return 包含物料需求列表和子订单列表的结果对象(替代C#的out参数) * @return 包含物料需求列表和子订单列表的结果对象(替代C#的out参数)
*/ */
public BOMBuildResult buildOperationBOM(String orderId, String childorderId, double parentQuantity, public BOMBuildResult buildOperationBOM(String orderId, String childorderId, double parentQuantity,
Entry operation, int level,Order forder,String sceneId,Chromosome chromosome) { Entry operation, int level,Order forder,String sceneId,Chromosome chromosome, LocalDateTime baseTime, GlobalParam globalParam) {
List<OrderMaterialRequirement> materialRequirements = new ArrayList<>(); List<OrderMaterialRequirement> materialRequirements = new ArrayList<>();
List<Order> _childorders = new ArrayList<>(); List<Order> _childorders = new ArrayList<>();
List<Entry> _newEntrys = new ArrayList<>(); List<Entry> _newEntrys = new ArrayList<>();
...@@ -678,8 +676,8 @@ private void clearFinishOrder (Order order) ...@@ -678,8 +676,8 @@ private void clearFinishOrder (Order order)
return null; return null;
} }
OrderMaterialRequirement orderMaterial= CreateMaterialRequirement(material,orderId,childorderId,operation,allneeded,component.getSpentQty().doubleValue(), component.getMainQty().doubleValue() , parentQuantity); OrderMaterialRequirement orderMaterial= CreateMaterialRequirement(material,orderId,childorderId,operation,allneeded,component.getSpentQty().doubleValue(), component.getMainQty().doubleValue() , parentQuantity, baseTime);
orderMaterial.setLevel(level); orderMaterial.setLevel(level);
orderMaterial.setBomId(component.getStrId()); orderMaterial.setBomId(component.getStrId());
materialRequirements.add(orderMaterial); materialRequirements.add(orderMaterial);
...@@ -713,8 +711,8 @@ private void clearFinishOrder (Order order) ...@@ -713,8 +711,8 @@ private void clearFinishOrder (Order order)
BOMBuildResult childResult = buildOrderBOM(sceneId,0, orderMaterial.getMaterialId(), BOMBuildResult childResult = buildOrderBOM(sceneId,0, orderMaterial.getMaterialId(),
orderId, order.getOrderId(), orderId, order.getOrderId(),
order.getQuantity(), l,order,operation.getId(),chromosome); order.getQuantity(), l,order,operation.getId(),chromosome, baseTime, globalParam);
// materialRequirements.addAll(childResult.getMaterialRequirements()); // materialRequirements.addAll(childResult.getMaterialRequirements());
_childorders.addAll(childResult.getChildOrders()); _childorders.addAll(childResult.getChildOrders());
_newEntrys.addAll(childResult.getNewEntrys()); _newEntrys.addAll(childResult.getNewEntrys());
operation.getDependentOnOrderIds().add(order.getId()); operation.getDependentOnOrderIds().add(order.getId());
...@@ -743,7 +741,7 @@ private void clearFinishOrder (Order order) ...@@ -743,7 +741,7 @@ private void clearFinishOrder (Order order)
childorder.setQuantity((int) orderMaterial.getQjQty()); childorder.setQuantity((int) orderMaterial.getQjQty());
childorder.setFinishOrderId(new ArrayList<>()); childorder.setFinishOrderId(new ArrayList<>());
childorder.getFinishOrderId().add(forder.getId()); childorder.getFinishOrderId().add(forder.getId());
childorder.setNewCreate(true); childorder.setNewSfCreate(true);
childorder.setTargetFinishedOperationId(new ArrayList<>()); childorder.setTargetFinishedOperationId(new ArrayList<>());
childorder.getTargetFinishedOperationId().add(operation.getId()); childorder.getTargetFinishedOperationId().add(operation.getId());
childorder.setSerie(forder.getSerie()); childorder.setSerie(forder.getSerie());
...@@ -769,8 +767,8 @@ private void clearFinishOrder (Order order) ...@@ -769,8 +767,8 @@ private void clearFinishOrder (Order order)
int l = level + 1; int l = level + 1;
BOMBuildResult childResult = buildOrderBOM(sceneId,0, orderMaterial.getMaterialId(), BOMBuildResult childResult = buildOrderBOM(sceneId,0, orderMaterial.getMaterialId(),
orderId, childorder.getOrderId(), orderId, childorder.getOrderId(),
childorder.getQuantity(), l,childorder,0,chromosome); childorder.getQuantity(), l,childorder,0,chromosome, baseTime, globalParam);
// materialRequirements.addAll(childResult.getMaterialRequirements()); // materialRequirements.addAll(childResult.getMaterialRequirements());
_childorders.addAll(childResult.getChildOrders()); _childorders.addAll(childResult.getChildOrders());
_newEntrys.addAll(childResult.getNewEntrys()); _newEntrys.addAll(childResult.getNewEntrys());
} }
...@@ -792,10 +790,10 @@ private void clearFinishOrder (Order order) ...@@ -792,10 +790,10 @@ private void clearFinishOrder (Order order)
RoutingHeader headers1= headers.stream() RoutingHeader headers1= headers.stream()
.filter(t->t.getMaterialId().equals(materialID)) .filter(t->t.getMaterialId().equals(materialID))
.findFirst().orElse(null); .findFirst().orElse(null);
if(headers1==null) if(headers1==null)
{ {
return null; return null;
} }
routingIds=headers1.getId().longValue(); routingIds=headers1.getId().longValue();
...@@ -811,8 +809,8 @@ if(headers1==null) ...@@ -811,8 +809,8 @@ if(headers1==null)
} }
List<RoutingDetailEquip> allroutingDetailEquips=GetRoutingDetailEquips(sceneId); List<RoutingDetailEquip> allroutingDetailEquips=GetRoutingDetailEquips(sceneId);
List<RoutingDetailEquip> routingDetailEquips= allroutingDetailEquips.stream() List<RoutingDetailEquip> routingDetailEquips= allroutingDetailEquips.stream()
.filter(t->t.getRoutingHeaderId().equals(headersid)) .filter(t->t.getRoutingHeaderId().equals(headersid))
.collect(Collectors.toList()); .collect(Collectors.toList());
...@@ -842,9 +840,9 @@ if(headers1==null) ...@@ -842,9 +840,9 @@ if(headers1==null)
List<RoutingDetailConnect> allroutingDetailconnections=GetRoutingDetailConnect(sceneId); List<RoutingDetailConnect> allroutingDetailconnections=GetRoutingDetailConnect(sceneId);
connections= allroutingDetailconnections.stream() connections= allroutingDetailconnections.stream()
.filter(t->t.getRoutingHeaderId().equals(headersid)) .filter(t->t.getRoutingHeaderId().equals(headersid))
.collect(Collectors.toList()); .collect(Collectors.toList());
List<ProdOrderProcess> ProdOrderProcesslist= connections.stream() List<ProdOrderProcess> ProdOrderProcesslist= connections.stream()
...@@ -921,7 +919,7 @@ if(headers1==null) ...@@ -921,7 +919,7 @@ if(headers1==null)
* @return 包含物料需求列表和子订单列表的结果对象(替代C#的out参数) * @return 包含物料需求列表和子订单列表的结果对象(替代C#的out参数)
*/ */
public BOMBuildResult buildOperationSFBOM(String orderId, String childorderId, double parentQuantity, public BOMBuildResult buildOperationSFBOM(String orderId, String childorderId, double parentQuantity,
Entry operation, int level,Order forder,String sceneId,Chromosome chromosome) { Entry operation, int level,Order forder,String sceneId,Chromosome chromosome, LocalDateTime baseTime, GlobalParam globalParam) {
List<OrderMaterialRequirement> materialRequirements = new ArrayList<>(); List<OrderMaterialRequirement> materialRequirements = new ArrayList<>();
List<Order> _childorders = new ArrayList<>(); List<Order> _childorders = new ArrayList<>();
List<Entry> _newEntrys = new ArrayList<>(); List<Entry> _newEntrys = new ArrayList<>();
...@@ -949,99 +947,99 @@ if(headers1==null) ...@@ -949,99 +947,99 @@ if(headers1==null)
// 查找物料(流式处理替代First) // 查找物料(流式处理替代First)
if (!orderMaterial.getMaterialTypeName().equals("MP") ) { if (!orderMaterial.getMaterialTypeName().equals("MP") ) {
// 处理半成品/成品的现有订单 // 处理半成品/成品的现有订单
// 为什么要先找现有订单,绑定上,因为要把它排在成品工单前面,才能有时间 // 为什么要先找现有订单,绑定上,因为要把它排在成品工单前面,才能有时间
List<Order> orders2 = orders.stream() List<Order> orders2 = orders.stream()
.filter(t -> t.getMaterialId().equals(orderMaterial.getMaterialId()) && t.getSYQuantity() > 0) .filter(t -> t.getMaterialId().equals(orderMaterial.getMaterialId()) && t.getSYQuantity() > 0)
.sorted(Comparator.comparing(Order::getDueDate)) .sorted(Comparator.comparing(Order::getDueDate))
.collect(Collectors.toList()); .collect(Collectors.toList());
if (!orders2.isEmpty()) { if (!orders2.isEmpty()) {
for (Order order : orders2) { for (Order order : orders2) {
if (order.getFinishOrderId() == null) { if (order.getFinishOrderId() == null) {
order.setFinishOrderId(new ArrayList<>()); order.setFinishOrderId(new ArrayList<>());
order.setTargetFinishedOperationId(new ArrayList<>()); order.setTargetFinishedOperationId(new ArrayList<>());
} }
order.getFinishOrderId().add(forder.getId()); order.getFinishOrderId().add(forder.getId());
order.getTargetFinishedOperationId().add(operation.getId()); order.getTargetFinishedOperationId().add(operation.getId());
orderMaterial.getProductOrderID().add(order.getId());
double useq = Math.min(needed, order.getSYQuantity());
needed -= useq;
order.setSYQuantity(order.getSYQuantity() - useq);
//防止已经生成过一次
if (!order.isCreateBom()) {
// 递归构建BOM
int l = level + 1;
BOMBuildResult childResult = buildOrderBOM(sceneId,0, orderMaterial.getMaterialId(),
orderId, order.getOrderId(),
order.getQuantity(), l,order,operation.getId(),chromosome);
materialRequirements.addAll(childResult.getMaterialRequirements());
_childorders.addAll(childResult.getChildOrders());
_newEntrys.addAll(childResult.getNewEntrys());
operation.getDependentOnOrderIds().add(order.getId());
}
if (needed <= 0) { orderMaterial.getProductOrderID().add(order.getId());
break;
} double useq = Math.min(needed, order.getSYQuantity());
needed -= useq;
order.setSYQuantity(order.getSYQuantity() - useq);
//防止已经生成过一次
if (!order.isCreateBom()) {
// 递归构建BOM
int l = level + 1;
BOMBuildResult childResult = buildOrderBOM(sceneId,0, orderMaterial.getMaterialId(),
orderId, order.getOrderId(),
order.getQuantity(), l,order,operation.getId(),chromosome, baseTime, globalParam);
materialRequirements.addAll(childResult.getMaterialRequirements());
_childorders.addAll(childResult.getChildOrders());
_newEntrys.addAll(childResult.getNewEntrys());
operation.getDependentOnOrderIds().add(order.getId());
} }
}
// 更新已配和缺件数量 if (needed <= 0) {
orderMaterial.setYpQty(allneeded - needed); break;
orderMaterial.setQjQty(needed);
if (needed > 0&&globalParam.isIsCheckSf()) {
// 创建新的子订单
Order childorder = new Order();
String OrderId = UUID.randomUUID().toString().replace("-", "");
childorder.setOrderId(OrderId);
childorder.setMaterialId(orderMaterial.getMaterialId());
childorder.setMaterialCode(orderMaterial.getMaterialCode());
childorder.setMaterialName(orderMaterial.getMaterialTypeName());
childorder.setOrderCode("M_"+orderMaterial.getMaterialCode());
childorder.setQuantity((int) orderMaterial.getQjQty());
childorder.setFinishOrderId(new ArrayList<>());
childorder.getFinishOrderId().add(forder.getId());
childorder.setNewCreate(true);
childorder.setTargetFinishedOperationId(new ArrayList<>());
childorder.getTargetFinishedOperationId().add(operation.getId());
childorder.setSerie(forder.getSerie());
childorder.setStartDate(forder.getStartDate());
childorder.setDueDate(forder.getDueDate());
childorder.setPriority(forder.getPriority());
childorder.setActualPriority(forder.getActualPriority());
Map<Integer, Object> list= CreateChild(sceneId,childorder,orderMaterial.getMaterialId(), operation.getId(),chromosome);
if(list==null)
{
continue;
} }
_childorders.add(childorder);
List<Entry> newentrys=(List<Entry>)list.get(1);
_newEntrys.addAll(newentrys);
orderMaterial.getProductOrderID().add(childorder.getId());
operation.getDependentOnOrderIds().add(childorder.getId());
// 递归构建BOM
int l = level + 1;
BOMBuildResult childResult = buildOrderBOM(sceneId,0, orderMaterial.getMaterialId(),
orderId, childorder.getOrderId(),
childorder.getQuantity(), l,childorder,0,chromosome);
materialRequirements.addAll(childResult.getMaterialRequirements());
_childorders.addAll(childResult.getChildOrders());
_newEntrys.addAll(childResult.getNewEntrys());
} }
} }
// 更新已配和缺件数量
orderMaterial.setYpQty(allneeded - needed);
orderMaterial.setQjQty(needed);
if (needed > 0&&globalParam.isIsCheckSf()) {
// 创建新的子订单
Order childorder = new Order();
String OrderId = UUID.randomUUID().toString().replace("-", "");
childorder.setOrderId(OrderId);
childorder.setMaterialId(orderMaterial.getMaterialId());
childorder.setMaterialCode(orderMaterial.getMaterialCode());
childorder.setMaterialName(orderMaterial.getMaterialTypeName());
childorder.setOrderCode("M_"+orderMaterial.getMaterialCode());
childorder.setQuantity((int) orderMaterial.getQjQty());
childorder.setFinishOrderId(new ArrayList<>());
childorder.getFinishOrderId().add(forder.getId());
childorder.setNewSfCreate(true);
childorder.setTargetFinishedOperationId(new ArrayList<>());
childorder.getTargetFinishedOperationId().add(operation.getId());
childorder.setSerie(forder.getSerie());
childorder.setStartDate(forder.getStartDate());
childorder.setDueDate(forder.getDueDate());
childorder.setPriority(forder.getPriority());
childorder.setActualPriority(forder.getActualPriority());
Map<Integer, Object> list= CreateChild(sceneId,childorder,orderMaterial.getMaterialId(), operation.getId(),chromosome);
if(list==null)
{
continue;
}
_childorders.add(childorder);
List<Entry> newentrys=(List<Entry>)list.get(1);
_newEntrys.addAll(newentrys);
orderMaterial.getProductOrderID().add(childorder.getId());
operation.getDependentOnOrderIds().add(childorder.getId());
// 递归构建BOM
int l = level + 1;
BOMBuildResult childResult = buildOrderBOM(sceneId,0, orderMaterial.getMaterialId(),
orderId, childorder.getOrderId(),
childorder.getQuantity(), l,childorder,0,chromosome, baseTime, globalParam);
materialRequirements.addAll(childResult.getMaterialRequirements());
_childorders.addAll(childResult.getChildOrders());
_newEntrys.addAll(childResult.getNewEntrys());
}
}
} }
} }
...@@ -1061,7 +1059,7 @@ if(headers1==null) ...@@ -1061,7 +1059,7 @@ if(headers1==null)
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()); // orderMaterial.setCheckLeadTime(material.getCkeckLeadTime());
double useStock=0; double useStock=0;
// 扣减现有库存 // 扣减现有库存
List<Stock> stocks= material.getMaterialStocks().stream() List<Stock> stocks= material.getMaterialStocks().stream()
...@@ -1089,7 +1087,7 @@ if(headers1==null) ...@@ -1089,7 +1087,7 @@ if(headers1==null)
} }
private OrderMaterialRequirement CreateMaterialRequirement(Material material,String orderId, String childorderId, Entry operation,double need,double spentQty,double mainQty,double qty) { private OrderMaterialRequirement CreateMaterialRequirement(Material material,String orderId, String childorderId, Entry operation,double need,double spentQty,double mainQty,double qty, LocalDateTime baseTime) {
OrderMaterialRequirement orderMaterial = new OrderMaterialRequirement(); OrderMaterialRequirement orderMaterial = new OrderMaterialRequirement();
orderMaterial.setOrderId(orderId); orderMaterial.setOrderId(orderId);
...@@ -1140,14 +1138,14 @@ if(headers1==null) ...@@ -1140,14 +1138,14 @@ if(headers1==null)
* @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) { 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) {
List<OrderMaterialRequirement> materialRequirements = new ArrayList<>(); List<OrderMaterialRequirement> materialRequirements = new ArrayList<>();
String sceneId=chromosome.getScenarioID(); String sceneId=chromosome.getScenarioID();
Random rnd = new Random(); Random rnd = new Random();
List<OrderMaterialRequirement> MaterialRequirements= operation.getMaterialRequirements(); List<OrderMaterialRequirement> MaterialRequirements= operation.getMaterialRequirements();
MaterialRequirements = MaterialRequirements.stream() MaterialRequirements = MaterialRequirements.stream()
.sorted((a, b) -> { .sorted((a, b) -> {
// 定义判断条件:是否满足 非MP + 生产订单ID非空非空串 // 定义判断条件:是否满足 非MP + 生产订单ID非空非空串
boolean aMatch = !"MP".equals(a.getMaterialTypeName()) boolean aMatch = !"MP".equals(a.getMaterialTypeName())
...@@ -1228,12 +1226,12 @@ if(headers1==null) ...@@ -1228,12 +1226,12 @@ if(headers1==null)
if (orderMaterial1 != null) { if (orderMaterial1 != null) {
useStock = orderMaterial1.getUseStock(); useStock = orderMaterial1.getUseStock();
needed -= useStock; needed -= 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) {
break; break;
} }
} }
} }
...@@ -1247,7 +1245,7 @@ if(headers1==null) ...@@ -1247,7 +1245,7 @@ if(headers1==null)
continue; continue;
} }
MaterialInTransit(material,"",orderMaterial,needed,earliestStartTime); MaterialInTransit(material,"",orderMaterial,needed,earliestStartTime, materials);
needed -= orderMaterial.getUseTransit(); needed -= orderMaterial.getUseTransit();
...@@ -1268,7 +1266,7 @@ if(headers1==null) ...@@ -1268,7 +1266,7 @@ if(headers1==null)
break; break;
} }
MaterialInTransit(material1,rsr.getMaterialid(),orderMaterial1,needed,earliestStartTime); MaterialInTransit(material1,rsr.getMaterialid(),orderMaterial1,needed,earliestStartTime, materials);
needed -= orderMaterial1.getUseTransit(); needed -= orderMaterial1.getUseTransit();
...@@ -1315,27 +1313,27 @@ if(headers1==null) ...@@ -1315,27 +1313,27 @@ if(headers1==null)
// 处理半成品/成品的现有订单 // 处理半成品/成品的现有订单
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) { for (Integer orderid : orderids) {
coder.ClearorderOperationResult(chromosome, orderid); coder.ClearorderOperationResult(chromosome, orderid);
coder.EditorderOperation(chromosome, orderid, needed,machineTasksCache, entryIndexById, scheduleIndexById); coder.EditorderOperation(chromosome, orderid, needed,machineTasksCache, entryIndexById, scheduleIndexById);
} }
}else { }else {
List<MaterialPurchase> materialPurchaseList=material.getMaterialPurchases(); List<MaterialPurchase> materialPurchaseList=material.getMaterialPurchases();
if(materialPurchaseList!=null&&materialPurchaseList.size()>0) { if(materialPurchaseList!=null&&materialPurchaseList.size()>0) {
int randomSeq = rnd.nextInt(materialPurchaseList.size()); int randomSeq = rnd.nextInt(materialPurchaseList.size());
MaterialPurchase result = materialPurchaseList.get(randomSeq); MaterialPurchase result = materialPurchaseList.get(randomSeq);
orderMaterial.setCheckLeadTime(result.getPurchaseCycle()); orderMaterial.setCheckLeadTime(result.getPurchaseCycle());
orderMaterial.setPurchaseTime(result.getInspectionCycle()); orderMaterial.setPurchaseTime(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); orderMaterial.getReplaceMaterial().removeIf(t->t.getUseStock()==0&&t.getUseTransit()==0);
} }
...@@ -1376,14 +1374,14 @@ if(headers1==null) ...@@ -1376,14 +1374,14 @@ if(headers1==null)
private void MaterialInTransit(Material material,String materialId, OrderMaterialRequirement orderMaterial, double needed,LocalDateTime earliestStartTime ){ private void MaterialInTransit(Material material,String materialId, OrderMaterialRequirement orderMaterial, double needed,LocalDateTime earliestStartTime, List<Material> materials ){
// 处理在途物料 // 处理在途物料
double accumulated = 0; double accumulated = 0;
LocalDateTime earliestTime = LocalDateTime.of(2000,1,1,0,0,0); 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()
.filter(m -> m.getId().equals(materialId)) .filter(m -> m.getId().equals(materialId))
.findFirst() .findFirst()
.orElse(null); .orElse(null);
......
...@@ -894,7 +894,7 @@ public class MaterialRequirementServicebf { ...@@ -894,7 +894,7 @@ public class MaterialRequirementServicebf {
childorder.setQuantity((int) orderMaterial.getQjQty()); childorder.setQuantity((int) orderMaterial.getQjQty());
childorder.setFinishOrderId(new ArrayList<>()); childorder.setFinishOrderId(new ArrayList<>());
childorder.getFinishOrderId().add(forder.getId()); childorder.getFinishOrderId().add(forder.getId());
childorder.setNewCreate(true); childorder.setNewSfCreate(true);
childorder.setTargetFinishedOperationId(new ArrayList<>()); childorder.setTargetFinishedOperationId(new ArrayList<>());
childorder.getTargetFinishedOperationId().add(operation.getId()); childorder.getTargetFinishedOperationId().add(operation.getId());
childorder.setSerie(forder.getSerie()); childorder.setSerie(forder.getSerie());
......
...@@ -19,12 +19,60 @@ import java.util.stream.Collectors; ...@@ -19,12 +19,60 @@ import java.util.stream.Collectors;
public class VariableNeighborhoodSearch { public class VariableNeighborhoodSearch {
private final Random rnd = new Random(); private final Random rnd = new Random();
// ==================== 常量定义 ====================
private static final int MAX_CONSECUTIVE_SAME_STRATEGY = 3;
private static final int MAX_NEIGHBORHOODS = 7;
private static final double HIGH_PRIORITY_GROUP_PROBABILITY = 0.7;
private static final int MAX_ATTEMPTS = 50;
private static final int NEIGHBOR_SELECTION_TOP_K = 3;
private static final int MOVE_STEPS_MIN = 1;
private static final int MOVE_STEPS_MAX = 5;
private static final int NON_BOTTLENECK_MOVE_STEPS_MAX = 3;
private static final int RANDOM_NEIGHBOR_TYPE_COUNT = 5;
private static final double INITIAL_SUCCESS_RATE = 0.3;
private static final double LOW_SUCCESS_RATE_THRESHOLD = 0.1;
private static final int LOW_SUCCESS_RATE_MIN_TRIALS = 10;
private static final double EXPLORATION_BONUS_FOR_LOW_USE = 0.3;
private static final double EXPLORATION_BONUS_FOR_LOW_SUCCESS = 0.2;
private static final double RANDOM_NOISE_FACTOR = 0.15;
private static final double FORCE_ROTATE_PENALTY = 0.5;
private static final double PERCENTILE_90 = 0.90;
private static final double BOTTLENECK_MACHINE_BASE_SCORE = 10000;
private static final double WAIT_TIME_WEIGHT = 30;
private static final double MACHINE_WAIT_TIME_WEIGHT = 30;
private static final double CRITICAL_PATH_WEIGHT_ON_BOTTLENECK = 25;
private static final double CRITICAL_PATH_WEIGHT_OFF_BOTTLENECK = 20;
private static final double DELAY_CONTRIBUTION_WEIGHT_ON_BOTTLENECK = 15;
private static final double DELAY_CONTRIBUTION_WEIGHT_OFF_BOTTLENECK = 10;
private static final double NORMALIZATION_CAP = 1.5;
private static final int TOP_BOTTLENECK_OPS_TO_RETURN = 10;
private static final int TOP_MACHINES_TO_LOG = 5;
private static final double PRIORITY_EPSILON = 0.001;
private static final int MIN_USE_COUNT_FOR_EXPLORATION_BONUS = 5;
// 日志级别
private static final int LOG_LEVEL_DEBUG = 0;
private static final int LOG_LEVEL_INFO = 1;
private static final int LOG_LEVEL_WARN = 2;
private int currentLogLevel = LOG_LEVEL_INFO;
// 局部搜索优化
private static final int MAX_LOCAL_SEARCH_NEIGHBORS = 5;
private void log(String message) { private void log(String message) {
log(message, true); log(message, LOG_LEVEL_INFO, false);
} }
private void log(String message, boolean enableLogging) { private void log(String message, boolean enableLogging) {
if (enableLogging) { log(message, LOG_LEVEL_INFO, enableLogging);
}
private void log(String message, int level) {
log(message, level, false);
}
private void log(String message, int level, boolean enableLogging) {
if (enableLogging && level >= currentLogLevel) {
FileHelper.writeLogFile(message); FileHelper.writeLogFile(message);
} }
} }
...@@ -51,7 +99,6 @@ public class VariableNeighborhoodSearch { ...@@ -51,7 +99,6 @@ public class VariableNeighborhoodSearch {
// 强制策略轮换:跟踪最后使用的策略 // 强制策略轮换:跟踪最后使用的策略
private int lastUsedStrategy = -1; private int lastUsedStrategy = -1;
private int consecutiveSameStrategyCount = 0; private int consecutiveSameStrategyCount = 0;
private static final int MAX_CONSECUTIVE_SAME_STRATEGY = 3; // 最多连续使用同一个策略3次
// 缓存的深拷贝列表,用于解码优化 // 缓存的深拷贝列表,用于解码优化
private List<Machine> cachedMachines; private List<Machine> cachedMachines;
...@@ -60,6 +107,8 @@ public class VariableNeighborhoodSearch { ...@@ -60,6 +107,8 @@ public class VariableNeighborhoodSearch {
private List<Material> cachedMaterials; private List<Material> cachedMaterials;
private List<Entry> cachedAllOperations; private List<Entry> cachedAllOperations;
private GeneticOperations geneticOperations;
// 邻域结构成功率统计(用于 search() 方法) // 邻域结构成功率统计(用于 search() 方法)
private static class NeighborhoodWithStats { private static class NeighborhoodWithStats {
NeighborhoodStructure structure; NeighborhoodStructure structure;
...@@ -87,7 +136,7 @@ public class VariableNeighborhoodSearch { ...@@ -87,7 +136,7 @@ public class VariableNeighborhoodSearch {
public VariableNeighborhoodSearch( List<Entry> allOperations, List<Order> orders, public VariableNeighborhoodSearch( List<Entry> allOperations, List<Order> orders,
List<Material> materials,List<GroupResult> entryRel, FitnessCalculator fitnessCalculator) { List<Material> materials,List<GroupResult> entryRel, FitnessCalculator fitnessCalculator) {
this(allOperations, orders, materials, entryRel, fitnessCalculator, 3); this(allOperations, orders, materials, entryRel, fitnessCalculator, 1);
} }
public VariableNeighborhoodSearch( List<Entry> allOperations, List<Order> orders, public VariableNeighborhoodSearch( List<Entry> allOperations, List<Order> orders,
...@@ -126,7 +175,7 @@ public class VariableNeighborhoodSearch { ...@@ -126,7 +175,7 @@ public class VariableNeighborhoodSearch {
for (NeighborhoodStructure ns : initialNeighborhoods) { for (NeighborhoodStructure ns : initialNeighborhoods) {
neighborhoodsWithStats.add(new NeighborhoodWithStats(ns)); neighborhoodsWithStats.add(new NeighborhoodWithStats(ns));
} }
geneticOperations=new GeneticOperations();
//log("VariableNeighborhoodSearch初始化: hasMultipleMachineOptions=" + hasMultipleMachineOptions); //log("VariableNeighborhoodSearch初始化: hasMultipleMachineOptions=" + hasMultipleMachineOptions);
} }
...@@ -147,6 +196,12 @@ public class VariableNeighborhoodSearch { ...@@ -147,6 +196,12 @@ public class VariableNeighborhoodSearch {
//非瓶颈工序往后移动 //非瓶颈工序往后移动
neighborhoods.add(new NeighborhoodStructure("MoveNonBottleneckBackward", this::moveNonBottleneckBackwardWrapper)); neighborhoods.add(new NeighborhoodStructure("MoveNonBottleneckBackward", this::moveNonBottleneckBackwardWrapper));
//瓶颈设备工序激进重排
neighborhoods.add(new NeighborhoodStructure("AggressiveBottleneckReorder", this::aggressiveBottleneckReorderWrapper));
//关键路径工序优化
neighborhoods.add(new NeighborhoodStructure("CriticalPathOptimize", this::criticalPathOptimizeWrapper));
//// 交换相同设备的两个工序 //// 交换相同设备的两个工序
neighborhoods.add(new NeighborhoodStructure("SwapSameMachine", this::generateSameMachineSwapNeighbor)); neighborhoods.add(new NeighborhoodStructure("SwapSameMachine", this::generateSameMachineSwapNeighbor));
...@@ -176,7 +231,7 @@ public class VariableNeighborhoodSearch { ...@@ -176,7 +231,7 @@ public class VariableNeighborhoodSearch {
// result.add(ns.structure); // result.add(ns.structure);
// } // }
int maxNeighborhoods = Math.min(7, sorted.size()); int maxNeighborhoods = Math.min(MAX_NEIGHBORHOODS, sorted.size());
for (int i = 0; i < maxNeighborhoods; i++) { for (int i = 0; i < maxNeighborhoods; i++) {
result.add(sorted.get(i).structure); result.add(sorted.get(i).structure);
} }
...@@ -218,7 +273,7 @@ public class VariableNeighborhoodSearch { ...@@ -218,7 +273,7 @@ public class VariableNeighborhoodSearch {
*/ */
public Chromosome search(Chromosome chromosome, GeneticDecoder decoder, List<Machine> machines) { public Chromosome search(Chromosome chromosome, GeneticDecoder decoder, List<Machine> machines) {
log("变邻域搜索 - 开始执行",true); log("变邻域搜索 - 开始执行",true);
geneticOperations.DelOrder(chromosome);
// 深拷贝当前染色体 // 深拷贝当前染色体
Chromosome current = ProductionDeepCopyUtil.deepCopy(chromosome, Chromosome.class); Chromosome current = ProductionDeepCopyUtil.deepCopy(chromosome, Chromosome.class);
Chromosome best = ProductionDeepCopyUtil.deepCopy(chromosome, Chromosome.class); Chromosome best = ProductionDeepCopyUtil.deepCopy(chromosome, Chromosome.class);
...@@ -276,7 +331,7 @@ public class VariableNeighborhoodSearch { ...@@ -276,7 +331,7 @@ public class VariableNeighborhoodSearch {
// 邻域移动 // 邻域移动
boolean success = isBetter(localBest, best); boolean success = isBetter(localBest, best);
if (success) { if (success) {
best = ProductionDeepCopyUtil.deepCopy(localBest, Chromosome.class); best = localBest;
writeKpi(best); writeKpi(best);
current = localBest; current = localBest;
k = 0; // 重置邻域索引 k = 0; // 重置邻域索引
...@@ -554,7 +609,7 @@ public class VariableNeighborhoodSearch { ...@@ -554,7 +609,7 @@ public class VariableNeighborhoodSearch {
} }
// 订单数相同时,按优先级排序 // 订单数相同时,按优先级排序
return Double.compare(entry2.getPriority(), entry1.getPriority()); return Double.compare(entry1.getPriority(), entry2.getPriority());
}); });
} }
...@@ -1072,7 +1127,7 @@ public class VariableNeighborhoodSearch { ...@@ -1072,7 +1127,7 @@ public class VariableNeighborhoodSearch {
} }
// 订单数相同时,按优先级排序 // 订单数相同时,按优先级排序
return Double.compare(entryB.getPriority(), entryA.getPriority()); return Double.compare(entryA.getPriority(), entryB.getPriority());
}); });
// 70%概率选择前3个候选,30%概率随机选择 // 70%概率选择前3个候选,30%概率随机选择
...@@ -1131,7 +1186,8 @@ public class VariableNeighborhoodSearch { ...@@ -1131,7 +1186,8 @@ public class VariableNeighborhoodSearch {
} }
/** /**
* 给指定位置的工序换设备 * 给指定位置的工序换设备 - 考虑设备负载均衡优化
* 优先选择负载低的设备
*/ */
private Chromosome generateMachineChangeForSpecificOp(Chromosome chromosome, List<MachineOption> machineOptions, int idx) { private Chromosome generateMachineChangeForSpecificOp(Chromosome chromosome, List<MachineOption> machineOptions, int idx) {
Chromosome neighbor=copyChromosome(chromosome);// ProductionDeepCopyUtil.deepCopy(chromosome, Chromosome.class); Chromosome neighbor=copyChromosome(chromosome);// ProductionDeepCopyUtil.deepCopy(chromosome, Chromosome.class);
...@@ -1147,7 +1203,8 @@ public class VariableNeighborhoodSearch { ...@@ -1147,7 +1203,8 @@ public class VariableNeighborhoodSearch {
} }
if (!availableMachines.isEmpty()) { if (!availableMachines.isEmpty()) {
int newMachineSeq = availableMachines.get(rnd.nextInt(availableMachines.size())); // 选择负载较低的设备(设备负载均衡优化)
int newMachineSeq = selectMachineByLoad(availableMachines, machineOptions, chromosome);
ms.set(idx, newMachineSeq); ms.set(idx, newMachineSeq);
neighbor.setMachineSelection(ms); neighbor.setMachineSelection(ms);
} }
...@@ -1247,7 +1304,7 @@ public class VariableNeighborhoodSearch { ...@@ -1247,7 +1304,7 @@ public class VariableNeighborhoodSearch {
} }
// 订单数相同时,按优先级排序 // 订单数相同时,按优先级排序
int priorityCompare = Double.compare(entryB.getPriority(), entryA.getPriority()); int priorityCompare = Double.compare(entryA.getPriority(), entryB.getPriority());
if (priorityCompare != 0) { if (priorityCompare != 0) {
return priorityCompare; return priorityCompare;
} }
...@@ -1381,6 +1438,7 @@ public class VariableNeighborhoodSearch { ...@@ -1381,6 +1438,7 @@ public class VariableNeighborhoodSearch {
* 将工序往前移动 * 将工序往前移动
*/ */
private Chromosome moveOperationForward(Chromosome chromosome, Map<Integer, Entry> originalPositionIndex,int pos, int steps) { private Chromosome moveOperationForward(Chromosome chromosome, Map<Integer, Entry> originalPositionIndex,int pos, int steps) {
geneticOperations.DelOrder(chromosome);
Chromosome neighbor = ProductionDeepCopyUtil.deepCopy(chromosome, Chromosome.class); Chromosome neighbor = ProductionDeepCopyUtil.deepCopy(chromosome, Chromosome.class);
List<Integer> os = neighbor.getOperationSequencing(); List<Integer> os = neighbor.getOperationSequencing();
...@@ -1522,14 +1580,15 @@ public class VariableNeighborhoodSearch { ...@@ -1522,14 +1580,15 @@ public class VariableNeighborhoodSearch {
private Chromosome copyChromosome(Chromosome chromosome) private Chromosome copyChromosome(Chromosome chromosome)
{ {
geneticOperations.DelOrder(chromosome);
Chromosome neighbor=new Chromosome(); Chromosome neighbor=new Chromosome();
neighbor.setID(UUID.randomUUID().toString()); neighbor.setID(UUID.randomUUID().toString());
neighbor.setOperationSequencing(chromosome.getOperationSequencing()); neighbor.setOperationSequencing(new ArrayList<>(chromosome.getOperationSequencing()));
neighbor.setMachineSelection(chromosome.getMachineSelection()); neighbor.setMachineSelection(new ArrayList<>(chromosome.getMachineSelection()));
neighbor.setScenarioID(chromosome.getScenarioID()); neighbor.setScenarioID(chromosome.getScenarioID());
neighbor.setBaseTime(chromosome.getBaseTime()); neighbor.setBaseTime(chromosome.getBaseTime());
neighbor.setFitnessLevel(chromosome.getFitnessLevel()); neighbor.setFitnessLevel(chromosome.getFitnessLevel());
neighbor.setGlobalOpList(chromosome.getGlobalOpList()); neighbor.setGlobalOpList(new ArrayList<>(chromosome.getGlobalOpList()));
return neighbor; return neighbor;
} }
...@@ -1722,14 +1781,17 @@ public class VariableNeighborhoodSearch { ...@@ -1722,14 +1781,17 @@ public class VariableNeighborhoodSearch {
if (op.getMachineOptions().size() > 1) { if (op.getMachineOptions().size() > 1) {
int currentMachineSeq = ms.get(idx); int currentMachineSeq = ms.get(idx);
List<Integer> availableMachines = new ArrayList<>(); List<Integer> availableMachines = new ArrayList<>();
List<MachineOption> machineOptions = new ArrayList<>();
for (int i = 1; i <= op.getMachineOptions().size(); i++) { for (int i = 1; i <= op.getMachineOptions().size(); i++) {
if (i != currentMachineSeq) { if (i != currentMachineSeq) {
availableMachines.add(i); availableMachines.add(i);
machineOptions.add(op.getMachineOptions().get(i));
} }
} }
if (!availableMachines.isEmpty()) { if (!availableMachines.isEmpty()) {
int newMachineSeq = availableMachines.get(rnd.nextInt(availableMachines.size())); // 选择负载较低的设备(设备负载均衡优化)
int newMachineSeq = selectMachineByLoad(availableMachines, machineOptions, chromosome);
ms.set(idx, newMachineSeq); ms.set(idx, newMachineSeq);
neighbor.setMachineSelection(ms); neighbor.setMachineSelection(ms);
} }
...@@ -1858,10 +1920,11 @@ public class VariableNeighborhoodSearch { ...@@ -1858,10 +1920,11 @@ public class VariableNeighborhoodSearch {
* 局部搜索 * 局部搜索
*/ */
private Chromosome localSearch(Chromosome chromosome, GeneticDecoder decoder, List<Machine> machines) { private Chromosome localSearch(Chromosome chromosome, GeneticDecoder decoder, List<Machine> machines) {
geneticOperations.DelOrder(chromosome);
Chromosome current = ProductionDeepCopyUtil.deepCopy(chromosome, Chromosome.class); Chromosome current = ProductionDeepCopyUtil.deepCopy(chromosome, Chromosome.class);
Chromosome best = ProductionDeepCopyUtil.deepCopy(chromosome, Chromosome.class); Chromosome best = ProductionDeepCopyUtil.deepCopy(chromosome, Chromosome.class);
decode(decoder, best, machines); decode(decoder, best, machines);
//writeKpi(best); writeKpi(best);
// 预定义邻域结构,避免每次循环重复创建 // 预定义邻域结构,避免每次循环重复创建
List<NeighborhoodStructure> neighborhoods = defineNeighborhoods(); List<NeighborhoodStructure> neighborhoods = defineNeighborhoods();
...@@ -1869,9 +1932,14 @@ public class VariableNeighborhoodSearch { ...@@ -1869,9 +1932,14 @@ public class VariableNeighborhoodSearch {
while (improved) { while (improved) {
improved = false; improved = false;
// 生成所有可能的邻域解 // 生成邻域解(限制数量以提高性能)
List<Chromosome> neighbors = new ArrayList<>(); List<Chromosome> neighbors = new ArrayList<>();
for (NeighborhoodStructure neighborhood : neighborhoods) { for (NeighborhoodStructure neighborhood : neighborhoods) {
if (neighbors.size() >= MAX_LOCAL_SEARCH_NEIGHBORS) {
break;
}
Chromosome neighbor = generateNeighbor(current, neighborhood); Chromosome neighbor = generateNeighbor(current, neighborhood);
if (neighbor != null) { if (neighbor != null) {
neighbors.add(neighbor); neighbors.add(neighbor);
...@@ -1884,7 +1952,7 @@ public class VariableNeighborhoodSearch { ...@@ -1884,7 +1952,7 @@ public class VariableNeighborhoodSearch {
Batchdecode(decoder, neighbors, machines); Batchdecode(decoder, neighbors, machines);
// 评估所有邻域解 // 评估所有邻域解,找到第一个改进就停止(贪心策略)
for (Chromosome neighbor : neighbors) { for (Chromosome neighbor : neighbors) {
if (neighbor != null && isBetter(neighbor, best)) { if (neighbor != null && isBetter(neighbor, best)) {
...@@ -1892,6 +1960,7 @@ public class VariableNeighborhoodSearch { ...@@ -1892,6 +1960,7 @@ public class VariableNeighborhoodSearch {
writeKpi(best); writeKpi(best);
current = neighbor; current = neighbor;
improved = true; improved = true;
break; // 找到一个改进就退出,提高效率
} }
} }
} }
...@@ -2105,4 +2174,309 @@ public class VariableNeighborhoodSearch { ...@@ -2105,4 +2174,309 @@ public class VariableNeighborhoodSearch {
return operator.apply(chromosome); return operator.apply(chromosome);
} }
} }
/**
* 机器选项和负载信息的辅助类
*/
private static class MachineOptionWithUtilization {
int seq;
MachineOption option;
double utilization;
MachineOptionWithUtilization(int seq, MachineOption option, double utilization) {
this.seq = seq;
this.option = option;
this.utilization = utilization;
}
}
/**
* 选择负载较低的设备 - 设备负载均衡优化
* 优先选择负载低的设备
*/
private int selectMachineByLoad(List<Integer> availableMachineSeqs, List<MachineOption> machineOptions, Chromosome chromosome) {
// 计算当前各设备的负载(利用率)
Map<Long, Double> machineUtilization = calculateMachineUtilization(chromosome);
// 构建可用机器列表,按负载从低到高排序
List<MachineOptionWithUtilization> availableMachines = new ArrayList<>();
for (int seq : availableMachineSeqs) {
MachineOption option = machineOptions.get(seq - 1);
Long machineId = option.getMachineId();
double utilization = machineUtilization.getOrDefault(machineId, 0.0);
availableMachines.add(new MachineOptionWithUtilization(seq, option, utilization));
}
// 按利用率从低到高排序
availableMachines.sort(Comparator.comparingDouble(m -> m.utilization));
// 70%概率选择负载最低的设备,30%概率随机选择
if (rnd.nextDouble() < 0.7) {
return availableMachines.get(0).seq;
} else {
return availableMachines.get(rnd.nextInt(availableMachines.size())).seq;
}
}
/**
* 交换候选对象,包含位置和评分(用于准备时间优化)
*/
private static class SwapCandidate {
int position;
double score;
SwapCandidate(int position, double score) {
this.position = position;
this.score = score;
}
}
/**
* 瓶颈设备工序激进重排 - Wrapper方法
*/
private Chromosome aggressiveBottleneckReorderWrapper(Chromosome chromosome) {
List<GAScheduleResult> results = chromosome.getResult();
Map<Integer, Object> obj = buildPositionToEntryIndex(chromosome);
Map<Integer, Entry> positionToEntryIndex = (Map<Integer, Entry>) obj.get(1);
List<List<Integer>> positionByPriority = (List<List<Integer>>) obj.get(2);
Map<String, Integer> machinePositionIndex = buildEntryMachinePositionIndex(chromosome);
if (results == null || results.isEmpty()) {
return generateRandomNeighbor(chromosome, positionToEntryIndex, positionByPriority);
}
Long bottleneckMachineId = findBottleneckMachine(chromosome);
if (bottleneckMachineId != null) {
Chromosome result = tryAggressiveBottleneckReorder(chromosome, bottleneckMachineId, positionToEntryIndex, machinePositionIndex);
if (result != null) {
return result;
}
}
return generateRandomNeighbor(chromosome, positionToEntryIndex, positionByPriority);
}
/**
* 瓶颈设备工序激进重排 - 更激进地调整瓶颈设备上的工序顺序
* 策略:将延迟订单的工序和高优先级工序尽可能往前移动
*/
private Chromosome tryAggressiveBottleneckReorder(Chromosome chromosome, Long bottleneckMachineId,
Map<Integer, Entry> positionIndex,
Map<String, Integer> machinePositionIndex) {
log("tryAggressiveBottleneckReorder: 开始激进重排瓶颈设备工序");
List<GAScheduleResult> allResults = chromosome.getResult();
if (allResults == null || allResults.isEmpty()) {
return null;
}
// 获取瓶颈设备上的所有工序
List<GAScheduleResult> bottleneckOps = allResults.stream()
.filter(r -> r.getMachineId()==(bottleneckMachineId))
.collect(Collectors.toList());
if (bottleneckOps.size() < 2) {
log("tryAggressiveBottleneckReorder: 瓶颈设备上工序太少,无法重排");
return null;
}
// 计算订单完成时间
Map<Integer, Integer> orderCompletionTimes = calculateOrderCompletionTimes(allResults);
// 找出延迟订单(结束时间 > 到期时间,假设Entry有dueDate字段,这里简化为结束时间较晚的订单)
Set<Integer> delayedOrderIds = new HashSet<>();
int avgCompletionTime = (int) orderCompletionTimes.values().stream()
.mapToInt(Integer::intValue)
.average()
.orElse(0);
for (Map.Entry<Integer, Integer> entry : orderCompletionTimes.entrySet()) {
if (entry.getValue() > avgCompletionTime * 1.2) { // 超过平均完成时间20%视为延迟
delayedOrderIds.add(entry.getKey());
}
}
Chromosome neighbor = copyChromosome(chromosome);
List<Integer> os = neighbor.getOperationSequencing();
// 对瓶颈设备上的工序进行评分
List<OperationScore> scoredOps = new ArrayList<>();
for (GAScheduleResult op : bottleneckOps) {
Entry entry = entrybyids.get(op.getOperationId());
if (entry == null) continue;
double score = 0;
// 1. 延迟订单的工序加分
if (delayedOrderIds.contains(op.getGroupId())) {
score += 100;
}
// 2. 高优先级工序加分(注意:priority值越低优先级越高)
score += (10.0 / (entry.getPriority() + 0.1)) * 50; // 优先级值越低,得分越高
// 3. 结束时间晚的工序加分(优先移动)
score += (double) op.getEndTime() / 10000;
String key = entry.getGroupId() + "_" + entry.getSequence();
Integer pos = buildPositionIndex(chromosome).get(key);
if (pos != null) {
scoredOps.add(new OperationScore(pos, score));
}
}
if (scoredOps.size() < 2) {
return null;
}
// 按评分从高到低排序
scoredOps.sort((a, b) -> Double.compare(b.score, a.score));
// 选择评分最高的工序,尝试往前移动
OperationScore selectedOp = scoredOps.get(0);
int steps = rnd.nextInt(Math.min(10, selectedOp.position)) + 1; // 最多往前移动10步
log(String.format("tryAggressiveBottleneckReorder: 选择位置%d,往前移动%d步", selectedOp.position, steps));
return insertOperationForward(neighbor, selectedOp.position, steps, entrys, positionIndex);
}
/**
* 工序评分辅助类
*/
private static class OperationScore {
int position;
double score;
OperationScore(int position, double score) {
this.position = position;
this.score = score;
}
}
/**
* 关键路径工序优化 - Wrapper方法
*/
private Chromosome criticalPathOptimizeWrapper(Chromosome chromosome) {
List<GAScheduleResult> results = chromosome.getResult();
Map<Integer, Object> obj = buildPositionToEntryIndex(chromosome);
Map<Integer, Entry> positionToEntryIndex = (Map<Integer, Entry>) obj.get(1);
List<List<Integer>> positionByPriority = (List<List<Integer>>) obj.get(2);
if (results == null || results.isEmpty()) {
return generateRandomNeighbor(chromosome, positionToEntryIndex, positionByPriority);
}
Long bottleneckMachineId = findBottleneckMachine(chromosome);
Chromosome result = tryCriticalPathOptimize(chromosome, bottleneckMachineId, positionToEntryIndex);
if (result != null) {
return result;
}
return generateRandomNeighbor(chromosome, positionToEntryIndex, positionByPriority);
}
/**
* 关键路径工序优化 - 专门针对关键路径上的工序进行优化
* 策略:
* 1. 找出关键路径上的工序
* 2. 优先尝试将关键路径工序往前移动
* 3. 尝试为关键路径工序换设备(如果有选择)
*/
private Chromosome tryCriticalPathOptimize(Chromosome chromosome, Long bottleneckMachineId,
Map<Integer, Entry> positionIndex) {
log("tryCriticalPathOptimize: 开始关键路径工序优化");
List<GAScheduleResult> allResults = chromosome.getResult();
if (allResults == null || allResults.isEmpty()) {
return null;
}
// 分析瓶颈工序,获取关键路径信息
List<BottleneckOperationAnalysis> analyses = analyzeBottleneckOperations(allResults, bottleneckMachineId);
// 找出关键路径上的工序
List<BottleneckOperationAnalysis> criticalPathOps = analyses.stream()
.filter(a -> a.onCriticalPath)
.collect(Collectors.toList());
if (criticalPathOps.isEmpty()) {
log("tryCriticalPathOptimize: 没有找到关键路径工序");
return null;
}
log(String.format("tryCriticalPathOptimize: 找到%d个关键路径工序", criticalPathOps.size()));
Chromosome neighbor = copyChromosome(chromosome);
List<Integer> os = neighbor.getOperationSequencing();
// 对关键路径工序进行评分
List<CriticalPathOpScore> scoredOps = new ArrayList<>();
for (BottleneckOperationAnalysis boa : criticalPathOps) {
GAScheduleResult op = boa.operation;
Entry entry = entrybyids.get(op.getOperationId());
if (entry == null) continue;
double score = 0;
// 1. 在瓶颈设备上的关键工序加分
if (bottleneckMachineId != null && op.getMachineId()==(bottleneckMachineId)) {
score += 100;
}
// 2. 等待时间长的工序加分
score += boa.waitTime / 100.0;
// 3. 机器等待时间长的工序加分
score += boa.machineWaitTime / 100.0;
// 4. 高优先级加分(注意:priority值越低优先级越高)
score += (10.0 / (entry.getPriority() + 0.1)) * 30; // 优先级值越低,得分越高
String key = entry.getGroupId() + "_" + entry.getSequence();
Integer pos = buildPositionIndex(chromosome).get(key);
if (pos != null) {
scoredOps.add(new CriticalPathOpScore(pos, entry, score));
}
}
if (scoredOps.isEmpty()) {
return null;
}
// 按评分从高到低排序
scoredOps.sort((a, b) -> Double.compare(b.score, a.score));
CriticalPathOpScore selected = scoredOps.get(0);
// 50%概率尝试往前移动,50%概率尝试换设备(如果有选择)
if (rnd.nextDouble() < 0.5 && selected.position > 0) {
// 尝试往前移动
int steps = rnd.nextInt(Math.min(5, selected.position)) + 1;
log(String.format("tryCriticalPathOptimize: 关键路径工序往前移动%d步", steps));
return insertOperationForward(neighbor, selected.position, steps, entrys, positionIndex);
} else if (selected.entry.getMachineOptions().size() > 1) {
// 尝试换设备
log("tryCriticalPathOptimize: 关键路径工序尝试换设备");
Map<String, Integer> machinePositionIndex = buildEntryMachinePositionIndex(chromosome);
int maPos = machinePositionIndex.get(selected.entry.getGroupId() + "_" + selected.entry.getSequence());
if (maPos >= 0) {
return generateMachineChangeForSpecificOp(neighbor, selected.entry.getMachineOptions(), maPos);
}
}
// 如果以上都失败,尝试简单的往前移动
if (selected.position > 0) {
int steps = rnd.nextInt(Math.min(3, selected.position)) + 1;
return insertOperationForward(neighbor, selected.position, steps, entrys, positionIndex);
}
return null;
}
/**
* 关键路径工序评分辅助类
*/
private static class CriticalPathOpScore {
int position;
Entry entry;
double score;
CriticalPathOpScore(int position, Entry entry, double score) {
this.position = position;
this.entry = entry;
this.score = score;
}
}
} }
\ No newline at end of file
...@@ -238,7 +238,7 @@ public class PlanResultService { ...@@ -238,7 +238,7 @@ public class PlanResultService {
_sceneService.saveChromosomeToFile(chromosome, SceneId); _sceneService.saveChromosomeToFile(chromosome, SceneId);
WriteScheduleSummary(chromosome); // WriteScheduleSummary(chromosome);
return chromosome; return chromosome;
......
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