no message

main
HUOJIN\92525 2026-01-04 17:47:58 +08:00
parent 2566ff544b
commit f521e2cb73
4 changed files with 72 additions and 42 deletions

View File

@ -26,10 +26,8 @@ import org.cpte.modules.receive.mapper.AsnMapper;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import java.util.Collections; import java.util.*;
import java.util.Comparator; import java.util.stream.Collectors;
import java.util.List;
import java.util.Set;
/** /**
* *
@ -204,14 +202,16 @@ public class ScanTrayProcessor {
//2.获取所有可用库位 //2.获取所有可用库位
availablePoints = pointMapper.queryPoints(null, CommonStatusEnum.FREE.getValue(), areaCode); availablePoints = pointMapper.queryPoints(null, CommonStatusEnum.FREE.getValue(), areaCode);
} }
//根据巷到分组,得到每个巷道有多个库位,<巷道编号,库位个数>
Map<String, Long> colMap = getColMap(areaCode);
List<PointScore> scoredPoints = availablePoints.stream() List<PointScore> scoredPoints = availablePoints.stream()
.map(point -> clusterPointScore(point, station, itemKeys)) .map(point -> clusterPointScore(point, station, itemKeys, colMap))
.sorted(Comparator.comparing(PointScore::getScore).reversed()) .sorted(Comparator.comparing(PointScore::getScore).reversed())
.limit(50)
.toList(); .toList();
if (!scoredPoints.isEmpty()) { if (!scoredPoints.isEmpty()) {
log.info("最优【{}】库位评分结果:{}", scoredPoints.get(0).getPoint().getPointCode(), scoredPoints.get(0).getScore());
return scoredPoints.get(0).getPoint(); return scoredPoints.get(0).getPoint();
} }
@ -221,65 +221,82 @@ public class ScanTrayProcessor {
/** /**
* *
*/ */
private PointScore clusterPointScore(Point point, Point station, List<ItemKey> itemKeys) { private PointScore clusterPointScore(Point point, Point station, List<ItemKey> itemKeys, Map<String, Long> colMap) {
double totalScore; double totalScore;
// 1. 距离评分 - 考虑从入库口到库位的距离 // 1. 距离评分 - 考虑从入库口到库位的距离
double distanceScore = calculateClusterDistanceCost(point, station) * 0.3;// 权重30% double distanceScore = calculateClusterDistanceCost(point, station) * 0.3;// 权重30%
// 2. 通道深度策略评分 - 新增核心策略 // 2. 通道深度策略评分 - 新增核心策略
double channelDepthScore = calculateChannelDepthScore(point) * 0.25; // 权重25% double channelDepthScore = calculateChannelDepthScore(point, colMap) * 0.25; // 权重25%
// 3. 通道类型评分 - 双通道优先 // 3. 通道类型评分 - 双通道优先
double channelScore = calculateChannelScore(point) * 0.15; // 权重15% double channelScore = calculateChannelScore(point) * 0.2; // 权重20%
// 4. 均衡评分 - 避免热点区域 // 4. 均衡评分 - 避免热点区域
// double balanceScore = calculateBalanceScore(point) * 0.1; // 权重10% // double balanceScore = calculateBalanceScore(point) * 0.1; // 权重10%
// 5. 物料聚集潜力评分 - 新增 // 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); log.info("【{}】库位总分:{} - 距离评分: {} - 通道深度策略评分: {} - 通道类型评分: {} - 均衡评分: {} - 物料聚集评分: {}", point.getPointCode(), totalScore, distanceScore, channelDepthScore, channelScore, 0, 0);
return new PointScore(point, totalScore); return new PointScore(point, totalScore);
} }
/** /**
* - * -
* (04) *
* (07) *
*/ */
private double calculateChannelDepthScore(Point point) { private double calculateChannelDepthScore(Point point, Map<String, Long> colMap) {
// 获取当前巷道的最大深度
Long maxDepth = colMap.get(point.getColNum());
if (point.getIzDoubleLane().equals(1)) { if (point.getIzDoubleLane().equals(1)) {
// 双通道策略:中间优先,得分 04 > 03=05 > 02=06 > 01=07 return doubleChannelDepthScore(Integer.parseInt(point.getRowNum()), maxDepth);
return doubleChannelDepthScore(Integer.parseInt(point.getRowNum()));
} else { } else {
// 单通道策略:深度优先,得分 07 > 06 > 05 > 04 > 03 > 02 > 01 return singleChannelDepthScore(Integer.parseInt(point.getRowNum()), maxDepth);
return singleChannelDepthScore(Integer.parseInt(point.getRowNum()));
} }
} }
/** /**
* *
* 04 > 03=05 > 02=06 > 01=07 *
*/ */
private double doubleChannelDepthScore(int depth) { private double doubleChannelDepthScore(int depth, long maxDepth) {
return switch (depth) { // 计算中间位置
case 4 -> 100; // 最优位置 long middle = (maxDepth + 1) / 2;
case 3, 5 -> 85; // 次优位置
case 2, 6 -> 70; // 良好位置 // 对于偶数深度,中间两个位置分数相同
case 1, 7 -> 60; // 一般位置 if (maxDepth % 2 == 0) {
default -> 50; 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) { private double singleChannelDepthScore(int depth, long maxDepth) {
// 深度越大分数越高07得100分01得14分 // 深度越大分数越高,按比例计算
return depth * 100.0 / 7; return depth * 100.0 / maxDepth;
} }
/** /**
@ -392,8 +409,21 @@ public class ScanTrayProcessor {
private double calculateClusterDistanceCost(Point point, Point station) { private double calculateClusterDistanceCost(Point point, Point station) {
// 计算曼哈顿距离 // 计算曼哈顿距离
double distance = Math.abs(point.getPositionX() - station.getPositionX()) + Math.abs(point.getPositionY() - station.getPositionY()); 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<String, Long> getColMap(String areaCode) {
List<Point> pointList = pointMapper.queryPoints(null, null, areaCode);
return pointList.stream().collect(Collectors.groupingBy(Point::getColNum, Collectors.counting()));
}
} }

View File

@ -76,10 +76,10 @@ public class ReceiveBackProcessor {
parameterValue1.setValue(List.of(task)); parameterValue1.setValue(List.of(task));
SMOMRequest.ParameterValue2 parameterValue2 = new SMOMRequest.ParameterValue2(); SMOMRequest.ParameterValue2 parameterValue2 = new SMOMRequest.ParameterValue2();
parameterValue2.setValue(1); parameterValue2.setValue(2);
SMOMRequest.Context context = new SMOMRequest.Context(); SMOMRequest.Context context = new SMOMRequest.Context();
context.setInvOrgId(1); context.setInvOrgId(2);
context.setTicket(ticket); context.setTicket(ticket);
SMOMRequest saiWmsRequest = new SMOMRequest(); SMOMRequest saiWmsRequest = new SMOMRequest();

View File

@ -84,10 +84,10 @@ public class PickBackProcessor {
parameterValue1.setValue(List.of(taskReq)); parameterValue1.setValue(List.of(taskReq));
SMOMRequest.ParameterValue2 parameterValue2 = new SMOMRequest.ParameterValue2(); SMOMRequest.ParameterValue2 parameterValue2 = new SMOMRequest.ParameterValue2();
parameterValue2.setValue(1); parameterValue2.setValue(2);
SMOMRequest.Context context = new SMOMRequest.Context(); SMOMRequest.Context context = new SMOMRequest.Context();
context.setInvOrgId(1); context.setInvOrgId(2);
context.setTicket(ticket); context.setTicket(ticket);
SMOMRequest saiWmsRequest = new SMOMRequest(); SMOMRequest saiWmsRequest = new SMOMRequest();

View File

@ -24,7 +24,7 @@ public class SwmsLoginUtil {
private OpenApiMapper openApiMapper; private OpenApiMapper openApiMapper;
public String loginJson() { public String loginJson() {
String userName = "LM"; String userName = "LIKU";
String password = "654321"; String password = "654321";
SMOMRequest.ParameterValue3 parameterValue1 = new SMOMRequest.ParameterValue3(); SMOMRequest.ParameterValue3 parameterValue1 = new SMOMRequest.ParameterValue3();