Commit 08991d0b authored by Tong Li's avatar Tong Li

设备日历生成太多

parent c7e03b35
...@@ -68,15 +68,15 @@ public class Initialization { ...@@ -68,15 +68,15 @@ public class Initialization {
int gsCount = (int) (param.getPopulationSize() * param.getGsRatio()); int gsCount = (int) (param.getPopulationSize() * param.getGsRatio());
int lsCount =gsCount+ (int) (param.getPopulationSize() * param.getLsRatio()); int lsCount =gsCount+ (int) (param.getPopulationSize() * param.getLsRatio());
int rsCount = param.getPopulationSize() - gsCount - lsCount; int rsCount = param.getPopulationSize() - gsCount - lsCount;
int populationSize=param.getPopulationSize(); int populationSize=param.getPopulationSize();
// 并行循环:对应 Parallel.For(0, PopulationSize, i => { ... }) // 并行循环:对应 Parallel.For(0, PopulationSize, i => { ... })
IntStream.range(0, populationSize) IntStream.range(0, populationSize)
.parallel() // 开启并行 .parallel() // 开启并行
.forEach(i -> { .forEach(i -> {
Chromosome chromo = new Chromosome(); // 初始化染色体 Chromosome chromo = new Chromosome(); // 初始化染色体
// chromo.setObjectiveWeights(_objectiveWeights); // chromo.setObjectiveWeights(_objectiveWeights);
// chromo.setInitMachines(ProductionDeepCopyUtil.deepCopyList(machines)); // chromo.setInitMachines(ProductionDeepCopyUtil.deepCopyList(machines));
chromo.setOrders(new CopyOnWriteArrayList<>(orders)); chromo.setOrders(new CopyOnWriteArrayList<>(orders));
// 全局选择(GS):按GlobalOpId顺序生成MachineSelection // 全局选择(GS):按GlobalOpId顺序生成MachineSelection
if (i < gsCount) { if (i < gsCount) {
chromo.setGsOrls(1); chromo.setGsOrls(1);
...@@ -132,7 +132,7 @@ chromo.setOrders(new CopyOnWriteArrayList<>(orders)); ...@@ -132,7 +132,7 @@ chromo.setOrders(new CopyOnWriteArrayList<>(orders));
Map<Long, Double> machineLoad = new HashMap<>(); Map<Long, Double> machineLoad = new HashMap<>();
// int[] machineLoad = new int[machineCount + 1]; // 设备负载(1-based,设备ID从1开始) // int[] machineLoad = new int[machineCount + 1]; // 设备负载(1-based,设备ID从1开始)
List<Integer> ms = new ArrayList<>(); // MachineSelection(顺序=GlobalOpId顺序) List<Integer> ms = new ArrayList<>(); // MachineSelection(顺序=GlobalOpId顺序)
List<Integer> os = new ArrayList<>(); // OperationSequencing List<Integer> os = new ArrayList<>(); // OperationSequencing
List<Integer> osp = new ArrayList<>(); // 相同优先级OperationSequencing List<Integer> osp = new ArrayList<>(); // 相同优先级OperationSequencing
...@@ -259,7 +259,7 @@ chromo.setOrders(new CopyOnWriteArrayList<>(orders)); ...@@ -259,7 +259,7 @@ chromo.setOrders(new CopyOnWriteArrayList<>(orders));
int machineSeq = index.orElse(0) + 1; int machineSeq = index.orElse(0) + 1;
ms.add(machineSeq); ms.add(machineSeq);
double maLoad= machineLoad.getOrDefault(minLoadMachine.getMachineId(),(double)0); double maLoad= machineLoad.getOrDefault(minLoadMachine.getMachineId(),(double)0);
// 更新设备负载 // 更新设备负载
machineLoad.put(minLoadMachine.getMachineId(), machineLoad.put(minLoadMachine.getMachineId(),
maLoad+ minLoadMachine.getProcessingTime()); maLoad+ minLoadMachine.getProcessingTime());
...@@ -347,13 +347,16 @@ chromo.setOrders(new CopyOnWriteArrayList<>(orders)); ...@@ -347,13 +347,16 @@ chromo.setOrders(new CopyOnWriteArrayList<>(orders));
List<Chromosome> population = new ArrayList<>(); List<Chromosome> population = new ArrayList<>();
int populationSize = param.getPopulationSize(); int populationSize = param.getPopulationSize();
this.baseTime=param.getBaseTime(); this.baseTime=param.getBaseTime();
// 按比例生成不同启发式规则的个体 // 按比例生成不同启发式规则的个体(优化:增加混合策略和瓶颈优先)
int sptCount = (int) (populationSize * 0.2); int sptCount = (int) (populationSize * 0.15);
int lptCount = sptCount + (int) (populationSize * 0.1); int eddsptCount = sptCount + (int) (populationSize * 0.15);
int eddCount = lptCount + (int) (populationSize * 0.2); int eddCount = eddsptCount + (int) (populationSize * 0.15);
int crCount = eddCount + (int) (populationSize * 0.2); int bottleneckCount = eddCount + (int) (populationSize * 0.15);
int sstCount = crCount + (int) (populationSize * 0.2); int sstCount = bottleneckCount + (int) (populationSize * 0.15);
int lsCount = populationSize - sstCount; int crCount = sstCount + (int) (populationSize * 0.1);
int lptCount = crCount + (int) (populationSize * 0.1);
int lsCount = populationSize - lptCount;
IntStream.range(0, populationSize) IntStream.range(0, populationSize)
.parallel() .parallel()
.forEach(i -> { .forEach(i -> {
...@@ -364,23 +367,31 @@ chromo.setOrders(new CopyOnWriteArrayList<>(orders)); ...@@ -364,23 +367,31 @@ chromo.setOrders(new CopyOnWriteArrayList<>(orders));
// SPT规则 // SPT规则
chromo.setGenerateType("SPT"); chromo.setGenerateType("SPT");
generateChromosomeByType(chromo, 1); generateChromosomeByType(chromo, 1);
} else if (i < lptCount) { } else if (i < eddsptCount) {
// LPT规则 // EDD+SPT混合策略
chromo.setGenerateType("LPT"); chromo.setGenerateType("EDD+SPT");
generateChromosomeByType(chromo, 2); generateEDDSPTChromosome(chromo);
} else if (i < eddCount) { } else if (i < eddCount) {
// EDD规则 // EDD规则
chromo.setGenerateType("EDD"); chromo.setGenerateType("EDD");
generateChromosomeByType(chromo, 3); generateChromosomeByType(chromo, 3);
} else if (i < bottleneckCount) {
// 瓶颈优先策略
chromo.setGenerateType("BottleneckFirst");
generateBottleneckFirstChromosome(chromo);
} else if (i < sstCount) {
// SST规则(已有物料排序)
chromo.setGenerateType("SST");
generateSSTChromosome(chromo);
} else if (i < crCount) { } else if (i < crCount) {
// CR规则 // CR规则
chromo.setGenerateType("CR"); chromo.setGenerateType("CR");
generateCRChromosome(chromo); generateCRChromosome(chromo);
} else if (i < sstCount) { } else if (i < lptCount) {
// SST规则 // LPT规则
chromo.setGenerateType("SST"); chromo.setGenerateType("LPT");
generateSSTChromosome(chromo); generateChromosomeByType(chromo, 2);
}else { } else {
// 随机规则 // 随机规则
chromo.setGenerateType("LS"); chromo.setGenerateType("LS");
generateLsChromosome(chromo); generateLsChromosome(chromo);
...@@ -393,7 +404,7 @@ chromo.setOrders(new CopyOnWriteArrayList<>(orders)); ...@@ -393,7 +404,7 @@ chromo.setOrders(new CopyOnWriteArrayList<>(orders));
} }
/** /**
* SPT(最短加工时间) * SPT(最短加工时间)
*/ */
private Chromosome generateChromosomeByType(Chromosome chromosome,int sortType) { private Chromosome generateChromosomeByType(Chromosome chromosome,int sortType) {
...@@ -425,6 +436,7 @@ chromo.setOrders(new CopyOnWriteArrayList<>(orders)); ...@@ -425,6 +436,7 @@ chromo.setOrders(new CopyOnWriteArrayList<>(orders));
if (considerSequence) { if (considerSequence) {
sortedOps.sort(Comparator.comparing((Entry op) -> op.getPriority()) sortedOps.sort(Comparator.comparing((Entry op) -> op.getPriority())
.thenComparing(Entry::getSequence) .thenComparing(Entry::getSequence)
.thenComparing(op -> op.getProductId() != null ? op.getProductId() : "") // 相同物料排在一起,减少换型
.thenComparing(op -> { .thenComparing(op -> {
if (op.getMachineOptions() == null || op.getMachineOptions().isEmpty()) { if (op.getMachineOptions() == null || op.getMachineOptions().isEmpty()) {
return sortType == 1 ? 0.0 : Double.MAX_VALUE; // 空值默认排最前/最后 return sortType == 1 ? 0.0 : Double.MAX_VALUE; // 空值默认排最前/最后
...@@ -436,7 +448,7 @@ chromo.setOrders(new CopyOnWriteArrayList<>(orders)); ...@@ -436,7 +448,7 @@ chromo.setOrders(new CopyOnWriteArrayList<>(orders));
} }
else{ else{
sortedOps.sort(Comparator.comparing((Entry op) -> op.getPriority()) sortedOps.sort(Comparator.comparing((Entry op) -> op.getPriority())
.thenComparing(op -> op.getProductId() != null ? op.getProductId() : "") // 相同物料排在一起,减少换型
.thenComparing(op -> { .thenComparing(op -> {
if (op.getMachineOptions() == null || op.getMachineOptions().isEmpty()) { if (op.getMachineOptions() == null || op.getMachineOptions().isEmpty()) {
return sortType == 1 ? 0.0 : Double.MAX_VALUE; // 空值默认排最前/最后 return sortType == 1 ? 0.0 : Double.MAX_VALUE; // 空值默认排最前/最后
...@@ -451,12 +463,13 @@ chromo.setOrders(new CopyOnWriteArrayList<>(orders)); ...@@ -451,12 +463,13 @@ chromo.setOrders(new CopyOnWriteArrayList<>(orders));
if (considerSequence) { if (considerSequence) {
sortedOps.sort(Comparator.comparing((Entry op) -> op.getPriority()) sortedOps.sort(Comparator.comparing((Entry op) -> op.getPriority())
.thenComparing(Entry::getSequence) .thenComparing(Entry::getSequence)
.thenComparing(op -> op.getProductId() != null ? op.getProductId() : "") // 相同物料排在一起,减少换型
.thenComparing(op -> dueDateMap.get(op.getGroupId()), .thenComparing(op -> dueDateMap.get(op.getGroupId()),
Comparator.nullsLast(Comparator.naturalOrder())) Comparator.nullsLast(Comparator.naturalOrder()))
.thenComparing(randomIds::get)); .thenComparing(randomIds::get));
}else { }else {
sortedOps.sort(Comparator.comparing((Entry op) -> op.getPriority()) sortedOps.sort(Comparator.comparing((Entry op) -> op.getPriority())
.thenComparing(op -> op.getProductId() != null ? op.getProductId() : "") // 相同物料排在一起,减少换型
.thenComparing(op -> dueDateMap.get(op.getGroupId()), .thenComparing(op -> dueDateMap.get(op.getGroupId()),
Comparator.nullsLast(Comparator.naturalOrder())) Comparator.nullsLast(Comparator.naturalOrder()))
.thenComparing(randomIds::get)); .thenComparing(randomIds::get));
...@@ -551,6 +564,7 @@ chromo.setOrders(new CopyOnWriteArrayList<>(orders)); ...@@ -551,6 +564,7 @@ chromo.setOrders(new CopyOnWriteArrayList<>(orders));
if (considerSequence) { if (considerSequence) {
sortedOps.sort(Comparator.comparing((Entry op) -> -op.getPriority()) sortedOps.sort(Comparator.comparing((Entry op) -> -op.getPriority())
.thenComparing(Entry::getSequence) .thenComparing(Entry::getSequence)
.thenComparing(op -> op.getProductId() != null ? op.getProductId() : "") // 相同物料排在一起,减少换型
.thenComparing(op -> { .thenComparing(op -> {
Order order = orderMap.get(op.getGroupId()); Order order = orderMap.get(op.getGroupId());
return calculateCriticalRatio(order, remainingProcessingTime.getOrDefault(op.getGroupId(), 0.0)); return calculateCriticalRatio(order, remainingProcessingTime.getOrDefault(op.getGroupId(), 0.0));
...@@ -558,7 +572,7 @@ chromo.setOrders(new CopyOnWriteArrayList<>(orders)); ...@@ -558,7 +572,7 @@ chromo.setOrders(new CopyOnWriteArrayList<>(orders));
.thenComparing(randomIds::get)); .thenComparing(randomIds::get));
}else { }else {
sortedOps.sort(Comparator.comparing((Entry op) -> -op.getPriority()) sortedOps.sort(Comparator.comparing((Entry op) -> -op.getPriority())
.thenComparing(op -> op.getProductId() != null ? op.getProductId() : "") // 相同物料排在一起,减少换型
.thenComparing(op -> { .thenComparing(op -> {
Order order = orderMap.get(op.getGroupId()); Order order = orderMap.get(op.getGroupId());
return calculateCriticalRatio(order, remainingProcessingTime.getOrDefault(op.getGroupId(), 0.0)); return calculateCriticalRatio(order, remainingProcessingTime.getOrDefault(op.getGroupId(), 0.0));
...@@ -651,7 +665,7 @@ chromo.setOrders(new CopyOnWriteArrayList<>(orders)); ...@@ -651,7 +665,7 @@ chromo.setOrders(new CopyOnWriteArrayList<>(orders));
} }
sortedOps.sort(Comparator.comparing((Entry op) -> -op.getPriority()) sortedOps.sort(Comparator.comparing((Entry op) -> -op.getPriority())
.thenComparing(op -> op.getProductId() != null ? op.getProductId() : "") .thenComparing(op -> op.getProductId() != null ? op.getProductId() : "")
.thenComparing(op -> op.getMachineOptions().get(0).getProcessingTime() * op.getQuantity()) .thenComparing(op -> op.getMachineOptions().get(0).getProcessingTime() * op.getQuantity())
.thenComparing(randomIds::get)); .thenComparing(randomIds::get));
...@@ -747,6 +761,189 @@ chromo.setOrders(new CopyOnWriteArrayList<>(orders)); ...@@ -747,6 +761,189 @@ chromo.setOrders(new CopyOnWriteArrayList<>(orders));
return loadCost + processingCost + setupCost; return loadCost + processingCost + setupCost;
} }
/**
* EDD+SPT混合策略:先按截止日期,再按加工时间
*/
private Chromosome generateEDDSPTChromosome(Chromosome chromosome) {
List<Integer> ms = new ArrayList<>();
List<Integer> os = new ArrayList<>();
Map<Long, Double> machineLoad = new HashMap<>();
Random rnd = new Random();
List<GlobalOperationInfo> globalOpList = new ArrayList<>();
Map<Integer, LocalDateTime> dueDateMap = new HashMap<>();
for (Order order : orders) {
dueDateMap.put(order.getId(), order.getDueDate());
}
Map<Entry, Integer> randomIds = new HashMap<>();
List<Integer> indices = new ArrayList<>();
for (int i = 0; i < allOperations.size(); i++) {
indices.add(i);
}
Collections.shuffle(indices, rnd);
for (int i = 0; i < allOperations.size(); i++) {
randomIds.put(allOperations.get(i), indices.get(i));
}
List<Entry> sortedOps = new ArrayList<>(allOperations);
boolean considerSequence = rnd.nextBoolean();
if (considerSequence) {
sortedOps.sort(Comparator.comparing((Entry op) -> op.getPriority())
.thenComparing(Entry::getSequence)
.thenComparing(op -> dueDateMap.get(op.getGroupId()),
Comparator.nullsLast(Comparator.naturalOrder()))
.thenComparing(op -> op.getProductId() != null ? op.getProductId() : "")
.thenComparing(op -> {
if (op.getMachineOptions() == null || op.getMachineOptions().isEmpty()) {
return 0.0;
}
return op.getMachineOptions().get(0).getProcessingTime() * op.getQuantity();
})
.thenComparing(randomIds::get));
} else {
sortedOps.sort(Comparator.comparing((Entry op) -> op.getPriority())
.thenComparing(op -> dueDateMap.get(op.getGroupId()),
Comparator.nullsLast(Comparator.naturalOrder()))
.thenComparing(op -> op.getProductId() != null ? op.getProductId() : "")
.thenComparing(op -> {
if (op.getMachineOptions() == null || op.getMachineOptions().isEmpty()) {
return 0.0;
}
return op.getMachineOptions().get(0).getProcessingTime() * op.getQuantity();
})
.thenComparing(randomIds::get));
}
int globalOpId = 0;
for (Entry op : sortedOps) {
int groupId = op.getGroupId();
List<MachineOption> optionalMachines = op.getMachineOptions();
double minLoad = optionalMachines.stream()
.mapToDouble(m -> machineLoad.getOrDefault(m.getMachineId(), 0.0) + m.getProcessingTime())
.min()
.orElse(Double.MAX_VALUE);
List<MachineOption> minLoadMachines = optionalMachines.stream()
.filter(m -> machineLoad.getOrDefault(m.getMachineId(), 0.0) + m.getProcessingTime() == minLoad)
.collect(Collectors.toList());
MachineOption selectedMachine = minLoadMachines.get(rnd.nextInt(minLoadMachines.size()));
OptionalInt index = IntStream.range(0, optionalMachines.size())
.filter(i -> selectedMachine.getMachineId() == optionalMachines.get(i).getMachineId())
.findFirst();
int machineSeq = index.orElse(0) + 1;
ms.add(machineSeq);
machineLoad.put(selectedMachine.getMachineId(),
machineLoad.getOrDefault(selectedMachine.getMachineId(), 0.0) + selectedMachine.getProcessingTime());
os.add(groupId);
GlobalOperationInfo info = new GlobalOperationInfo();
info.setGlobalOpId(globalOpId);
info.setGroupId(op.getGroupId());
info.setSequence(op.getSequence());
info.setOp(op);
globalOpList.add(info);
globalOpId++;
}
chromosome.setGlobalOpList(globalOpList);
chromosome.setOperationSequencing(os);
chromosome.setMachineSelection(ms);
return chromosome;
}
/**
* 瓶颈优先策略:优先安排预计为瓶颈的设备上的工序
*/
private Chromosome generateBottleneckFirstChromosome(Chromosome chromosome) {
List<Integer> ms = new ArrayList<>();
List<Integer> os = new ArrayList<>();
Map<Long, Double> machineLoad = new HashMap<>();
Random rnd = new Random();
List<GlobalOperationInfo> globalOpList = new ArrayList<>();
Map<Entry, Integer> randomIds = new HashMap<>();
List<Integer> indices = new ArrayList<>();
for (int i = 0; i < allOperations.size(); i++) {
indices.add(i);
}
Collections.shuffle(indices, rnd);
for (int i = 0; i < allOperations.size(); i++) {
randomIds.put(allOperations.get(i), indices.get(i));
}
List<Entry> sortedOps = new ArrayList<>(allOperations);
Map<Long, Integer> machineOperationCount = new HashMap<>();
Map<Long, Double> machineTotalTime = new HashMap<>();
for (Entry op : allOperations) {
if (op.getMachineOptions() != null && !op.getMachineOptions().isEmpty()) {
for (MachineOption mo : op.getMachineOptions()) {
machineOperationCount.put(mo.getMachineId(),
machineOperationCount.getOrDefault(mo.getMachineId(), 0) + 1);
machineTotalTime.put(mo.getMachineId(),
machineTotalTime.getOrDefault(mo.getMachineId(), 0.0)
+ mo.getProcessingTime() * op.getQuantity());
}
}
}
sortedOps.sort(Comparator.comparing((Entry op) -> -op.getPriority())
.thenComparing((Entry op) -> {
if (op.getMachineOptions() == null || op.getMachineOptions().isEmpty()) {
return 0.0;
}
double maxTime = 0;
for (MachineOption mo : op.getMachineOptions()) {
double time = machineTotalTime.getOrDefault(mo.getMachineId(), 0.0);
if (time > maxTime) maxTime = time;
}
return -maxTime;
})
.thenComparing(op -> op.getProductId() != null ? op.getProductId() : "")
.thenComparing(randomIds::get));
int globalOpId = 0;
for (Entry op : sortedOps) {
int groupId = op.getGroupId();
List<MachineOption> optionalMachines = op.getMachineOptions();
double minLoad = optionalMachines.stream()
.mapToDouble(m -> machineLoad.getOrDefault(m.getMachineId(), 0.0) + m.getProcessingTime())
.min()
.orElse(Double.MAX_VALUE);
List<MachineOption> minLoadMachines = optionalMachines.stream()
.filter(m -> machineLoad.getOrDefault(m.getMachineId(), 0.0) + m.getProcessingTime() == minLoad)
.collect(Collectors.toList());
MachineOption selectedMachine = minLoadMachines.get(rnd.nextInt(minLoadMachines.size()));
OptionalInt index = IntStream.range(0, optionalMachines.size())
.filter(i -> selectedMachine.getMachineId() == optionalMachines.get(i).getMachineId())
.findFirst();
int machineSeq = index.orElse(0) + 1;
ms.add(machineSeq);
machineLoad.put(selectedMachine.getMachineId(),
machineLoad.getOrDefault(selectedMachine.getMachineId(), 0.0) + selectedMachine.getProcessingTime());
os.add(groupId);
GlobalOperationInfo info = new GlobalOperationInfo();
info.setGlobalOpId(globalOpId);
info.setGroupId(op.getGroupId());
info.setSequence(op.getSequence());
info.setOp(op);
globalOpList.add(info);
globalOpId++;
}
chromosome.setGlobalOpList(globalOpList);
chromosome.setOperationSequencing(os);
chromosome.setMachineSelection(ms);
return chromosome;
}
/** /**
* 随机 * 随机
*/ */
...@@ -768,7 +965,8 @@ chromo.setOrders(new CopyOnWriteArrayList<>(orders)); ...@@ -768,7 +965,8 @@ chromo.setOrders(new CopyOnWriteArrayList<>(orders));
randomIds.put(allOperations.get(i), indices.get(i)); randomIds.put(allOperations.get(i), indices.get(i));
} }
sortedOps.sort(Comparator.comparing((Entry op) -> -op.getPriority()) sortedOps.sort(Comparator.comparing((Entry op) -> -op.getPriority())
.thenComparing(randomIds::get)); .thenComparing(op -> op.getProductId() != null ? op.getProductId() : "") // 相同物料排在一起,减少换型
.thenComparing(randomIds::get));
......
...@@ -206,7 +206,7 @@ public class PlanResultService { ...@@ -206,7 +206,7 @@ public class PlanResultService {
if(machineIds.get(machineId)!=null&&machineIds.get(machineId)>3600*24*200) { if(machineIds.get(machineId)!=null&&machineIds.get(machineId)>3600*24*200) {
int day = (int) (machineIds.get(machineId) / 3600 / 24)+100; int day = (int) (machineIds.get(machineId) / 3600 / 24)+100;
day=Math.min(day,400); // day=Math.min(day,400);
List<TimeSegment> segments = machineScheduler.generateTimeSegment(machine, null, day); List<TimeSegment> segments = machineScheduler.generateTimeSegment(machine, null, day);
machineScheduler.addSegmentsWithDeduplication(machine, segments); machineScheduler.addSegmentsWithDeduplication(machine, segments);
} }
......
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