From f521e2cb73cdad12d368b747ec70ab4b0403385f Mon Sep 17 00:00:00 2001 From: "HUOJIN\\92525" <925259474@qq.com> Date: Sun, 4 Jan 2026 17:47:58 +0800 Subject: [PATCH] no message --- .../service/processor/ScanTrayProcessor.java | 104 +++++++++++------- .../processor/ReceiveBackProcessor.java | 4 +- .../service/processor/PickBackProcessor.java | 4 +- .../org/cpte/modules/utils/SwmsLoginUtil.java | 2 +- 4 files changed, 72 insertions(+), 42 deletions(-) diff --git a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/conveyorLine/service/processor/ScanTrayProcessor.java b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/conveyorLine/service/processor/ScanTrayProcessor.java index 6fcfb5f..c33d0b9 100644 --- a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/conveyorLine/service/processor/ScanTrayProcessor.java +++ b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/conveyorLine/service/processor/ScanTrayProcessor.java @@ -26,10 +26,8 @@ import org.cpte.modules.receive.mapper.AsnMapper; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; -import java.util.Collections; -import java.util.Comparator; -import java.util.List; -import java.util.Set; +import java.util.*; +import java.util.stream.Collectors; /** * 扫描托盘处理 @@ -204,14 +202,16 @@ public class ScanTrayProcessor { //2.获取所有可用库位 availablePoints = pointMapper.queryPoints(null, CommonStatusEnum.FREE.getValue(), areaCode); } + //根据巷到分组,得到每个巷道有多个库位,<巷道编号,库位个数> + Map colMap = getColMap(areaCode); List scoredPoints = availablePoints.stream() - .map(point -> clusterPointScore(point, station, itemKeys)) + .map(point -> clusterPointScore(point, station, itemKeys, colMap)) .sorted(Comparator.comparing(PointScore::getScore).reversed()) - .limit(50) .toList(); if (!scoredPoints.isEmpty()) { + log.info("最优【{}】库位评分结果:{}", scoredPoints.get(0).getPoint().getPointCode(), scoredPoints.get(0).getScore()); return scoredPoints.get(0).getPoint(); } @@ -221,65 +221,82 @@ public class ScanTrayProcessor { /** * 库位评分计算 */ - private PointScore clusterPointScore(Point point, Point station, List itemKeys) { + private PointScore clusterPointScore(Point point, Point station, List itemKeys, Map colMap) { double totalScore; // 1. 距离评分 - 考虑从入库口到库位的距离 double distanceScore = calculateClusterDistanceCost(point, station) * 0.3;// 权重30% // 2. 通道深度策略评分 - 新增核心策略 - double channelDepthScore = calculateChannelDepthScore(point) * 0.25; // 权重25% + double channelDepthScore = calculateChannelDepthScore(point, colMap) * 0.25; // 权重25% // 3. 通道类型评分 - 双通道优先 - double channelScore = calculateChannelScore(point) * 0.15; // 权重15% + double channelScore = calculateChannelScore(point) * 0.2; // 权重20% // 4. 均衡评分 - 避免热点区域 - // double balanceScore = calculateBalanceScore(point) * 0.1; // 权重10% + // double balanceScore = calculateBalanceScore(point) * 0.1; // 权重10% // 5. 物料聚集潜力评分 - 新增 - // double clusterPotentialScore = calculateClusterPotentialScore(point, itemKeys) * 0.2; // 权重20% + // double clusterPotentialScore = calculateClusterPotentialScore(point, itemKeys) * 0.2; // 权重20% - totalScore = distanceScore + channelDepthScore + channelScore ; + totalScore = distanceScore + channelDepthScore + channelScore; log.info("【{}】库位总分:{} - 距离评分: {} - 通道深度策略评分: {} - 通道类型评分: {} - 均衡评分: {} - 物料聚集评分: {}", point.getPointCode(), totalScore, distanceScore, channelDepthScore, channelScore, 0, 0); return new PointScore(point, totalScore); } /** - * 通道深度策略评分 - 核心优化 - * 双通道:中间优先(04),向两端扩展 - * 单通道:深度优先(07),向前扩展 + * 通道深度策略评分 - 核心优化(动态深度) + * 双通道:中间优先,向两端扩展 + * 单通道:深度优先,越靠里分数越高 */ - private double calculateChannelDepthScore(Point point) { + private double calculateChannelDepthScore(Point point, Map colMap) { + // 获取当前巷道的最大深度 + Long maxDepth = colMap.get(point.getColNum()); if (point.getIzDoubleLane().equals(1)) { - // 双通道策略:中间优先,得分 04 > 03=05 > 02=06 > 01=07 - return doubleChannelDepthScore(Integer.parseInt(point.getRowNum())); + return doubleChannelDepthScore(Integer.parseInt(point.getRowNum()), maxDepth); } else { - // 单通道策略:深度优先,得分 07 > 06 > 05 > 04 > 03 > 02 > 01 - return singleChannelDepthScore(Integer.parseInt(point.getRowNum())); + return singleChannelDepthScore(Integer.parseInt(point.getRowNum()), maxDepth); } } /** - * 双通道深度评分 - * 理想顺序:04 > 03=05 > 02=06 > 01=07 + * 双通道深度评分(动态深度) + * 策略:中间位置最优,向两端递减 */ - private double doubleChannelDepthScore(int depth) { - return switch (depth) { - case 4 -> 100; // 最优位置 - case 3, 5 -> 85; // 次优位置 - case 2, 6 -> 70; // 良好位置 - case 1, 7 -> 60; // 一般位置 - default -> 50; - }; + private double doubleChannelDepthScore(int depth, long maxDepth) { + // 计算中间位置 + long middle = (maxDepth + 1) / 2; + + // 对于偶数深度,中间两个位置分数相同 + if (maxDepth % 2 == 0) { + if (depth == middle || depth == middle + 1) { + return 100; // 中间最优位置 + } + } else { + if (depth == middle) { + return 100; // 中间最优位置 + } + } + + // 计算距离中心的偏离程度,偏离越大分数越低 + double center = (maxDepth + 1) / 2.0; + double distanceFromCenter = Math.abs(depth - center); + + // 根据巷道深度调整评分递减幅度,确保评分在合理范围内 + double maxDistance = Math.max(center - 1, maxDepth - center); + if (maxDistance == 0) return 100; // 只有一个位置的情况 + + // 使用线性递减,确保边缘位置仍有合理分数 + return 100 - (distanceFromCenter / maxDistance) * 40; } /** - * 单通道深度评分 - * 理想顺序:07 > 06 > 05 > 04 > 03 > 02 > 01 + * 单通道深度评分(动态深度) + * 策略:深度越大(越靠里)分数越高 */ - private double singleChannelDepthScore(int depth) { - // 深度越大分数越高,07得100分,01得14分 - return depth * 100.0 / 7; + private double singleChannelDepthScore(int depth, long maxDepth) { + // 深度越大分数越高,按比例计算 + return depth * 100.0 / maxDepth; } /** @@ -392,8 +409,21 @@ public class ScanTrayProcessor { private double calculateClusterDistanceCost(Point point, Point station) { // 计算曼哈顿距离 double distance = Math.abs(point.getPositionX() - station.getPositionX()) + Math.abs(point.getPositionY() - station.getPositionY()); - + // 使用更大的标准化参数(根据实际坐标范围) + double normalizationFactor = 250000.0; // 或使用动态计算的最大距离值 // 距离越小分数越高 - return Math.max(0, 100 - (distance / 100.0)); + return Math.max(0, 100 - (distance / normalizationFactor) * 100); } + + /** + * 获取每个巷道的库位个数 + * + * @param areaCode 库区 + * @return Map<巷道编码, 库位个数> + */ + private Map getColMap(String areaCode) { + List pointList = pointMapper.queryPoints(null, null, areaCode); + return pointList.stream().collect(Collectors.groupingBy(Point::getColNum, Collectors.counting())); + } + } diff --git a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/receive/service/processor/ReceiveBackProcessor.java b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/receive/service/processor/ReceiveBackProcessor.java index fe5d4f7..3df26c4 100644 --- a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/receive/service/processor/ReceiveBackProcessor.java +++ b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/receive/service/processor/ReceiveBackProcessor.java @@ -76,10 +76,10 @@ public class ReceiveBackProcessor { parameterValue1.setValue(List.of(task)); SMOMRequest.ParameterValue2 parameterValue2 = new SMOMRequest.ParameterValue2(); - parameterValue2.setValue(1); + parameterValue2.setValue(2); SMOMRequest.Context context = new SMOMRequest.Context(); - context.setInvOrgId(1); + context.setInvOrgId(2); context.setTicket(ticket); SMOMRequest saiWmsRequest = new SMOMRequest(); diff --git a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/shipping/service/processor/PickBackProcessor.java b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/shipping/service/processor/PickBackProcessor.java index 8a1d027..3155c49 100644 --- a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/shipping/service/processor/PickBackProcessor.java +++ b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/shipping/service/processor/PickBackProcessor.java @@ -84,10 +84,10 @@ public class PickBackProcessor { parameterValue1.setValue(List.of(taskReq)); SMOMRequest.ParameterValue2 parameterValue2 = new SMOMRequest.ParameterValue2(); - parameterValue2.setValue(1); + parameterValue2.setValue(2); SMOMRequest.Context context = new SMOMRequest.Context(); - context.setInvOrgId(1); + context.setInvOrgId(2); context.setTicket(ticket); SMOMRequest saiWmsRequest = new SMOMRequest(); diff --git a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/utils/SwmsLoginUtil.java b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/utils/SwmsLoginUtil.java index 8136116..5d6cc91 100644 --- a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/utils/SwmsLoginUtil.java +++ b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/utils/SwmsLoginUtil.java @@ -24,7 +24,7 @@ public class SwmsLoginUtil { private OpenApiMapper openApiMapper; public String loginJson() { - String userName = "LM"; + String userName = "LIKU"; String password = "654321"; SMOMRequest.ParameterValue3 parameterValue1 = new SMOMRequest.ParameterValue3();