Commit ef3a51e0 authored by Tong Li's avatar Tong Li

Merge remote-tracking branch 'origin/master' into tl

parents 7351ba4a 87592467
......@@ -32,3 +32,14 @@ build/
### VS Code ###
.vscode/
/src/main/resources/application.yml
### Example user template template
### Example user template
# IntelliJ project files
.idea
*.iml
out
gen
!/logs/
!/log/
!/result/
This source diff could not be displayed because it is too large. You can view the blob instead.
2026-04-21 19:15:40.112 | main | com.aps.common.util.redis.RedisUtils | Redis 操作失败 1/3: get(material), 错误: Redis exception; nested exception is io.lettuce.core.RedisException: Connection closed
2026-04-21 19:15:40.627 | main | com.aps.common.util.redis.RedisUtils | Redis 操作失败 2/3: get(material), 错误: LettuceConnectionFactory was destroyed and cannot be used anymore
2026-04-21 19:58:28.398 | main | com.aps.common.util.redis.RedisUtils | Redis 操作失败 1/3: get(SceneId.6D63146BE5C84A78B5AB044327BA55BD), 错误: Redis exception; nested exception is io.lettuce.core.RedisException: java.io.IOException: 远程主机强迫关闭了一个现有的连接。
2026-04-21 21:22:58.624 | main | com.aps.common.util.redis.RedisUtils | Redis 操作失败 1/3: get(SceneId.6D63146BE5C84A78B5AB044327BA55BD), 错误: Redis exception; nested exception is io.lettuce.core.RedisException: java.io.IOException: 远程主机强迫关闭了一个现有的连接。
2026-04-24 11:05:58.256 | main | com.aps.common.util.redis.RedisUtils | Redis 操作失败 1/3: get(SceneId.6D63146BE5C84A78B5AB044327BA55BD), 错误: Redis exception; nested exception is io.lettuce.core.RedisException: java.io.IOException: 远程主机强迫关闭了一个现有的连接。
2026-04-24 15:25:23.471 | main | com.aps.common.util.redis.RedisUtils | Redis 操作失败 1/3: get(SceneId.6D63146BE5C84A78B5AB044327BA55BD), 错误: Redis exception; nested exception is io.lettuce.core.RedisException: java.io.IOException: 远程主机强迫关闭了一个现有的连接。
2026-04-24 15:57:33.089 | main | com.aps.common.util.redis.RedisUtils | Redis 操作失败 1/3: get(SceneId.6D63146BE5C84A78B5AB044327BA55BD), 错误: Redis exception; nested exception is io.lettuce.core.RedisException: java.io.IOException: 远程主机强迫关闭了一个现有的连接。
......@@ -14,6 +14,7 @@ public class ProdEquipment implements Serializable {
private Long equipId;
private String equipCode;
private String equipName;
private String capacityTypeName;
private Long resourceId;
private String resourceCode;
private String execId;
......@@ -30,4 +31,4 @@ public class ProdEquipment implements Serializable {
* 准备时间
*/
private int setupTime;
}
\ No newline at end of file
}
......@@ -16,7 +16,9 @@ public class MachineVO {
@Schema(description = "设备名称")
private String equipName;
private String capacityTypeName;
@Schema(description = "任务集合")
private List<GenVO> tasks;
}
\ No newline at end of file
}
......@@ -58,6 +58,8 @@ public class Machine {
*/
private String code;
private String capacityTypeName;
/**
* 节假日列表
*/
......@@ -131,4 +133,4 @@ public class Machine {
public int hashCode() {
return Objects.hash(id);
}
}
\ No newline at end of file
}
......@@ -1963,6 +1963,8 @@ public class GeneticDecoder {
.sorted(Comparator.comparing(Entry::getSequence))
.collect(Collectors.toList());
List<GlobalOperationInfo> entrys=
chromosome.getGlobalOpList().stream().filter(t->t.getOp().getGroupId()==groupId).collect(Collectors.toList());
for (Entry currentOp : orderOps) {
......@@ -1973,15 +1975,20 @@ public class GeneticDecoder {
GlobalOperationInfo global= entrys.stream().
filter(t->t.getOp().getId()==currentOp.getId())
.findFirst().orElse(null);
int globalOpId= global.getGlobalOpId();
int machineSeq= chromosome.getMachineSelection().get(globalOpId);
MachineOption machineOption=
currentOp.getMachineOptions().get(machineSeq-1);
Long machineId = machineOption.getMachineId();
Long machineId = currentOp.getSelectMachineID();
MachineOption machineOption= currentOp.getMachineOptions().stream()
.filter(t->t.getMachineId().equals(machineId)).findFirst().orElse(null);
// MachineOption machineOption= currentOp.getMachineOptions().stream()
// .filter(t->t.getMachineId().equals(machineId)).findFirst().orElse(null);
double processTime = machineOption.getProcessingTime();
OpMachine opMachine=new OpMachine();
opMachine.setGroupId(groupId);
......
package com.aps.service.Algorithm;
import com.aps.common.util.FileHelper;
import com.aps.common.util.ProductionDeepCopyUtil;
import com.aps.entity.Algorithm.*;
import com.aps.entity.basic.Entry;
......@@ -594,47 +595,64 @@ public class GeneticOperations {
return indexWeights.get(CommonCalculator.getOsIndex(indexWeights));
}
public void DelOrder(Chromosome chromosome) {
List<Entry> allOperations = chromosome.getAllOperations();
List<GlobalOperationInfo> globalOpList= chromosome.getGlobalOpList();
if(chromosome.getOrders()==null||chromosome.getOrders().size()==0)
return;
List<Order> orders = chromosome.getOrders();
List<Integer> OperationSequencing= chromosome.getOperationSequencing();
List<Integer> newoorderids= orders.stream()
.filter(t->t.isNewSfCreate())
.map(Order::getId)
.sorted(Comparator.reverseOrder())
.collect(Collectors.toList());
if(newoorderids!=null&&newoorderids.size()>0) {
List<Entry> allOperations = chromosome.getAllOperations();
List<GlobalOperationInfo> globalOpList = chromosome.getGlobalOpList();
List<Integer> OperationSequencing = chromosome.getOperationSequencing();
// log(String.format("半成品订单-删除前,工序: %d,工序序列: %d,设备: %d,设备序列: %d",
// allOperations.size(), OperationSequencing.size(), globalOpList.size(), chromosome.getMachineSelection().size()), true);
for (Integer id : newoorderids) {
List<Entry> sourceOps = allOperations.stream()
.filter(o -> o.getGroupId()==id)
.filter(o -> o.getGroupId() == id)
.sorted(Comparator.comparing(Entry::getSequence))
.collect(Collectors.toList());
for (Entry entry : sourceOps) {
OptionalInt index1 = IntStream.range(0, globalOpList.size())
.filter(h -> entry.getId()==globalOpList.get(h).getOp().getId())
.filter(h -> entry.getId() == globalOpList.get(h).getOp().getId())
.findFirst();
globalOpList.remove((int)index1.orElse(0));
globalOpList.remove((int) index1.orElse(0));
chromosome.getMachineSelection().remove((int)index1.orElse(0));
chromosome.getMachineSelection().remove((int) index1.orElse(0));
}
chromosome.getOperatRel().remove(id-1);
chromosome.getOperatRel().remove(id - 1);
}
allOperations.removeIf(t ->newoorderids.contains(t.getGroupId()));
OperationSequencing.removeIf(t ->newoorderids.contains(t));
allOperations.removeIf(t -> newoorderids.contains(t.getGroupId()));
OperationSequencing.removeIf(t -> newoorderids.contains(t));
AtomicInteger globalOpId = new AtomicInteger(0);
globalOpList.forEach(t-> {
globalOpList.forEach(t -> {
t.setGlobalOpId(globalOpId.getAndIncrement());
});
orders.removeIf(t ->newoorderids.contains(t.getId()));
orders.removeIf(t -> newoorderids.contains(t.getId()));
// log(String.format("半成品订单-删除后,工序: %d,工序序列: %d,设备: %d,设备序列: %d",
// allOperations.size(), OperationSequencing.size(), globalOpList.size(), chromosome.getMachineSelection().size()), true);
//
}
}
private void log(String message, boolean enableLogging) {
if (false ) {
FileHelper.writeLogFile(message);
}
}
......
......@@ -324,6 +324,12 @@ if(entry.getMachineOptions()!=null)
.distinct()
.sorted()
.collect(Collectors.toList());
Map<Long, String> capacityTypeNameByEquipId = ProdEquipments.stream()
.filter(t -> t.getEquipId() != null && t.getCapacityTypeName() != null)
.collect(Collectors.toMap(
ProdEquipment::getEquipId,
ProdEquipment::getCapacityTypeName,
(existing, replacement) -> existing));
List<Machine> machines = new ArrayList<>();
List<PlanResource> PlanResources = _PlanResourceService.lambdaQuery()
......@@ -336,6 +342,7 @@ if(entry.getMachineOptions()!=null)
Machine machine = new Machine();
machine.setId(id);
machine.setCapacityTypeName(capacityTypeNameByEquipId.get(id));
machine.setCode("");
machine.setName("");
......@@ -399,6 +406,9 @@ if(entry.getMachineOptions()!=null)
{
machine.setCode(equipinfo.getEquipId());
machine.setName(equipinfo.getEquipName());
if (machine.getCapacityTypeName() == null) {
machine.setCapacityTypeName(equipinfo.getCapacityTypeName());
}
}else {
machine.setCode(PlanResource.getReferenceCode());
machine.setName(PlanResource.getTitle());
......@@ -457,6 +467,9 @@ if(entry.getMachineOptions()!=null)
{
machine.setCode(equipinfo.getEquipId());
machine.setName(equipinfo.getEquipName());
if (machine.getCapacityTypeName() == null) {
machine.setCapacityTypeName(equipinfo.getCapacityTypeName());
}
}else {
machine.setCode(PlanResource.getReferenceCode());
machine.setName(PlanResource.getTitle());
......@@ -551,6 +564,7 @@ if(entry.getMachineOptions()!=null)
{
machine.setCode(equipinfo.getEquipId());
machine.setName(equipinfo.getEquipName());
machine.setCapacityTypeName(equipinfo.getCapacityTypeName());
}else {
machine.setCode(resource.getReferenceCode());
machine.setName(resource.getTitle());
......@@ -715,6 +729,13 @@ if(entry.getMachineOptions()!=null)
machine.setId(resource.getId());
machine.setCode(resource.getReferenceCode());
machine.setName(resource.getTitle());
Equipinfo equipinfo = _equipinfoService.lambdaQuery()
.eq(Equipinfo::getId, resource.getReferenceId())
.eq(Equipinfo::getIsdeleted, 0)
.one();
if (equipinfo != null) {
machine.setCapacityTypeName(equipinfo.getCapacityTypeName());
}
List<Shift> shifts1 = new ArrayList<>();
......
......@@ -21,7 +21,7 @@ public class VariableNeighborhoodSearch {
// ==================== 策略选择与轮换参数 ====================
private static final int MAX_CONSECUTIVE_SAME_STRATEGY = 4; // 同一策略最多连续使用次数,避免陷入局部最优
private static final int MAX_NEIGHBORHOODS = 4; // 使用的邻域数量(0-3:插单/交换/并行合并/重排)
private static final int MAX_NEIGHBORHOODS = 3; // 使用的邻域数量(0-3:插单/交换/并行合并/重排)
// ==================== 邻域搜索参数 ====================
private static final double HIGH_PRIORITY_GROUP_PROBABILITY = 0.7; // 优先选择高优先级工单的概率
......@@ -204,7 +204,7 @@ public class VariableNeighborhoodSearch {
neighborhoods.add(new NeighborhoodStructure("SmartBottleneckChange", this::ChangeMachineForBottleneckOpWrapper));
//瓶颈工序在相同设备上移动
neighborhoods.add(new NeighborhoodStructure("moveBottleneckSameMachine", this::moveBottleneckSameMachineWrapper));
neighborhoods.add(new NeighborhoodStructure("moveBottleneckSameMachine", this::moveBottleneckSameMachineWrapper));
//瓶颈工序往前移动
neighborhoods.add(new NeighborhoodStructure("MoveBottleneckForward", this::moveBottleneckForwardWrapper));
......@@ -238,7 +238,7 @@ public class VariableNeighborhoodSearch {
neighborhoods.add(new NeighborhoodStructure("MultiOperationSwap", this::multiOperationSwapWrapper));
// MultiMachineChange - 一次改变多个工序的机器选择
neighborhoods.add(new NeighborhoodStructure("MultiMachineChange", this::multiMachineChangeWrapper));
neighborhoods.add(new NeighborhoodStructure("MultiMachineChange", this::multiMachineChangeWrapper));
// HybridShake - 混合抖动:综合调整
neighborhoods.add(new NeighborhoodStructure("HybridShake", this::hybridShakeWrapper));
......@@ -807,7 +807,7 @@ public class VariableNeighborhoodSearch {
i + 1, op.getGroupId(), op.getOperationId(), op.getMachineId(),
boa.bottleneckScore, boa.waitTime, boa.machineWaitTime,
boa.onCriticalPath ? "是" : "否", boa.delayContribution
));
),false);
}
// 更新关键工序为识别出的瓶颈工序
......@@ -1236,6 +1236,7 @@ public class VariableNeighborhoodSearch {
return result != null ? result : null;
}
private Chromosome ChangeMachineForBottleneckOpWrapper(Chromosome chromosome) {
log("ChangeMachineForBottleneckOpWrapper");
List<GAScheduleResult> results = chromosome.getResult();
Map<Integer, Object> obj = buildPositionToEntryIndex(chromosome);
Map<Integer, Entry> positionToEntryIndex = (Map<Integer, Entry>) obj.get(1);
......@@ -1268,6 +1269,7 @@ public class VariableNeighborhoodSearch {
* 优先选择负载低的设备
*/
private Chromosome generateMachineChangeForSpecificOp(Chromosome chromosome, List<MachineOption> machineOptions, int idx) {
Chromosome neighbor=copyChromosome(chromosome);// ProductionDeepCopyUtil.deepCopy(chromosome, Chromosome.class);
List<Integer> ms = neighbor.getMachineSelection();
if (!ms.isEmpty() && idx >= 0 && idx < ms.size()) {
......@@ -1294,7 +1296,7 @@ public class VariableNeighborhoodSearch {
private Chromosome moveBottleneckForwardWrapper(Chromosome chromosome) {
List<GAScheduleResult> results = chromosome.getResult();
log("moveBottleneckForwardWrapper");
Map<String, Integer> positionIndex = buildPositionIndex(chromosome);
Map<Integer, Object> obj = buildPositionToEntryIndex(chromosome);
......@@ -1320,7 +1322,7 @@ public class VariableNeighborhoodSearch {
private Chromosome moveBottleneckSameMachineWrapper(Chromosome chromosome) {
List<GAScheduleResult> results = chromosome.getResult();
log("moveBottleneckSameMachineWrapper");
Map<String, Integer> positionIndex = buildPositionIndex(chromosome);
Map<Integer, Object> obj = buildPositionToEntryIndex(chromosome);
Map<Integer, Entry> positionToEntryIndex =(Map<Integer, Entry>)obj.get(1);
......@@ -1348,6 +1350,7 @@ public class VariableNeighborhoodSearch {
private Chromosome tryMoveBottleneckOpForward(Chromosome chromosome, List<GAScheduleResult> bottleneckOps,
Map<String, Integer> positionkey,List<List<Integer>> positionByPriority,Map<Integer, Entry> positionIndex,Map<String, Integer> machinePositionIndex,boolean isSameMachine) {
log(String.format("tryMoveBottleneckOpForward: isSameMachine=%b", isSameMachine));
log("tryMoveBottleneckOpForward:positionIndex"+positionIndex.size());
if (bottleneckOps.isEmpty()) {
log("tryMoveBottleneckOpForward: 瓶颈工序为空");
......@@ -1447,7 +1450,7 @@ public class VariableNeighborhoodSearch {
private Chromosome moveNonBottleneckBackwardWrapper(Chromosome chromosome) {
List<GAScheduleResult> results = chromosome.getResult();
log("moveNonBottleneckBackwardWrapper");
Map<String, Integer> positionIndex = buildPositionIndex(chromosome);
Map<Integer, Object> obj = buildPositionToEntryIndex(chromosome);
Map<Integer, Entry> positionToEntryIndex =(Map<Integer, Entry>)obj.get(1);
......@@ -1473,6 +1476,8 @@ public class VariableNeighborhoodSearch {
Map<Integer, Entry> positionToEntryIndex
) {
log(String.format("tryMoveNonBottleneckOpBackward: 瓶颈设备ID=%d", bottleneckMachineId));
log("tryMoveNonBottleneckOpBackward:positionIndex"+positionIndex.size());
log("tryMoveNonBottleneckOpBackward:positionToEntryIndex"+positionToEntryIndex.size());
List<GAScheduleResult> results = chromosome.getResult();
if (results == null) {
......@@ -1553,6 +1558,8 @@ public class VariableNeighborhoodSearch {
* 将工序往后移动
*/
private Chromosome moveOperationBackward(Chromosome chromosome,Map<Integer, Entry> originalPositionIndex, int pos, int steps) {
log("moveOperationBackward:originalPositionIndex"+originalPositionIndex.size());
Chromosome neighbor=copyChromosome(chromosome);// ProductionDeepCopyUtil.deepCopy(chromosome, Chromosome.class);
List<Integer> os = neighbor.getOperationSequencing();
......@@ -1588,6 +1595,8 @@ public class VariableNeighborhoodSearch {
* 将工序往前插入(不交换,直接插入到目标位置)
*/
private Chromosome insertOperationForward(Chromosome chromosome, int pos, int steps, Map<String, Entry> entrys,Map<Integer, Entry> originalPositionIndex) {
log("insertOperationForward:originalPositionIndex"+originalPositionIndex.size());
Chromosome neighbor=copyChromosome(chromosome);// ProductionDeepCopyUtil.deepCopy(chromosome, Chromosome.class);
List<Integer> os = neighbor.getOperationSequencing();
......@@ -1631,8 +1640,10 @@ public class VariableNeighborhoodSearch {
* 随机生成邻域解(兜底策略)
*/
private Chromosome generateRandomNeighbor(Chromosome chromosome,Map<Integer, Entry> positionIndex,List<List<Integer>> positionByPriority) {
int neighborType = rnd.nextInt(5);
int neighborType =4;// rnd.nextInt(5);
log(String.format("随机生成邻域解-"+neighborType));
log("generateRandomNeighbor:positionIndex"+positionIndex.size());
log("generateRandomNeighbor:positionByPriority"+positionByPriority.size());
switch (neighborType) {
case 0:
......@@ -1652,6 +1663,8 @@ public class VariableNeighborhoodSearch {
private Chromosome generateSwapNeighborWrapper(Chromosome chromosome) {
log("generateSwapNeighborWrapper");
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);
......@@ -1676,6 +1689,7 @@ public class VariableNeighborhoodSearch {
* 生成交换邻域解 - 只在相同优先级的工序之间交换
*/
private Chromosome generateSwapNeighbor(Chromosome chromosome,Map<Integer, Entry> positionIndex,List<List<Integer>> positionByPriority) {
log("generateSwapNeighbor"+positionIndex.size());
Chromosome neighbor=copyChromosome(chromosome);
List<Integer> os = neighbor.getOperationSequencing();
if (os.size() >= 2 && !positionByPriority.isEmpty()) {
......@@ -1717,6 +1731,7 @@ public class VariableNeighborhoodSearch {
return neighbor;
}
private Chromosome generateReverseNeighborWrapper(Chromosome chromosome) {
log("generateReverseNeighborWrapper");
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);
......@@ -1726,6 +1741,8 @@ public class VariableNeighborhoodSearch {
* 生成反转邻域解 - 只反转相同优先级的连续工序
*/
private Chromosome generateReverseNeighbor(Chromosome chromosome,Map<Integer, Entry> positionIndex,List<List<Integer>> positionByPriority) {
log("generateReverseNeighbor"+positionIndex.size());
Chromosome neighbor = copyChromosome(chromosome); //ProductionDeepCopyUtil.deepCopy(chromosome, Chromosome.class);
List<Integer> os = neighbor.getOperationSequencing();
if (os.size() >= 2&&positionByPriority.size()>0) {
......@@ -1769,25 +1786,26 @@ public class VariableNeighborhoodSearch {
double priority = startOp.getPriority();
boolean allSameGroupId = true;
for (int i = start; i <= end; i++) {
Entry op = positionIndex.get(i);
if (op == null&&op.getGroupId()==startOp.getGroupId() ) {
allSameGroupId = false;
break;
}
}
// for (int i = start; i <= end; i++) {
// Entry op = positionIndex.get(i);
// if (op == null||op.getGroupId()==startOp.getGroupId() ) {
// allSameGroupId = false;
// break;
// }
// }
if (allSameGroupId) {
//if (allSameGroupId) {
java.util.Collections.reverse(os.subList(start, end + 1));
neighbor.setOperationSequencing(os);
break;
}
// }
}
}
return neighbor;
}
private Chromosome generateInsertNeighborWrapper(Chromosome chromosome) {
log("generateInsertNeighborWrapper");
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);
......@@ -1798,6 +1816,7 @@ public class VariableNeighborhoodSearch {
*/
private Chromosome generateInsertNeighbor(Chromosome chromosome,Map<Integer, Entry> positionIndex,List<List<Integer>> positionByPriority) {
Chromosome neighbor=copyChromosome(chromosome);// ProductionDeepCopyUtil.deepCopy(chromosome, Chromosome.class);
log("generateInsertNeighbor"+positionIndex.size());
List<Integer> os = neighbor.getOperationSequencing();
if (os.size() >= 2&&positionByPriority.size()>0) {
// Map<Integer, Entry> positionIndex = buildPositionToEntryIndex(neighbor);
......@@ -1822,6 +1841,7 @@ public class VariableNeighborhoodSearch {
}
List<Integer> positionos = positionByPriority.get(priorityGroupIndex);
if (positionos.size() < 2) continue;
int idx1InList = rnd.nextInt(positionos.size());
......@@ -1854,6 +1874,7 @@ public class VariableNeighborhoodSearch {
* 生成机器选择邻域解 - 不受优先级限制
*/
private Chromosome generateMachineChangeNeighbor(Chromosome chromosome) {
log("generateMachineChangeNeighbor");
Chromosome neighbor=copyChromosome(chromosome);// ProductionDeepCopyUtil.deepCopy(chromosome, Chromosome.class);
List<Integer> ms = neighbor.getMachineSelection();
if (!ms.isEmpty()) {
......@@ -1884,6 +1905,8 @@ public class VariableNeighborhoodSearch {
}
Chromosome generateSameMachineSwapNeighbor(Chromosome chromosome){
log("generateSameMachineSwapNeighbor");
List<Integer> os = chromosome.getOperationSequencing();
Map<String, Integer> machinePositionIndex = buildEntryMachinePositionIndex(chromosome);
......@@ -1896,8 +1919,8 @@ public class VariableNeighborhoodSearch {
}
private Chromosome generateSameMachineSwapNeighbor(Chromosome chromosome,int idx1,Map<Integer, Entry> positionIndex,Map<String, Integer> machinePositionIndex) {
//有问题
log("generateSameMachineSwapNeighbor"+positionIndex.size());
Chromosome neighbor=copyChromosome(chromosome);// ProductionDeepCopyUtil.deepCopy(chromosome, Chromosome.class);
List<Integer> os = neighbor.getOperationSequencing();
List<Integer> ms = neighbor.getMachineSelection();
......@@ -1935,6 +1958,11 @@ public class VariableNeighborhoodSearch {
if (positions.isEmpty()||positions.size() <=1) return neighbor;
int idx2 = positions.get(rnd.nextInt(positions.size()));
if(idx1>os.size()||idx2>os.size())
{
int i=0;
}
Collections.swap(os, idx1, idx2);
neighbor.setOperationSequencing(os);
}
......@@ -2003,9 +2031,11 @@ public class VariableNeighborhoodSearch {
* 局部搜索
*/
private Chromosome localSearch(Chromosome chromosome, GeneticDecoder decoder, List<Machine> machines) {
geneticOperations.DelOrder(chromosome);
Chromosome best = ProductionDeepCopyUtil.deepCopy(chromosome, Chromosome.class);
Chromosome best =copyChromosome(chromosome);
decode(decoder, best, machines);
Chromosome current = ProductionDeepCopyUtil.deepCopy(best, Chromosome.class);
geneticOperations.DelOrder(current);
writeKpi(best);
// 预定义邻域结构,避免每次循环重复创建
List<NeighborhoodStructure> neighborhoods = defineNeighborhoods();
......@@ -2018,7 +2048,7 @@ public class VariableNeighborhoodSearch {
break;
}
Chromosome neighbor = generateNeighbor(best, neighborhood);
Chromosome neighbor = generateNeighbor(current, neighborhood);
if (neighbor != null) {
neighbors.add(neighbor);
}
......@@ -2123,6 +2153,9 @@ public class VariableNeighborhoodSearch {
private Map<String, Integer> buildPositionIndex(Chromosome chromosome) {
Map<String, Integer> index = new HashMap<>();
List<Integer> os = chromosome.getOperationSequencing();
Map<Integer, Integer> orderProcessCounter = new HashMap<>();
for (int i = 0; i < os.size(); i++) {
......@@ -2170,6 +2203,9 @@ public class VariableNeighborhoodSearch {
Map<Double, Set<Integer>> groupidByPriority = new HashMap<>();
List<Integer> os = chromosome.getOperationSequencing();
log(String.format("buildPositionToEntryIndex--工序: %d,工序序列: %d,设备: %d,设备序列: %d",
chromosome.getAllOperations().size(), os.size(), chromosome.getGlobalOpList().size(), chromosome.getMachineSelection().size()));
Map<Integer, Integer> orderProcessCounter = new HashMap<>();
for (int i = 0; i < os.size(); i++) {
......@@ -2325,6 +2361,7 @@ public class VariableNeighborhoodSearch {
* 瓶颈设备工序激进重排 - Wrapper方法
*/
private Chromosome aggressiveBottleneckReorderWrapper(Chromosome chromosome) {
log("aggressiveBottleneckReorderWrapper");
List<GAScheduleResult> results = chromosome.getResult();
Map<Integer, Object> obj = buildPositionToEntryIndex(chromosome);
Map<Integer, Entry> positionToEntryIndex = (Map<Integer, Entry>) obj.get(1);
......@@ -2444,6 +2481,8 @@ public class VariableNeighborhoodSearch {
* 关键路径工序优化 - Wrapper方法
*/
private Chromosome criticalPathOptimizeWrapper(Chromosome chromosome) {
log("criticalPathOptimizeWrapper");
List<GAScheduleResult> results = chromosome.getResult();
Map<Integer, Object> obj = buildPositionToEntryIndex(chromosome);
Map<Integer, Entry> positionToEntryIndex = (Map<Integer, Entry>) obj.get(1);
......
......@@ -438,6 +438,7 @@ public class ChromosomeDataService {
filteredMachine.setEarliestTime(originalMachine.getEarliestTime());
filteredMachine.setTotalTaskTime(originalMachine.getTotalTaskTime());
filteredMachine.setCode(originalMachine.getCode());
filteredMachine.setCapacityTypeName(originalMachine.getCapacityTypeName());
filteredMachine.setActualWorkTime(originalMachine.getActualWorkTime());
filteredMachine.setRate(originalMachine.getRate());
filteredMachine.setDepartment(originalMachine.getDepartment());
......@@ -1639,6 +1640,7 @@ public class ChromosomeDataService {
filteredMachine.setEarliestTime(originalMachine.getEarliestTime());
filteredMachine.setTotalTaskTime(originalMachine.getTotalTaskTime());
filteredMachine.setCode(originalMachine.getCode());
filteredMachine.setCapacityTypeName(originalMachine.getCapacityTypeName());
filteredMachine.setActualWorkTime(originalMachine.getActualWorkTime());
filteredMachine.setRate(originalMachine.getRate());
filteredMachine.setDepartment(originalMachine.getDepartment());
......
......@@ -551,11 +551,9 @@ public class LanuchServiceImpl implements LanuchService {
.filter(Objects::nonNull)
.collect(Collectors.toList());
// 批量插入
if (!launchOrderList .isEmpty()) {
for (ProdLaunchOrder order : launchOrderList ) {
prodLaunchOrderService.save(order); // 单条插入
}
// 批量插入,避免每个工单一次数据库往返
if (!launchOrderList.isEmpty()) {
prodLaunchOrderService.saveBatch(launchOrderList, 500);
}
log.info("成功处理{}条订单数据", prodOrderMainList.size());
......@@ -783,8 +781,68 @@ public class LanuchServiceImpl implements LanuchService {
return;
}
Set<Integer> routingIds = order.stream()
.map(ProdLaunchOrder::getRoutingId)
.filter(Objects::nonNull)
.collect(Collectors.toSet());
if (routingIds.isEmpty()) {
throw new SceneGenerationException("新建场景失败:工单未配置工艺路线");
}
List<RoutingHeader> routingHeaders = routingHeaderMapper.selectList(new LambdaQueryWrapper<RoutingHeader>()
.in(RoutingHeader::getId, routingIds)
.eq(RoutingHeader::getIsDeleted, 0));
Map<Integer, RoutingHeader> routingHeaderMap = routingHeaders.stream()
.collect(Collectors.toMap(RoutingHeader::getId, Function.identity(), (existing, replacement) -> existing));
List<Long> routingHeaderIds = routingIds.stream()
.map(Integer::longValue)
.collect(Collectors.toList());
Map<Long, List<RoutingDetail>> routingDetailsByHeaderId = getRoutingDetails(routingHeaderIds).stream()
.collect(Collectors.groupingBy(RoutingDetail::getRoutingHeaderId));
routingDetailsByHeaderId.values().forEach(list -> list.sort(Comparator.comparing(RoutingDetail::getTaskSeq)));
Map<Long, List<RoutingDetailEquip>> routingDetailEquipByHeaderId = getRoutingDetailEquip(routingHeaderIds).stream()
.collect(Collectors.groupingBy(RoutingDetailEquip::getRoutingHeaderId));
List<Equipinfo> equipinfoList = equipinfoService.lambdaQuery()
.eq(Equipinfo::getIsdeleted, 0)
.list();
Map<Long, Equiptype1> equipTypeMap = GetEquipTypes().stream()
.collect(Collectors.toMap(Equiptype1::getId, Function.identity(), (existing, replacement) -> existing));
List<ProdProcessExec> allProcessExecList = new ArrayList<>();
List<ProdEquipment> allProdEquipments = new ArrayList<>();
for (ProdLaunchOrder prodOrderMain : order) {
convertToProcessExec(prodOrderMain, sceneId);
RoutingHeader routingHeader = routingHeaderMap.get(prodOrderMain.getRoutingId());
if (routingHeader == null) {
log.error("未找到对应工艺: {}", prodOrderMain.getRoutingId());
throw new RuntimeException("未找到对应工艺: " + prodOrderMain.getRoutingId());
}
List<RoutingDetail> routingDetails = routingDetailsByHeaderId.get(routingHeader.getId().longValue());
if (CollectionUtils.isEmpty(routingDetails)) {
log.error("工艺下无工序信息: {}", routingHeader.getId());
throw new RuntimeException("工艺下无工序信息: " + routingHeader.getId());
}
List<RoutingDetailEquip> routingDetailEquip = routingDetailEquipByHeaderId.getOrDefault(
routingHeader.getId().longValue(),
Collections.emptyList());
List<ProdProcessExec> processExecList = routingDetails.stream()
.map(detail -> createProcessExec(prodOrderMain, detail, sceneId, routingDetailEquip, routingHeader, equipTypeMap))
.collect(Collectors.toList());
allProcessExecList.addAll(processExecList);
allProdEquipments.addAll(batchInsertEquipMent(routingDetailEquip, sceneId, processExecList, false, equipinfoList));
}
if (!CollectionUtils.isEmpty(allProcessExecList)) {
prodProcessExecService.saveBatch(allProcessExecList, 500);
}
if (!CollectionUtils.isEmpty(allProdEquipments)) {
prodEquipmentService.saveBatch(allProdEquipments, 500);
}
log.info("完成{}个工单的工序转换",order.size());
......@@ -936,9 +994,17 @@ public class LanuchServiceImpl implements LanuchService {
*/
public ProdProcessExec createProcessExec(ProdLaunchOrder prodOrderMain,
RoutingDetail detail,
String sceneId, List<RoutingDetailEquip> routingDetailEquip,
RoutingHeader routingHeader) {
RoutingDetail detail,
String sceneId, List<RoutingDetailEquip> routingDetailEquip,
RoutingHeader routingHeader) {
return createProcessExec(prodOrderMain, detail, sceneId, routingDetailEquip, routingHeader, null);
}
private ProdProcessExec createProcessExec(ProdLaunchOrder prodOrderMain,
RoutingDetail detail,
String sceneId, List<RoutingDetailEquip> routingDetailEquip,
RoutingHeader routingHeader,
Map<Long, Equiptype1> equipTypeMap) {
validateProcessDurationLimit(prodOrderMain, detail, routingDetailEquip);
ProdProcessExec prodProcessExec = new ProdProcessExec();
......@@ -970,7 +1036,9 @@ public class LanuchServiceImpl implements LanuchService {
prodProcessExec.setSingleOut(detail.getSingleOut());
if (detail.getEquipTypeId() != null)
{
Equiptype1 equipType = equiptype1Service.lambdaQuery().eq(Equiptype1::getId, detail.getEquipTypeId()).one();
Equiptype1 equipType = equipTypeMap == null
? equiptype1Service.lambdaQuery().eq(Equiptype1::getId, detail.getEquipTypeId()).one()
: equipTypeMap.get(detail.getEquipTypeId());
if (equipType != null) {
prodProcessExec.setEquipTypeName(equipType.getEquipTypeName());
......@@ -1162,16 +1230,26 @@ public class LanuchServiceImpl implements LanuchService {
return;
}
Set<Integer> routingIds = prodOrderMains.stream()
.map(ProdLaunchOrder::getRoutingId)
.filter(Objects::nonNull)
.collect(Collectors.toSet());
List<RoutingDetailConnect> allConnections = routingIds.isEmpty()
? new ArrayList<>()
: routingDetailConnectService.lambdaQuery()
.in(RoutingDetailConnect::getRoutingHeaderId, routingIds)
.eq(RoutingDetailConnect::getIsdeleted, 0)
.list();
Map<Long, List<RoutingDetailConnect>> connectionsByRoutingId = allConnections.stream()
.collect(Collectors.groupingBy(RoutingDetailConnect::getRoutingHeaderId));
// 先批量获取所有需要的ProdProcessExec对象
Set<Long> routingDetailIds = new HashSet<>();
for (ProdLaunchOrder order : prodOrderMains) {
List<RoutingDetailConnect> connections = routingDetailConnectService.lambdaQuery()
.eq(RoutingDetailConnect::getRoutingHeaderId, order.getRoutingId())
.eq(RoutingDetailConnect::getIsdeleted, 0)
.list();
for (RoutingDetailConnect connection : connections) {
for (RoutingDetailConnect connection : allConnections) {
if (connection.getSourceoperationid() != null) {
routingDetailIds.add(connection.getSourceoperationid());
}
if (connection.getDestoperationid() != null) {
routingDetailIds.add(connection.getDestoperationid());
}
}
......@@ -1191,7 +1269,7 @@ public class LanuchServiceImpl implements LanuchService {
ProdProcessExec::getExecId,
(existing, replacement) -> existing)); // 处理重复key的情况
generateProcessRelations(prodOrderMains, sceneId, routingDetailIdToExecIdMap);
generateProcessRelations(prodOrderMains, sceneId, routingDetailIdToExecIdMap, connectionsByRoutingId);
......@@ -1208,6 +1286,27 @@ public class LanuchServiceImpl implements LanuchService {
*/
public void generateProcessRelations(List<ProdLaunchOrder> prodOrderMains, String sceneId, Map<String, String> routingDetailIdToExecIdMap) {
Set<Integer> routingIds = Optional.ofNullable(prodOrderMains)
.orElse(Collections.emptyList())
.stream()
.map(ProdLaunchOrder::getRoutingId)
.filter(Objects::nonNull)
.collect(Collectors.toSet());
Map<Long, List<RoutingDetailConnect>> connectionsByRoutingId = routingIds.isEmpty()
? new HashMap<>()
: routingDetailConnectService.lambdaQuery()
.in(RoutingDetailConnect::getRoutingHeaderId, routingIds)
.eq(RoutingDetailConnect::getIsdeleted, 0)
.list()
.stream()
.collect(Collectors.groupingBy(RoutingDetailConnect::getRoutingHeaderId));
generateProcessRelations(prodOrderMains, sceneId, routingDetailIdToExecIdMap, connectionsByRoutingId);
}
private void generateProcessRelations(List<ProdLaunchOrder> prodOrderMains,
String sceneId,
Map<String, String> routingDetailIdToExecIdMap,
Map<Long, List<RoutingDetailConnect>> connectionsByRoutingId) {
if (CollectionUtils.isEmpty(prodOrderMains)) {
return;
}
......@@ -1215,7 +1314,10 @@ public class LanuchServiceImpl implements LanuchService {
List<ProdOrderProcess> processRelations = new java.util.ArrayList<>();
for (ProdLaunchOrder prodOrderMain : prodOrderMains) {
List<ProdOrderProcess> relations = createProcessRelations(prodOrderMain, sceneId, routingDetailIdToExecIdMap);
List<RoutingDetailConnect> connections = prodOrderMain.getRoutingId() == null
? Collections.emptyList()
: connectionsByRoutingId.get(prodOrderMain.getRoutingId().longValue());
List<ProdOrderProcess> relations = createProcessRelations(prodOrderMain, sceneId, routingDetailIdToExecIdMap, connections);
processRelations.addAll(relations);
}
......@@ -1263,6 +1365,20 @@ public class LanuchServiceImpl implements LanuchService {
.collect(Collectors.toList());
}
private List<ProdOrderProcess> createProcessRelations(ProdLaunchOrder prodOrderMain,
String sceneId,
Map<String, String> routingDetailIdToExecIdMap,
List<RoutingDetailConnect> connections) {
if (CollectionUtils.isEmpty(connections)) {
return new ArrayList<>();
}
return connections.stream()
.filter(connection -> connection.getSourceoperationid() != null)
.map(connection -> createProcessRelation(prodOrderMain, connection, sceneId, routingDetailIdToExecIdMap))
.collect(Collectors.toList());
}
/**
◦ 创建单个工序关系
......@@ -1521,6 +1637,7 @@ public class LanuchServiceImpl implements LanuchService {
if (equipinfo1 != null) {
prodEquipment.setEquipCode(equipinfo1.getEquipId());
prodEquipment.setEquipName(equipinfo1.getEquipName());
prodEquipment.setCapacityTypeName(equipinfo1.getCapacityTypeName());
} else {
log.warn("未找到referenceId={}对应的设备信息", planResource.getReferenceId());
continue;
......@@ -1609,6 +1726,7 @@ public class LanuchServiceImpl implements LanuchService {
prodEquipment.setEquipCode(equipinfo1.getEquipId());
prodEquipment.setEquipName(equipinfo1.getEquipName());
prodEquipment.setCapacityTypeName(equipinfo1.getCapacityTypeName());
// 使用Map快速查询
prodEquipment.setResourceId(machineId);
......
......@@ -2004,12 +2004,32 @@ public class PlanResultService {
//
}
applySceneCapacityTypeName(machines, ProdEquipments);
FileHelper.writeLogFile("初始化设备日历-----------结束-------");
redisUtils.set("machines",machines);
GlobalCacheUtil.put("machines", machines, 10, TimeUnit.MINUTES);
return machines;
}
private void applySceneCapacityTypeName(List<Machine> machines, List<ProdEquipment> prodEquipments) {
if (machines == null || prodEquipments == null || prodEquipments.isEmpty()) {
return;
}
Map<Long, String> capacityTypeNameByEquipId = prodEquipments.stream()
.filter(t -> t.getEquipId() != null && t.getCapacityTypeName() != null)
.collect(Collectors.toMap(
ProdEquipment::getEquipId,
ProdEquipment::getCapacityTypeName,
(existing, replacement) -> existing));
for (Machine machine : machines) {
String capacityTypeName = capacityTypeNameByEquipId.get(machine.getId());
if (capacityTypeName != null) {
machine.setCapacityTypeName(capacityTypeName);
}
}
}
public List<Machine> InitCalendarToAllMachines ()
{
FileHelper.writeLogFile("初始化Redis设备日历-----------开始-------");
......@@ -2751,6 +2771,7 @@ public class PlanResultService {
machineVO.setId(machine.getId());
machineVO.setEquipId(String.valueOf(machine.getId()));
machineVO.setEquipName(machine.getName());
machineVO.setCapacityTypeName(machine.getCapacityTypeName());
// 注意:tasks 字段需要在其他地方设置,因为 Machine 类中没有任务信息
return machineVO;
}
......@@ -2898,8 +2919,7 @@ public class PlanResultService {
}
applySceneCapacityTypeName(machines, ProdEquipments);
return machines;
......@@ -3477,8 +3497,7 @@ public class PlanResultService {
machine.setShifts(shifts1);
}
}
applySceneCapacityTypeName(machines, ProdEquipments);
return machines;
......
......@@ -121,6 +121,7 @@ public class PlanSchedulerService {
machineVO.setId(machine.getId());
machineVO.setEquipId(String.valueOf(machine.getId()));
machineVO.setEquipName(machine.getName());
machineVO.setCapacityTypeName(machine.getCapacityTypeName());
return machineVO;
}
}
\ No newline at end of file
}
......@@ -9,6 +9,7 @@
<id column="RESOURCE_ID" property="resourceId" />
<result column="EQUIP_CODE" property="equipCode" />
<result column="EQUIP_NAME" property="equipName" />
<result column="CAPACITY_TYPE_NAME" property="capacityTypeName" />
<result column="EXEC_ID" property="execId" />
<result column="SPEED" property="speed" />
<result column="ID" property="id" />
......@@ -18,7 +19,7 @@
<!-- 通用查询结果列 -->
<sql id="Base_Column_List">
SCENE_ID, EQUIP_ID, EQUIP_CODE, EQUIP_NAME, RESOURCE_ID, EXEC_ID, SPEED, ID, EFFICIENCY_VALUE, SETUP_TIME
SCENE_ID, EQUIP_ID, EQUIP_CODE, EQUIP_NAME, CAPACITY_TYPE_NAME, RESOURCE_ID, EXEC_ID, SPEED, ID, EFFICIENCY_VALUE, SETUP_TIME
</sql>
</mapper>
\ No newline at end of file
</mapper>
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