Commit e56eef9d authored by Tong Li's avatar Tong Li

解码优化

parent 103266f2
...@@ -22,7 +22,7 @@ public class FileHelper { ...@@ -22,7 +22,7 @@ public class FileHelper {
String filePath = LOG_FILE_PATH + date + LOG_FILE; String filePath = LOG_FILE_PATH + date + LOG_FILE;
try (PrintWriter writer = new PrintWriter(new FileWriter(filePath, true))) { try (PrintWriter writer = new PrintWriter(new FileWriter(filePath, true))) {
String timestamp = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")); String timestamp = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS"));
writer.println("[" + timestamp + "] " + message); writer.println("[" + timestamp + "] " + message);
System.out.println("[" + timestamp + "] " + message); System.out.println("[" + timestamp + "] " + message);
......
...@@ -118,11 +118,11 @@ public class GeneticAlgorithm { ...@@ -118,11 +118,11 @@ public class GeneticAlgorithm {
FileHelper.writeLogFile("初始化种群-----------开始-------"); FileHelper.writeLogFile("初始化种群-----------开始-------");
// 步骤1:初始化种群 // 步骤1:初始化种群
// List<Chromosome> population = initialization.generateInitialPopulation(param, globalOpList); List<Chromosome> population = initialization.generateInitialPopulation(param, globalOpList);
// 步骤1:使用构造启发式算法生成初始种群 // 步骤1:使用构造启发式算法生成初始种群
FileHelper.writeLogFile("构造启发式初始化-----------开始-------"); FileHelper.writeLogFile("构造启发式初始化-----------开始-------");
List<Chromosome> population = initialization.generateHeuristicInitialPopulation(param, globalOpList); // List<Chromosome> population = initialization.generateHeuristicInitialPopulation(param, globalOpList);
FileHelper.writeLogFile("构造启发式初始化-----------结束-------"); FileHelper.writeLogFile("构造启发式初始化-----------结束-------");
...@@ -477,7 +477,7 @@ return population; ...@@ -477,7 +477,7 @@ return population;
FileHelper.writeLogFile("解码---------------"+population.size() ); FileHelper.writeLogFile("解码---------------"+population.size() );
GeneticDecoder decoder = new GeneticDecoder(_GlobalParam, param.getBaseTime(), machines, orders, materials, machineScheduler,materialRequirementService, sceneId); GeneticDecoder decoder = new GeneticDecoder(_GlobalParam, param.getBaseTime(), machines, orders, materials, machineScheduler,materialRequirementService, sceneId);
boolean ismore=true; boolean ismore=false;
if(ismore) { if(ismore) {
CompletableFuture.allOf(population.stream() CompletableFuture.allOf(population.stream()
.map(chromosome -> CompletableFuture.runAsync(() -> decode(decoder, chromosome, param, allOperations, globalOpList), decodeExecutor)) .map(chromosome -> CompletableFuture.runAsync(() -> decode(decoder, chromosome, param, allOperations, globalOpList), decodeExecutor))
......
...@@ -21,6 +21,7 @@ import java.time.Duration; ...@@ -21,6 +21,7 @@ import java.time.Duration;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit; import java.time.temporal.ChronoUnit;
import java.util.*; import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicInteger;
...@@ -338,10 +339,29 @@ if(finishedOrder==null||finishedOrder.size()==0) ...@@ -338,10 +339,29 @@ if(finishedOrder==null||finishedOrder.size()==0)
orderProcessCounter.put(orderid, scheduledCount); orderProcessCounter.put(orderid, scheduledCount);
} }
public void decode(Chromosome chromosome) {
int operationCount = chromosome.getAllOperations().size();
int cpuCores = Runtime.getRuntime().availableProcessors();
//
// // 根据工序数量和CPU核心数决定是否使用内部并行
if (operationCount > 500 && cpuCores > 4) {
// 使用并行处理
FileHelper.writeLogFile("使用并行处理 _s");
parallelDecodeByMachine(chromosome);
FileHelper.writeLogFile("使用并行处理 _e");
}
// else {
// 使用串行处理
// FileHelper.writeLogFile("使用串行处理 _s");
// serialDecode(chromosome);
// FileHelper.writeLogFile("使用串行处理 _e");
//}
}
/** /**
* 染色体解码为调度方案 * 染色体解码为调度方案
*/ */
public void decode(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);
...@@ -356,9 +376,14 @@ if(finishedOrder==null||finishedOrder.size()==0) ...@@ -356,9 +376,14 @@ if(finishedOrder==null||finishedOrder.size()==0)
List<GlobalOperationInfo> globalOpList=chromosome.getGlobalOpList(); List<GlobalOperationInfo> globalOpList=chromosome.getGlobalOpList();
List<Entry> allOperations=chromosome.getAllOperations(); List<Entry> allOperations=chromosome.getAllOperations();
_allOperations=chromosome.getAllOperations();
Map<Integer, GlobalOperationInfo> globalOpMap = globalOpList.stream()
.collect(Collectors.toMap(GlobalOperationInfo::getGlobalOpId, g -> g));
Map<Long, Machine> machineIdMap = chromosome.getMachines().stream()
.collect(Collectors.toMap(Machine::getId, m -> m));
// 验证:MachineSelection长度必须与全局工序数一致 // 验证:MachineSelection长度必须与全局工序数一致
if (chromosome.getMachineSelection().size() != globalOpList.size()) { if (chromosome.getMachineSelection().size() != globalOpList.size()) {
...@@ -369,6 +394,8 @@ if(finishedOrder==null||finishedOrder.size()==0) ...@@ -369,6 +394,8 @@ if(finishedOrder==null||finishedOrder.size()==0)
// 步骤1:生成“工序→机器/加工时间”映射 // 步骤1:生成“工序→机器/加工时间”映射
List<OpMachine> opMachineMap = new ArrayList<>(); List<OpMachine> opMachineMap = new ArrayList<>();
Map<String, OpMachine> opMachineKeyMap = new HashMap<>();
for (GlobalOperationInfo globalOp : globalOpList) { for (GlobalOperationInfo globalOp : globalOpList) {
int globalOpId = globalOp.getGlobalOpId(); int globalOpId = globalOp.getGlobalOpId();
Entry op = globalOp.getOp(); Entry op = globalOp.getOp();
...@@ -397,26 +424,37 @@ if(finishedOrder==null||finishedOrder.size()==0) ...@@ -397,26 +424,37 @@ if(finishedOrder==null||finishedOrder.size()==0)
opMachine.setSingleOut(selectedMachine.getSingleOut()); opMachine.setSingleOut(selectedMachine.getSingleOut());
opMachineMap.add(opMachine); opMachineMap.add(opMachine);
String key = opMachine.getGroupId() + "_" + opMachine.getSequence();
opMachineKeyMap.put(key, opMachine);
} }
// 步骤2:按OperationSequencing顺序调度工序 // 步骤2:按OperationSequencing顺序调度工序
Map<Integer, Integer> orderProcessCounter = allOperations.stream() // Map<Integer, Integer> orderProcessCounter = allOperations.stream()
.collect(Collectors.groupingBy(Entry::getGroupId, Collectors.collectingAndThen( // .collect(Collectors.groupingBy(Entry::getGroupId, Collectors.collectingAndThen(
Collectors.counting(), Long::intValue))) // Collectors.counting(), Long::intValue)))
.entrySet().stream() // .entrySet().stream()
.collect(Collectors.toMap(Map.Entry::getKey, e -> 0)); // .collect(Collectors.toMap(Map.Entry::getKey, e -> 0));
//
// Map<Integer, Integer> orderLastEndTime = allOperations.stream()
// .collect(Collectors.groupingBy(Entry::getGroupId))
// .keySet().stream()
// .collect(Collectors.toMap(k -> k, k -> 0));
Map<Integer, Integer> orderLastEndTime = allOperations.stream() // 步骤2:按OperationSequencing顺序调度工序
.collect(Collectors.groupingBy(Entry::getGroupId)) Map<Integer, Integer> orderProcessCounter = new HashMap<>();
.keySet().stream() Map<Integer, Integer> orderLastEndTime = new HashMap<>();
.collect(Collectors.toMap(k -> k, k -> 0)); for (Entry op : allOperations) {
int groupId = op.getGroupId();
orderProcessCounter.putIfAbsent(groupId, 0);
orderLastEndTime.putIfAbsent(groupId, 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<>();
for (int groupId : chromosome.getOperationSequencing()) { for (int groupId : chromosome.getOperationSequencing()) {
int scheduledCount = orderProcessCounter.get(groupId); int scheduledCount = orderProcessCounter.get(groupId);
List<Entry> orderOps = allOperations.stream() List<Entry> orderOps = allOperations.stream()
...@@ -444,43 +482,47 @@ if(finishedOrder==null||finishedOrder.size()==0) ...@@ -444,43 +482,47 @@ if(finishedOrder==null||finishedOrder.size()==0)
} }
// 从映射表中获取机器和加工时间 // 从映射表中获取机器和加工时间
OpMachine machineOption=opMachineMap.stream() // OpMachine machineOption=opMachineMap.stream()
.filter(m -> m.getGroupId() == groupId&&m.getSequence()==opSequence) // .filter(m -> m.getGroupId() == groupId&&m.getSequence()==opSequence)
.findFirst() // .findFirst()
.orElse(null); // .orElse(null);
String opMachineKey = groupId + "_" + opSequence;
OpMachine machineOption = opMachineKeyMap.get(opMachineKey);
Long machineId = machineOption.getMachineId(); Long machineId = machineOption.getMachineId();
double processTime = machineOption.getProcessingTime(); double processTime = machineOption.getProcessingTime();
Machine targetMachine = chromosome.getMachines().stream() // Machine targetMachine = chromosome.getMachines().stream()
.filter(m -> m.getId() == machineId) // .filter(m -> m.getId() == machineId)
.findFirst() // .findFirst()
.orElse(null); // .orElse(null);
// Machine targetMachine = machineIdMap.get(machineId);
int prevtime = 0; // int prevtime = 0;
//后处理时间 // //后处理时间
int teardownTime = currentOp.getTeardownTime(); // int teardownTime = currentOp.getTeardownTime();
if (!currentOp.getPrevEntryIds().isEmpty()) { // if (!currentOp.getPrevEntryIds().isEmpty()) {
// 处理多个前工序 // // 处理多个前工序
prevtime= CalPrevtime( prevtime, currentOp, chromosome, processTime, targetMachine); // prevtime= CalPrevtime( prevtime, currentOp, chromosome, processTime, targetMachine);
} // }
// 上个离散参数 // 上个离散参数
// 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()
.filter(m -> m.getId() == machineId)
.findFirst()
.orElse(null);
// Machine machine = chromosome.getMachines().stream()
// .filter(m -> m.getId() == machineId)
// .findFirst()
// .orElse(null);
// 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);
int actualEndTime = processWithSingleMachine(currentOp, machine, processTime, prevtime,machineOption, chromosome,false,prevendtime); // 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);
...@@ -494,11 +536,562 @@ if(finishedOrder==null||finishedOrder.size()==0) ...@@ -494,11 +536,562 @@ if(finishedOrder==null||finishedOrder.size()==0)
calculateScheduleResult(chromosome); calculateScheduleResult(chromosome);
} }
public void parallelDecode(Chromosome chromosome) {
FileHelper.writeLogFile("构建工序依赖图 _s");
// 1. 构建工序依赖图
Map<Integer, List<Integer>> dependencyGraph = buildDependencyGraph(chromosome);
FileHelper.writeLogFile("拓扑排序 _s");
// 2. 拓扑排序
List<Integer> topologicalOrder = topologicalSort(dependencyGraph,chromosome);
FileHelper.writeLogFile("按设备分组 _s");
// 3. 按设备分组
Map<Long, List<Integer>> machineToOpsMap = new HashMap<>();
Map<Integer, Integer> opToGroupIdMap = new HashMap<>();
Map<Integer, Long> opToMachineMap = new HashMap<>();
List<GlobalOperationInfo> globalOpList=chromosome.getGlobalOpList();
// 步骤1:生成“工序→机器/加工时间”映射
List<OpMachine> opMachineMap = new ArrayList<>();
Map<String, OpMachine> opMachineKeyMap = new HashMap<>();
Map<Long, CopyOnWriteArrayList<GAScheduleResult>> machineTasksCache = new HashMap<>();
Map<Long, Machine> machineIdMap = chromosome.getMachines().stream()
.collect(Collectors.toMap(Machine::getId, m -> m));
for (GlobalOperationInfo globalOp : globalOpList) {
int globalOpId = globalOp.getGlobalOpId();
Entry op = globalOp.getOp();
int groupId = globalOp.getGroupId();
int sequence = globalOp.getSequence();
// 从MachineSelection中获取当前工序的机器选择顺序号
int machineSeq = chromosome.getMachineSelection().get(globalOpId);
List<MachineOption> optionalMachines = op.getMachineOptions();
// 验证:机器顺序号必须在可选范围内
if (machineSeq < 1 || machineSeq > optionalMachines.size()) {
throw new IllegalStateException(String.format(
"全局工序%d(订单%d工序%d)的机器顺序号%d超出范围(1-%d)",
globalOpId, groupId, sequence, machineSeq, optionalMachines.size()));
}
// 获取选择的设备ID和加工时间
MachineOption selectedMachine = optionalMachines.get(machineSeq - 1);
OpMachine opMachine=new OpMachine();
opMachine.setGroupId(groupId);
opMachine.setSequence(sequence);
opMachine.setMachineId(selectedMachine.getMachineId());
opMachine.setProcessingTime(selectedMachine.getProcessingTime());
opMachine.setRuntime(selectedMachine.getRuntime());
opMachine.setSingleOut(selectedMachine.getSingleOut());
opMachineMap.add(opMachine);
String key = opMachine.getGroupId() + "_" + opMachine.getSequence();
opMachineKeyMap.put(key, opMachine);
}
FileHelper.writeLogFile("预处理工序信息 _s");
// 预处理工序信息
for (int opId : topologicalOrder) {
Entry op = findOperationById(chromosome, opId);
if (op != null) {
// 假设已经为工序分配了设备
String opMachineKey = op.getGroupId() + "_" + op.getSequence();
OpMachine machineOption = opMachineKeyMap.get(opMachineKey);
if (machineOption != null) {
machineToOpsMap.computeIfAbsent(machineOption.getMachineId(), k -> new ArrayList<>()).add(opId);
opToGroupIdMap.put(opId, op.getGroupId());
opToMachineMap.put(opId, machineOption.getMachineId());
}
}
}
// 4. 并行处理
Map<Integer, CompletableFuture<Void>> opFutures = new HashMap<>();
Map<Long, CompletableFuture<Void>> machineFutures = new HashMap<>();
FileHelper.writeLogFile("并行处理 _s");
for (int opId : topologicalOrder) {
// 获取当前工序的依赖
Entry op = findOperationById(chromosome, opId);
List<Integer> dependencies = dependencyGraph.getOrDefault(opId, Collections.emptyList());
// 等待所有依赖完成
List<CompletableFuture<Void>> dependencyFutures = dependencies.stream()
.map(opFutures::get)
.filter(Objects::nonNull)
.collect(Collectors.toList());
String opMachineKey = op.getGroupId() + "_" + op.getSequence();
OpMachine machineOption = opMachineKeyMap.get(opMachineKey);
Long machineId = machineOption.getMachineId();
double processTime = machineOption.getProcessingTime();
// 等待当前设备的上一个工序完成
CompletableFuture<Void> machineFuture = machineFutures.getOrDefault(machineId, CompletableFuture.completedFuture(null));
// 合并所有依赖
List<CompletableFuture<Void>> allDependencies = new ArrayList<>(dependencyFutures);
allDependencies.add(machineFuture);
// 创建当前工序的处理任务
CompletableFuture<Void> currentFuture = CompletableFuture.allOf(allDependencies.toArray(new CompletableFuture[0]))
.thenRunAsync(() -> {
// 处理当前工序
int actualEndTime = processOperation(op,machineId,processTime,machineOption,chromosome,machineIdMap,machineTasksCache);
});
// 保存当前工序的Future
opFutures.put(opId, currentFuture);
// 更新设备的Future
machineFutures.put(machineId, currentFuture);
}
// 等待所有工序完成
CompletableFuture.allOf(opFutures.values().toArray(new CompletableFuture[0])).join();
FileHelper.writeLogFile("calculateScheduleResult _s");
if(chromosome.getReOrderids()!=null&&chromosome.getReOrderids().size()>0) {
chromosome.getOperationSequencing().removeIf(t -> chromosome.getReOrderids().contains(t));
}
calculateScheduleResult(chromosome);
}
public void parallelDecodeByMachine(Chromosome chromosome) {
// 1. 获取工序处理顺序
List<Integer> operationSequencing = chromosome.getOperationSequencing();
List<GlobalOperationInfo> globalOpList=chromosome.getGlobalOpList();
List<Entry> allOperations=chromosome.getAllOperations();
// 2. 构建工序依赖图
Map<Integer, List<Integer>> dependencyGraph = buildDependencyGraph(chromosome);
Map<Long, CopyOnWriteArrayList<GAScheduleResult>> machineTasksCache = new HashMap<>();
Map<Long, Machine> machineIdMap = chromosome.getMachines().stream()
.collect(Collectors.toMap(Machine::getId, m -> m));
// 生成“工序→机器/加工时间”映射
List<OpMachine> opMachineMap = new ArrayList<>();
Map<String, OpMachine> opMachineKeyMap = new HashMap<>();
for (GlobalOperationInfo globalOp : globalOpList) {
int globalOpId = globalOp.getGlobalOpId();
Entry op = globalOp.getOp();
int groupId = globalOp.getGroupId();
int sequence = globalOp.getSequence();
// 从MachineSelection中获取当前工序的机器选择顺序号
int machineSeq = chromosome.getMachineSelection().get(globalOpId);
List<MachineOption> optionalMachines = op.getMachineOptions();
// 验证:机器顺序号必须在可选范围内
if (machineSeq < 1 || machineSeq > optionalMachines.size()) {
throw new IllegalStateException(String.format(
"全局工序%d(订单%d工序%d)的机器顺序号%d超出范围(1-%d)",
globalOpId, groupId, sequence, machineSeq, optionalMachines.size()));
}
// 获取选择的设备ID和加工时间
MachineOption selectedMachine = optionalMachines.get(machineSeq - 1);
OpMachine opMachine=new OpMachine();
opMachine.setGroupId(groupId);
opMachine.setSequence(sequence);
opMachine.setMachineId(selectedMachine.getMachineId());
opMachine.setProcessingTime(selectedMachine.getProcessingTime());
opMachine.setRuntime(selectedMachine.getRuntime());
opMachine.setSingleOut(selectedMachine.getSingleOut());
opMachineMap.add(opMachine);
String key = opMachine.getGroupId() + "_" + opMachine.getSequence();
opMachineKeyMap.put(key, opMachine);
}
// 初始化订单处理计数器
Map<Integer, Integer> orderProcessCounter = new HashMap<>();
for (Entry op : allOperations) {
int groupId = op.getGroupId();
orderProcessCounter.putIfAbsent(groupId, 0);
}
Map<Long, List<Entry>> machineToOpsMap = new HashMap<>();
//按照 OperationSequencing 顺序生成 machineToOpsMap
for (int groupId : operationSequencing) {
int scheduledCount = orderProcessCounter.get(groupId);
List<Entry> orderOps = allOperations.stream()
.filter(t -> t.getGroupId() == groupId)
.sorted(Comparator.comparing(Entry::getSequence))
.collect(Collectors.toList());
if (scheduledCount >= orderOps.size()) {
throw new IllegalStateException(String.format(
"订单%d的工序已全部调度(共%d道),无需重复处理!",
groupId, orderOps.size()));
}
Entry currentOp = orderOps.get(scheduledCount);
String opMachineKey = groupId + "_" + currentOp.getSequence();
OpMachine machineOption = opMachineKeyMap.get(opMachineKey);
Long machineId = machineOption.getMachineId();
machineToOpsMap.computeIfAbsent(machineId, k -> new ArrayList<>()).add(currentOp);
orderProcessCounter.put(groupId, orderProcessCounter.get(groupId) + 1);
}
// 6. 按照每个设备队列中第一个工序的 sequence 递增顺序排序
List<Map.Entry<Long, List<Entry>>> sortedMachineEntries = new ArrayList<>(machineToOpsMap.entrySet());
sortedMachineEntries.sort((e1, e2) -> {
List<Entry> ops1 = e1.getValue();
List<Entry> ops2 = e2.getValue();
if (ops1.isEmpty() && ops2.isEmpty()) {
return 0;
}
if (ops1.isEmpty()) {
return 1;
}
if (ops2.isEmpty()) {
return -1;
}
int sequence1 = ops1.get(0).getSequence();
int sequence2 = ops2.get(0).getSequence();
int sequenceCompare = Integer.compare(sequence1, sequence2);
if (sequenceCompare == 0) {
// sequence 相同的情况下,按照设备下 Entry 的数量递增排序
return Integer.compare(ops1.size(), ops2.size());
} else {
return sequenceCompare;
}
});
// 7. 初始化同步机制
// Map<Integer, CompletableFuture<Void>> opFutures = new ConcurrentHashMap<>();
// Map<Long, CompletableFuture<Void>> machineFutures = new ConcurrentHashMap<>();
//
// // 8. 并行处理每个设备的工序(按照排序后的顺序)
// List<CompletableFuture<Void>> allMachineFutures = new ArrayList<>();
//
// for (Map.Entry<Long, List<Entry>> entry : sortedMachineEntries) {
// final Long machineId = entry.getKey();
// final List<Entry> ops = entry.getValue();
// FileHelper.writeLogFile("使用并行处理 _s---"+machineId);
// CompletableFuture<Void> machineFuture = CompletableFuture.runAsync(() -> {
// // 顺序处理设备上的工序
// int i=0;
// for (Entry op : ops) {
// int opId = op.getId();
// String opMachineKey = op.getGroupId() + "_" + op.getSequence();
// OpMachine machineOption = opMachineKeyMap.get(opMachineKey);
//
//
// double processTime = machineOption.getProcessingTime();
// // 获取当前工序的依赖
// List<Integer> dependencies = dependencyGraph.getOrDefault(opId, Collections.emptyList());
// // 等待所有依赖完成
// List<CompletableFuture<Void>> dependencyFutures = dependencies.stream()
// .map(opFutures::get)
// .filter(Objects::nonNull)
// .collect(Collectors.toList());
//
// // 等待设备上一个工序完成
// CompletableFuture<Void> prevMachineFuture = machineFutures.getOrDefault(machineId, CompletableFuture.completedFuture(null));
//
// // 合并所有依赖
// List<CompletableFuture<Void>> allDependencies = new ArrayList<>(dependencyFutures);
// allDependencies.add(prevMachineFuture);
// if(machineId==2341) {
// FileHelper.writeLogFile("使用并行处理 ---" + machineId + "----" + i);
// }
// // 创建当前工序的处理任务
// CompletableFuture<Void> currentFuture = CompletableFuture.allOf(allDependencies.toArray(new CompletableFuture[0]))
// .thenRun(() -> {
// // 处理当前工序
// int actualEndTime = processOperation(op,machineId,processTime,machineOption,chromosome,machineIdMap,machineTasksCache);
//
// });
//
// // 保存当前工序的Future
// opFutures.put(opId, currentFuture);
// // 更新设备的Future
// machineFutures.put(machineId, currentFuture);
//
// // 等待当前工序完成
// try {
// currentFuture.get();
// } catch (Exception e) {
// e.printStackTrace();
// }
// i++;
// if(i==ops.size())
// {
// FileHelper.writeLogFile("使用并行处理 _e---"+machineId);
//
// }
// }
// });
//
// allMachineFutures.add(machineFuture);
// }
// 7. 改进的并行处理:只对工序少的设备并行,工序多的设备串行
Map<Integer, Boolean> opCompleted = new HashMap<>();
final Object lock = new Object();
List<Thread> threads = new ArrayList<>();
for (Map.Entry<Long, List<Entry>> entry : sortedMachineEntries) {
final Long machineId = entry.getKey();
final List<Entry> ops = entry.getValue();
// 工序超过500的设备直接在主线程串行处理
if (ops.size() > 500) {
// FileHelper.writeLogFile("设备 " + machineId + " 有 " + ops.size() + " 个工序,直接串行处理");
processMachineOps(chromosome, machineId, ops, dependencyGraph, opCompleted, lock,opMachineKeyMap,machineIdMap,machineTasksCache);
} else {
// 工序少的设备创建线程处理
Thread thread = new Thread(() -> {
processMachineOps(chromosome, machineId, ops, dependencyGraph, opCompleted, lock,opMachineKeyMap,machineIdMap,machineTasksCache);
});
thread.start();
threads.add(thread);
}
}
// 等待所有线程完成
for (Thread thread : threads) {
try {
thread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
// 9. 等待所有设备处理完成
// CompletableFuture.allOf(allMachineFutures.toArray(new CompletableFuture[0])).join();
if(chromosome.getReOrderids()!=null&&chromosome.getReOrderids().size()>0) {
chromosome.getOperationSequencing().removeIf(t -> chromosome.getReOrderids().contains(t));
}
calculateScheduleResult(chromosome);
}
/**
* 处理单个设备的工序
*/
private void processMachineOps(Chromosome chromosome, Long machineId, List<Entry> ops,
Map<Integer, List<Integer>> dependencyGraph,
Map<Integer, Boolean> opCompleted, Object lock,Map<String, OpMachine> opMachineKeyMap,Map<Long, Machine> machineIdMap,Map<Long, CopyOnWriteArrayList<GAScheduleResult>> machineTasksCache) {
//long machineStartTime = System.currentTimeMillis();
for (int i = 0; i < ops.size(); i++) {
Entry op = ops.get(i);
int opId = op.getId();
long opStartTime = System.currentTimeMillis();
// 获取当前工序的依赖
List<Integer> dependencies = dependencyGraph.getOrDefault(opId, Collections.emptyList());
// 等待所有依赖完成
boolean allDependenciesCompleted;
synchronized (lock) {
allDependenciesCompleted = true;
for (int depId : dependencies) {
if (!opCompleted.getOrDefault(depId, false)) {
allDependenciesCompleted = false;
break;
}
}
}
if (!allDependenciesCompleted) {
// 需要等待依赖
waitForDependencies(dependencies, opCompleted, lock);
}
String opMachineKey = op.getGroupId() + "_" + op.getSequence();
OpMachine machineOption = opMachineKeyMap.get(opMachineKey);
double processTime = machineOption.getProcessingTime();
// 处理当前工序
// long processStartTime = System.currentTimeMillis();
int actualEndTime = processOperation(op,machineId,processTime,machineOption,chromosome,machineIdMap,machineTasksCache);
// long processEndTime = System.currentTimeMillis();
// 标记工序完成
synchronized (lock) {
opCompleted.put(opId, true);
}
// long opEndTime = System.currentTimeMillis();
// if (i % 100 == 0 || i == ops.size() - 1) {
// FileHelper.writeLogFile("设备 " + machineId + " 工序 " + i + "/" + ops.size() +
// " 完成,总耗时:" + (opEndTime - machineStartTime) + "ms,本工序耗时:" + (opEndTime - opStartTime) + "ms");
// }
}
// long machineEndTime = System.currentTimeMillis();
// FileHelper.writeLogFile("设备 " + machineId + " 处理完成,总工序:" + ops.size() +
// ",总耗时:" + (machineEndTime - machineStartTime) + "ms");
}
/**
* 等待依赖工序完成
*/
private void waitForDependencies(List<Integer> dependencies, Map<Integer, Boolean> opCompleted, Object lock) {
while (true) {
boolean allCompleted;
synchronized (lock) {
allCompleted = true;
for (int depId : dependencies) {
if (!opCompleted.getOrDefault(depId, false)) {
allCompleted = false;
break;
}
}
if (allCompleted) {
break;
}
}
// 短暂休眠,避免CPU空转
try {
Thread.sleep(10);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
break;
}
}
}
/**
* 构建工序依赖图,只考虑通过 getPrevOperationId 定义的依赖关系
*/
private Map<Integer, List<Integer>> buildDependencyGraph(Chromosome chromosome) {
Map<Integer, List<Integer>> dependencyGraph = new HashMap<>();
// 只添加通过 getPrevOperationId 定义的依赖关系
for (Entry op : chromosome.getAllOperations()) {
int opId = op.getId();
List<Integer> dependencies = new ArrayList<>();
// 添加前序工序依赖(包括订单内和跨订单的依赖)
for (OperationDependency dep : op.getPrevEntryIds()) {
dependencies.add(dep.getPrevOperationId());
}
dependencyGraph.put(opId, dependencies);
}
return dependencyGraph;
}
/**
* 拓扑排序
*/
private List<Integer> topologicalSort(Map<Integer, List<Integer>> graph, Chromosome chromosome) {
List<Integer> result = new ArrayList<>();
Map<Integer, Integer> inDegree = new HashMap<>();
// 初始化入度
for (Integer node : graph.keySet()) {
inDegree.put(node, 0);
}
for (List<Integer> dependencies : graph.values()) {
for (Integer dep : dependencies) {
inDegree.put(dep, inDegree.getOrDefault(dep, 0) + 1);
}
}
// 获取订单处理顺序
List<Integer> operationSequencing = chromosome.getOperationSequencing();
// 构建订单ID到工序ID的映射
Map<Integer, List<Integer>> orderToOpIdsMap = new HashMap<>();
for (Entry op : chromosome.getAllOperations()) {
int groupId = op.getGroupId();
int opId = op.getId();
orderToOpIdsMap.computeIfAbsent(groupId, k -> new ArrayList<>()).add(opId);
}
// 按照 OperationSequencing 的顺序处理订单
for (int groupId : operationSequencing) {
List<Integer> opIds = orderToOpIdsMap.getOrDefault(groupId, Collections.emptyList());
// 处理当前订单的所有工序
Queue<Integer> queue = new LinkedList<>();
for (int opId : opIds) {
if (inDegree.getOrDefault(opId, 0) == 0) {
queue.offer(opId);
}
}
while (!queue.isEmpty()) {
Integer node = queue.poll();
result.add(node);
if (graph.containsKey(node)) {
for (Integer neighbor : graph.get(node)) {
int newInDegree = inDegree.get(neighbor) - 1;
inDegree.put(neighbor, newInDegree);
if (newInDegree == 0 && opIds.contains(neighbor)) {
queue.offer(neighbor);
}
}
}
}
}
return result;
}
/**
* 根据工序ID查找工序
*/
private Entry findOperationById(Chromosome chromosome, int opId) {
for (Entry op : chromosome.getAllOperations()) {
if (op.getId() == opId) {
return op;
}
}
return null;
}
private int processOperation(Entry currentOp,Long machineId,double processTime,OpMachine machineOption,Chromosome chromosome,Map<Long, Machine> machineIdMap,Map<Long, CopyOnWriteArrayList<GAScheduleResult>> machineTasksCache)
{
Machine targetMachine = machineIdMap.get(machineId);
int prevtime = 0;
//后处理时间
int teardownTime = currentOp.getTeardownTime();
if (!currentOp.getPrevEntryIds().isEmpty()) {
// 处理多个前工序
prevtime= CalPrevtime( prevtime, currentOp, chromosome, processTime, targetMachine);
}
int bomtime = getOperationBOMTime(currentOp,chromosome);
int prevendtime=prevtime;
prevtime = Math.max(prevtime, bomtime);
Machine machine = machineIdMap.get(machineId);
int actualEndTime = processWithSingleMachine(currentOp, machine, processTime, prevtime,machineOption, chromosome,false,prevendtime,machineTasksCache);
return actualEndTime;
}
private int processWithSingleMachine(Entry operation, Machine machine, double processingTime, private int processWithSingleMachine(Entry operation, Machine machine, double processingTime,
int prevOperationEndTime,OpMachine machineOption, Chromosome chromosome,boolean calbom,int prevendtime) { int prevOperationEndTime,OpMachine machineOption, Chromosome chromosome,boolean calbom,int prevendtime,Map<Long, CopyOnWriteArrayList<GAScheduleResult>> machineTasksCache) {
int processingTimeTotal=0; int processingTimeTotal=0;
int earliestStartTime = prevOperationEndTime; int earliestStartTime = prevOperationEndTime;
if(operation.getConstTime()==1)//常数时间 if(operation.getConstTime()==1)//常数时间
...@@ -551,12 +1144,16 @@ if(finishedOrder==null||finishedOrder.size()==0) ...@@ -551,12 +1144,16 @@ if(finishedOrder==null||finishedOrder.size()==0)
} }
int setupTime=0; int setupTime=0;
CopyOnWriteArrayList<GAScheduleResult> machineTasks;
CopyOnWriteArrayList<GAScheduleResult> machineTasks =chromosome.getResult().stream() if (machineTasksCache.containsKey(machine.getId())) {
.filter(t -> t.getMachineId() == machine.getId()) machineTasks = machineTasksCache.get(machine.getId());
.sorted(Comparator.comparingInt(GAScheduleResult::getStartTime)) } else {
.collect(Collectors.toCollection(CopyOnWriteArrayList::new)); machineTasks = chromosome.getResult().stream()
.filter(t -> t.getMachineId() == machine.getId())
.sorted(Comparator.comparingInt(GAScheduleResult::getStartTime))
.collect(Collectors.toCollection(CopyOnWriteArrayList::new));
machineTasksCache.put(machine.getId(), machineTasks);
}
GAScheduleResult lastGeneOnMachine = null; GAScheduleResult lastGeneOnMachine = null;
if(machineTasks!=null&&machineTasks.size()>0) if(machineTasks!=null&&machineTasks.size()>0)
...@@ -595,7 +1192,7 @@ if(finishedOrder==null||finishedOrder.size()==0) ...@@ -595,7 +1192,7 @@ if(finishedOrder==null||finishedOrder.size()==0)
: earliestStartTime; : earliestStartTime;
} }
bomtime= EditOperationBOMTime(operation,chromosome,earliestStartTime); bomtime= EditOperationBOMTime(operation,chromosome,earliestStartTime,machineTasksCache);
if(bomtime>prevendtime&&bomtime<earliestStartTimeold) if(bomtime>prevendtime&&bomtime<earliestStartTimeold)
...@@ -610,7 +1207,7 @@ if(finishedOrder==null||finishedOrder.size()==0) ...@@ -610,7 +1207,7 @@ if(finishedOrder==null||finishedOrder.size()==0)
.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);
if(machineTasks!=null&&machineTasks.size()>0&&_globalParam.is_smoothChangeOver()) if(machineTasks!=null&&machineTasks.size()>0&&_globalParam.is_smoothChangeOver())
{ {
...@@ -747,7 +1344,7 @@ if(finishedOrder==null||finishedOrder.size()==0) ...@@ -747,7 +1344,7 @@ if(finishedOrder==null||finishedOrder.size()==0)
// 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());
machineTasksCache.remove(machine.getId());
return endTime; return endTime;
} }
...@@ -931,7 +1528,7 @@ if(finishedOrder==null||finishedOrder.size()==0) ...@@ -931,7 +1528,7 @@ if(finishedOrder==null||finishedOrder.size()==0)
return Math.max(rawTime, sfTime); return Math.max(rawTime, sfTime);
} }
private int EditOperationBOMTime(Entry currentOp, Chromosome chromosome,int earliestStartTime) { private int EditOperationBOMTime(Entry currentOp, Chromosome chromosome,int earliestStartTime,Map<Long, CopyOnWriteArrayList<GAScheduleResult>> machineTasksCache) {
List<OrderMaterialRequirement> opboms= currentOp.getMaterialRequirements(); List<OrderMaterialRequirement> opboms= currentOp.getMaterialRequirements();
...@@ -940,18 +1537,19 @@ if(finishedOrder==null||finishedOrder.size()==0) ...@@ -940,18 +1537,19 @@ if(finishedOrder==null||finishedOrder.size()==0)
return 0; return 0;
} }
LocalDateTime earliestStartTime1=baseTime.plusSeconds(earliestStartTime); LocalDateTime earliestStartTime1=baseTime.plusSeconds(earliestStartTime);
materialRequirementService.EditOperationBOM(currentOp,chromosome,earliestStartTime1,this); materialRequirementService.EditOperationBOM(currentOp,chromosome,earliestStartTime1,this,machineTasksCache);
return getOperationBOMTime(currentOp, chromosome); return getOperationBOMTime(currentOp, chromosome);
} }
public void EditorderOperation(Chromosome chromosome, int groupId,double needed){ public void EditorderOperation(Chromosome chromosome, int groupId,double needed,Map<Long, CopyOnWriteArrayList<GAScheduleResult>> machineTasksCache){
List<Entry> orderOps = chromosome.getAllOperations().stream() List<Entry> orderOps = chromosome.getAllOperations().stream()
.filter(t -> t.getGroupId() == groupId) .filter(t -> t.getGroupId() == groupId)
.sorted(Comparator.comparing(Entry::getSequence)) .sorted(Comparator.comparing(Entry::getSequence))
.collect(Collectors.toList()); .collect(Collectors.toList());
for (Entry currentOp : orderOps) { for (Entry currentOp : orderOps) {
if(currentOp.isNewCreate()) { if(currentOp.isNewCreate()) {
...@@ -1002,8 +1600,8 @@ return getOperationBOMTime(currentOp, chromosome); ...@@ -1002,8 +1600,8 @@ return getOperationBOMTime(currentOp, chromosome);
.filter(m -> m.getId() == machineId) .filter(m -> m.getId() == machineId)
.findFirst() .findFirst()
.orElse(null); .orElse(null);
// 缓存机器任务
int actualEndTime = processWithSingleMachine(currentOp, machine, processTime, prevtime,opMachine, chromosome,true,prevendtime); int actualEndTime = processWithSingleMachine(currentOp, machine, processTime, prevtime,opMachine, chromosome,true,prevendtime,machineTasksCache);
} }
......
...@@ -1140,7 +1140,7 @@ if(headers1==null) ...@@ -1140,7 +1140,7 @@ if(headers1==null)
* @return 包含物料需求列表和子订单列表的结果对象(替代C#的out参数) * @return 包含物料需求列表和子订单列表的结果对象(替代C#的out参数)
*/ */
public void EditOperationBOM(Entry operation,Chromosome chromosome,LocalDateTime earliestStartTime,GeneticDecoder coder) { public void EditOperationBOM(Entry operation,Chromosome chromosome,LocalDateTime earliestStartTime,GeneticDecoder coder,Map<Long, CopyOnWriteArrayList<GAScheduleResult>> machineTasksCache) {
List<OrderMaterialRequirement> materialRequirements = new ArrayList<>(); List<OrderMaterialRequirement> materialRequirements = new ArrayList<>();
String sceneId=chromosome.getScenarioID(); String sceneId=chromosome.getScenarioID();
...@@ -1319,7 +1319,7 @@ if(headers1==null) ...@@ -1319,7 +1319,7 @@ if(headers1==null)
for (Integer orderid : orderids) { for (Integer orderid : orderids) {
coder.ClearorderOperationResult(chromosome, orderid); coder.ClearorderOperationResult(chromosome, orderid);
coder.EditorderOperation(chromosome, orderid, needed); coder.EditorderOperation(chromosome, orderid, needed,machineTasksCache);
} }
}else { }else {
......
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