Commit ad57430d authored by Tong Li's avatar Tong Li

解码优化

parent 25c58c5b
......@@ -473,12 +473,15 @@ if(finishedOrder==null||finishedOrder.size()==0)
Map<Integer, Integer> orderLastEndTime = new HashMap<>();
Map<Integer, Entry> entryIndexById = new HashMap<>();
Map<Integer, List<Entry>> entrysBygroupId = new HashMap<>();
Map<Integer, GAScheduleResult> scheduleIndexById = new HashMap<>();
for (Entry op : allOperations) {
int groupId = op.getGroupId();
orderProcessCounter.putIfAbsent(groupId, 0);
orderLastEndTime.putIfAbsent(groupId, 0);
entryIndexById.put(op.getId(),op);
entrysBygroupId.computeIfAbsent(groupId, k -> new ArrayList<>()).add(op);
//scheduleIndexById.put(op.getId(),null);
}
// Map<Long, String> machineState = chromosome.getMachines().stream()
......@@ -487,9 +490,7 @@ if(finishedOrder==null||finishedOrder.size()==0)
// List<Entry> allScheduledOps = new ArrayList<>();
// 缓存机器任务
Map<Long, CopyOnWriteArrayList<GAScheduleResult>> machineTasksCache = new HashMap<>();
for (Entry op : allOperations) {
}
for (int groupId : chromosome.getOperationSequencing()) {
int scheduledCount = orderProcessCounter.get(groupId);
List<Entry> orderOps = entrysBygroupId.get(groupId).stream()
......@@ -555,7 +556,7 @@ if(finishedOrder==null||finishedOrder.size()==0)
// Machine machine = machineIdMap.get(machineId);
// int changeoverTime =0; //(lastDiscreteParameter.isEmpty() ||
// lastDiscreteParameter.equals(currentOp.getDiscreteParameter())) ? 0 : 0;
int actualEndTime = processOperation(currentOp,machineId,processTime,machineOption,chromosome,machineIdMap,machineTasksCache);
int actualEndTime = processOperation(currentOp,machineId,processTime,machineOption,chromosome,machineIdMap,machineTasksCache,entryIndexById,scheduleIndexById);
// int actualEndTime = processWithSingleMachine(currentOp, machine, processTime, prevtime,machineOption, chromosome,false,prevendtime,machineTasksCache);
orderProcessCounter.put(groupId, orderProcessCounter.get(groupId) + 1);
......@@ -570,131 +571,7 @@ if(finishedOrder==null||finishedOrder.size()==0)
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));
// 构建工序ID索引:opId -> Entry(O(1)查找)
Map<Integer, Entry> opIdIndex = buildOpIdIndex(chromosome);
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);
Entry op = opIdIndex.get(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);
Entry op = opIdIndex.get(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();
......@@ -748,9 +625,15 @@ if(finishedOrder==null||finishedOrder.size()==0)
// 初始化订单处理计数器
Map<Integer, Integer> orderProcessCounter = new HashMap<>();
Map<Integer, Entry> entryIndexById = new HashMap<>();
Map<Integer, List<Entry>> entrysBygroupId = new HashMap<>();
Map<Integer, GAScheduleResult> scheduleIndexById= new HashMap<>();
for (Entry op : allOperations) {
int groupId = op.getGroupId();
orderProcessCounter.putIfAbsent(groupId, 0);
entryIndexById.put(op.getId(),op);
entrysBygroupId.computeIfAbsent(groupId, k -> new ArrayList<>()).add(op);
}
Map<Long, List<Entry>> machineToOpsMap = new HashMap<>();
//按照 OperationSequencing 顺序生成 machineToOpsMap
......@@ -886,11 +769,11 @@ if(finishedOrder==null||finishedOrder.size()==0)
// 工序超过500的设备直接在主线程串行处理
if (ops.size() > 500) {
// FileHelper.writeLogFile("设备 " + machineId + " 有 " + ops.size() + " 个工序,直接串行处理");
processMachineOps(chromosome, machineId, ops, dependencyGraph, opCompleted, lock, opMachineKeyMap, machineIdMap, machineTasksCache);
processMachineOps(chromosome, machineId, ops, dependencyGraph, opCompleted, lock, opMachineKeyMap, machineIdMap, machineTasksCache, entryIndexById,scheduleIndexById);
} else {
// 工序少的设备创建线程处理
Thread thread = new Thread(() -> {
processMachineOps(chromosome, machineId, ops, dependencyGraph, opCompleted, lock, opMachineKeyMap, machineIdMap, machineTasksCache);
processMachineOps(chromosome, machineId, ops, dependencyGraph, opCompleted, lock, opMachineKeyMap, machineIdMap, machineTasksCache, entryIndexById,scheduleIndexById);
});
thread.start();
threads.add(thread);
......@@ -920,7 +803,7 @@ if(finishedOrder==null||finishedOrder.size()==0)
*/
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) {
Map<Integer, Boolean> opCompleted, Object lock,Map<String, OpMachine> opMachineKeyMap,Map<Long, Machine> machineIdMap,Map<Long, CopyOnWriteArrayList<GAScheduleResult>> machineTasksCache,Map<Integer, Entry> entryIndexById,Map<Integer, GAScheduleResult> scheduleIndexById) {
//long machineStartTime = System.currentTimeMillis();
for (int i = 0; i < ops.size(); i++) {
......@@ -956,7 +839,7 @@ if(finishedOrder==null||finishedOrder.size()==0)
// 处理当前工序
// long processStartTime = System.currentTimeMillis();
int actualEndTime = processOperation(op,machineId,processTime,machineOption,chromosome,machineIdMap,machineTasksCache);
int actualEndTime = processOperation(op,machineId,processTime,machineOption,chromosome,machineIdMap,machineTasksCache, entryIndexById,scheduleIndexById);
// long processEndTime = System.currentTimeMillis();
......@@ -1114,7 +997,7 @@ if(finishedOrder==null||finishedOrder.size()==0)
private int processOperation(Entry currentOp,Long machineId,double processTime,OpMachine machineOption,Chromosome chromosome,Map<Long, Machine> machineIdMap,Map<Long, CopyOnWriteArrayList<GAScheduleResult>> machineTasksCache)
private int processOperation(Entry currentOp,Long machineId,double processTime,OpMachine machineOption,Chromosome chromosome,Map<Long, Machine> machineIdMap,Map<Long, CopyOnWriteArrayList<GAScheduleResult>> machineTasksCache,Map<Integer, Entry> entryIndexById,Map<Integer, GAScheduleResult> scheduleIndexById)
{
Machine targetMachine = machineIdMap.get(machineId);
......@@ -1123,7 +1006,7 @@ if(finishedOrder==null||finishedOrder.size()==0)
int teardownTime = currentOp.getTeardownTime();
if (!currentOp.getPrevEntryIds().isEmpty()) {
// 处理多个前工序
prevtime= CalPrevtime( prevtime, currentOp, chromosome, processTime, targetMachine);
prevtime= CalPrevtime( prevtime, currentOp, chromosome, processTime, targetMachine,entryIndexById, scheduleIndexById);
}
int bomtime = getOperationBOMTime(currentOp,chromosome);
......@@ -1131,14 +1014,14 @@ if(finishedOrder==null||finishedOrder.size()==0)
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);
int actualEndTime = processWithSingleMachine(currentOp, machine, processTime, prevtime,machineOption, chromosome,false,prevendtime,machineTasksCache,entryIndexById, scheduleIndexById);
return actualEndTime;
}
private int processWithSingleMachine(Entry operation, Machine machine, double processingTime,
int prevOperationEndTime,OpMachine machineOption, Chromosome chromosome,boolean calbom,int prevendtime,Map<Long, CopyOnWriteArrayList<GAScheduleResult>> machineTasksCache) {
int prevOperationEndTime,OpMachine machineOption, Chromosome chromosome,boolean calbom,int prevendtime,Map<Long, CopyOnWriteArrayList<GAScheduleResult>> machineTasksCache,Map<Integer, Entry> entryIndexById,Map<Integer, GAScheduleResult> scheduleIndexById) {
int processingTimeTotal=0;
int earliestStartTime = prevOperationEndTime;
if(operation.getConstTime()==1)//常数时间
......@@ -1239,7 +1122,7 @@ return actualEndTime;
: earliestStartTime;
}
bomtime= EditOperationBOMTime(operation,chromosome,earliestStartTime,machineTasksCache);
bomtime= EditOperationBOMTime(operation,chromosome,earliestStartTime,machineTasksCache, entryIndexById, scheduleIndexById);
if(bomtime>prevendtime&&bomtime<earliestStartTimeold)
......@@ -1394,7 +1277,7 @@ return actualEndTime;
if (machineTasks != null) {
machineTasks.add(result);
}
scheduleIndexById.put(operation.getId(),result);
return endTime;
}
......@@ -1405,16 +1288,18 @@ return actualEndTime;
* @param chromosome
* @return
*/
private int CalPrevtime(int prevtime,Entry currentOp,Chromosome chromosome,double processTime,Machine machine) {
private int CalPrevtime(int prevtime,Entry currentOp,Chromosome chromosome,double processTime,Machine machine,Map<Integer, Entry> entryIndexById,Map<Integer, GAScheduleResult> scheduleIndexById) {
List<OperationDependency> FsOperations = currentOp.getPrevEntryIds().stream()
.filter(t -> t.getDependencyType() == DependencyType.FinishToStart)
.collect(Collectors.toList());//串行
if (FsOperations != null && FsOperations.size() > 0) {
for (OperationDependency opid : FsOperations) {
List<GAScheduleResult> prevOperations = chromosome.getResult().stream()
.filter(t -> t.getGroupId() == currentOp.getGroupId() && t.getOperationId() == opid.getPrevOperationId())
.collect(Collectors.toList());//多台
for (GAScheduleResult prevOp : prevOperations) {
// List<GAScheduleResult> prevOperations = chromosome.getResult().stream()
// .filter(t -> t.getOperationId() == opid.getPrevOperationId())
// .collect(Collectors.toList());//
GAScheduleResult prevOp= scheduleIndexById.get(opid.getPrevOperationId());
// for (GAScheduleResult prevOp : prevOperations) {
if(prevOp!=null){
//加上后处理时间
prevtime = Math.max(prevtime, prevOp.getEndTime() + currentOp.getTeardownTime());
}
......@@ -1431,10 +1316,13 @@ return actualEndTime;
for (int j=0;j<SSOperations.size();j++)
{
OperationDependency opid=SSOperations.get(j);
List<GAScheduleResult> prevOperations = chromosome.getResult().stream()
.filter(t -> t.getGroupId() == currentOp.getGroupId() && t.getOperationId() == opid.getPrevOperationId())
.collect(Collectors.toList());//多台
for (GAScheduleResult prevOp : prevOperations) {
// List<GAScheduleResult> prevOperations = chromosome.getResult().stream()
// .filter(t -> t.getOperationId() == opid.getPrevOperationId())
// .collect(Collectors.toList());//多台
GAScheduleResult prevOp= scheduleIndexById.get(opid.getPrevOperationId());
// for (GAScheduleResult prevOp : prevOperations) {
if(prevOp!=null){
newScheduleResult.add(prevOp);
newScheduleResultDetails.addAll(prevOp.getGeneDetails());
}
......@@ -1444,15 +1332,17 @@ return actualEndTime;
prevtime = Math.max(prevtime, prevtime1);
}else {
Entry entry= chromosome.getAllOperations().stream()
.filter(t->t.getId()==opid.getPrevOperationId())
.findFirst().orElse(null);
// Entry entry= chromosome.getAllOperations().stream()
// .filter(t->t.getId()==opid.getPrevOperationId())
// .findFirst().orElse(null);
Entry entry=entryIndexById.get(opid.getPrevOperationId());
OperationDependency opid2=SSOperations.get(j+1);
Entry entry1= chromosome.getAllOperations().stream()
.filter(t->t.getId()==opid2.getPrevOperationId())
.findFirst().orElse(null);
if(entry.getRoutingDetailId()!=entry1.getRoutingDetailId())
// Entry entry1= chromosome.getAllOperations().stream()
// .filter(t->t.getId()==opid2.getPrevOperationId())
// .findFirst().orElse(null);
Entry entry1=entryIndexById.get(opid2.getPrevOperationId());
//不是同一前工序,效率不能合并 newScheduleResult 清空,如何是一个工序就合并计算
if(entry!=null&&entry1!=null&&entry.getRoutingDetailId()!=entry1.getRoutingDetailId())
{
int prevtime1 = CalSSPrevtime(newScheduleResult,newScheduleResultDetails, prevtime, currentOp, chromosome, processTime, machine);
......@@ -1577,7 +1467,7 @@ return actualEndTime;
return Math.max(rawTime, sfTime);
}
private int EditOperationBOMTime(Entry currentOp, Chromosome chromosome,int earliestStartTime,Map<Long, CopyOnWriteArrayList<GAScheduleResult>> machineTasksCache) {
private int EditOperationBOMTime(Entry currentOp, Chromosome chromosome,int earliestStartTime,Map<Long, CopyOnWriteArrayList<GAScheduleResult>> machineTasksCache,Map<Integer, Entry> entryIndexById,Map<Integer, GAScheduleResult> scheduleIndexById) {
List<OrderMaterialRequirement> opboms= currentOp.getMaterialRequirements();
......@@ -1586,12 +1476,12 @@ return actualEndTime;
return 0;
}
LocalDateTime earliestStartTime1=baseTime.plusSeconds(earliestStartTime);
materialRequirementService.EditOperationBOM(currentOp,chromosome,earliestStartTime1,this,machineTasksCache);
materialRequirementService.EditOperationBOM(currentOp,chromosome,earliestStartTime1,this,machineTasksCache, entryIndexById, scheduleIndexById);
return getOperationBOMTime(currentOp, chromosome);
}
public void EditorderOperation(Chromosome chromosome, int groupId,double needed,Map<Long, CopyOnWriteArrayList<GAScheduleResult>> machineTasksCache){
public void EditorderOperation(Chromosome chromosome, int groupId,double needed,Map<Long, CopyOnWriteArrayList<GAScheduleResult>> machineTasksCache,Map<Integer, Entry> entryIndexById,Map<Integer, GAScheduleResult> scheduleIndexById){
List<Entry> orderOps = chromosome.getAllOperations().stream()
.filter(t -> t.getGroupId() == groupId)
.sorted(Comparator.comparing(Entry::getSequence))
......@@ -1635,7 +1525,7 @@ return getOperationBOMTime(currentOp, chromosome);
int teardownTime = currentOp.getTeardownTime();
if (!currentOp.getPrevEntryIds().isEmpty()) {
// 处理多个前工序
prevtime= CalPrevtime( prevtime, currentOp, chromosome, processTime, targetMachine);
prevtime= CalPrevtime( prevtime, currentOp, chromosome, processTime, targetMachine, entryIndexById,scheduleIndexById);
}
// 上个离散参数
......@@ -1650,7 +1540,7 @@ return getOperationBOMTime(currentOp, chromosome);
.findFirst()
.orElse(null);
// 缓存机器任务
int actualEndTime = processWithSingleMachine(currentOp, machine, processTime, prevtime,opMachine, chromosome,true,prevendtime,machineTasksCache);
int actualEndTime = processWithSingleMachine(currentOp, machine, processTime, prevtime,opMachine, chromosome,true,prevendtime,machineTasksCache, entryIndexById, scheduleIndexById);
}
......
......@@ -1140,7 +1140,7 @@ if(headers1==null)
* @return 包含物料需求列表和子订单列表的结果对象(替代C#的out参数)
*/
public void EditOperationBOM(Entry operation,Chromosome chromosome,LocalDateTime earliestStartTime,GeneticDecoder coder,Map<Long, CopyOnWriteArrayList<GAScheduleResult>> machineTasksCache) {
public void EditOperationBOM(Entry operation,Chromosome chromosome,LocalDateTime earliestStartTime,GeneticDecoder coder,Map<Long, CopyOnWriteArrayList<GAScheduleResult>> machineTasksCache,Map<Integer, Entry> entryIndexById,Map<Integer, GAScheduleResult> scheduleIndexById) {
List<OrderMaterialRequirement> materialRequirements = new ArrayList<>();
String sceneId=chromosome.getScenarioID();
......@@ -1319,7 +1319,7 @@ if(headers1==null)
for (Integer orderid : orderids) {
coder.ClearorderOperationResult(chromosome, orderid);
coder.EditorderOperation(chromosome, orderid, needed,machineTasksCache);
coder.EditorderOperation(chromosome, orderid, needed,machineTasksCache, entryIndexById, scheduleIndexById);
}
}else {
......
......@@ -222,7 +222,7 @@ public class PlanResultService {
lockedOrderProcessorService.markLockedOrdersOccupiedTime(machines, timeConfig.getBaseTime());
// 5. 执行调度算法
GeneticAlgorithm scheduler =new GeneticAlgorithm(globalParam,machines,orders,Materials1,materialIds,machineScheduler,entryRel,materialRequirementService,_sceneService,SceneId); //new GeneticAlgorithm(products, machines, orders, machineScheduler);
HybridAlgorithm scheduler =new HybridAlgorithm(globalParam,machines,orders,Materials1,materialIds,machineScheduler,entryRel,materialRequirementService,_sceneService,SceneId); //new GeneticAlgorithm(products, machines, orders, machineScheduler);
param.initAdaptiveParams(entrys.size());
double[] customWeights = new double[] { 0.4, 0.1, 0.1, 0.1, 0.3 }; // 延迟时间权重提升到0.5
//完工时间、总流程时间、总换型时间、机器负载标准差、延迟时间
......
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