From 1f0db72effe89280001306a0d95ae78ed0dd4db0 Mon Sep 17 00:00:00 2001
From: Junjie <fallin.jie@qq.com>
Date: 星期日, 15 三月 2026 17:47:02 +0800
Subject: [PATCH] #
---
src/main/java/com/zy/common/utils/NavigateUtils.java | 200 ++++++++++++++++++++++++++++++++++++++++++-------
1 files changed, 171 insertions(+), 29 deletions(-)
diff --git a/src/main/java/com/zy/common/utils/NavigateUtils.java b/src/main/java/com/zy/common/utils/NavigateUtils.java
index ef8909d..620f8f7 100644
--- a/src/main/java/com/zy/common/utils/NavigateUtils.java
+++ b/src/main/java/com/zy/common/utils/NavigateUtils.java
@@ -6,16 +6,20 @@
import java.util.HashSet;
import java.util.List;
import java.util.Map;
+import java.util.Set;
+import com.zy.asrs.entity.BasDevp;
import com.zy.asrs.entity.BasStation;
+import com.zy.asrs.service.BasDevpService;
import com.zy.asrs.service.BasStationService;
import com.zy.core.News;
+import com.zy.core.model.StationObjModel;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
-import com.baomidou.mybatisplus.mapper.EntityWrapper;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.core.common.SpringUtils;
import com.core.exception.CoolException;
import com.zy.common.model.NavigateNode;
@@ -31,11 +35,16 @@
@Component
public class NavigateUtils {
+ private static final String CFG_STATION_PATH_LEN_WEIGHT_PERCENT = "stationPathLenWeightPercent";
+ private static final String CFG_STATION_PATH_CONG_WEIGHT_PERCENT = "stationPathCongWeightPercent";
+ private static final String CFG_STATION_PATH_PASS_OTHER_OUT_STATION_WEIGHT_PERCENT = "stationPathPassOtherOutStationWeightPercent";
+ private static final String CFG_STATION_PATH_PASS_OTHER_OUT_STATION_FORCE_SKIP = "stationPathPassOtherOutStationForceSkip";
+
@Autowired
private BasStationService basStationService;
public synchronized List<NavigateNode> calcByStationId(Integer startStationId, Integer endStationId) {
- BasStation startStation = basStationService.selectById(startStationId);
+ BasStation startStation = basStationService.getById(startStationId);
if (startStation == null) {
throw new CoolException("鏈壘鍒拌 璧风偣 瀵瑰簲鐨勭珯鐐规暟鎹�");
}
@@ -84,6 +93,20 @@
for (int i = 0; i < fitlerList.size(); i++) {
NavigateNode currentNode = fitlerList.get(i);
currentNode.setIsInflectionPoint(false);
+ currentNode.setIsLiftTransferPoint(false);
+
+ try {
+ JSONObject valueObject = JSON.parseObject(currentNode.getNodeValue());
+ if (valueObject != null) {
+ Object isLiftTransfer = valueObject.get("isLiftTransfer");
+ if (isLiftTransfer != null) {
+ String isLiftTransferStr = isLiftTransfer.toString();
+ if ("1".equals(isLiftTransferStr) || "true".equalsIgnoreCase(isLiftTransferStr)) {
+ currentNode.setIsLiftTransferPoint(true);
+ }
+ }
+ }
+ } catch (Exception ignore) {}
NavigateNode nextNode = (i + 1 < fitlerList.size()) ? fitlerList.get(i + 1) : null;
NavigateNode prevNode = (i - 1 >= 0) ? fitlerList.get(i - 1) : null;
@@ -204,7 +227,7 @@
try {
DeviceConfigService deviceConfigService = SpringUtils.getBean(DeviceConfigService.class);
if (deviceConfigService != null) {
- List<DeviceConfig> devpList = deviceConfigService.selectList(new EntityWrapper<DeviceConfig>()
+ List<DeviceConfig> devpList = deviceConfigService.list(new QueryWrapper<DeviceConfig>()
.eq("device_type", String.valueOf(SlaveType.Devp)));
for (DeviceConfig deviceConfig : devpList) {
StationThread stationThread = (StationThread) SlaveConnection.get(SlaveType.Devp, deviceConfig.getDeviceNo());
@@ -219,10 +242,28 @@
}
} catch (Exception ignore) {}
+ Set<Integer> outStationIdSet = loadAllOutStationIdSet();
+
+ double lenWeightPercent = 50.0;
+ double congWeightPercent = 50.0;
+ double passOtherOutStationWeightPercent = 100.0;
+ boolean forceSkipPassOtherOutStation = false;
+ try {
+ ConfigService configService = SpringUtils.getBean(ConfigService.class);
+ if (configService != null) {
+ lenWeightPercent = loadDoubleConfig(configService, CFG_STATION_PATH_LEN_WEIGHT_PERCENT, lenWeightPercent);
+ congWeightPercent = loadDoubleConfig(configService, CFG_STATION_PATH_CONG_WEIGHT_PERCENT, congWeightPercent);
+ passOtherOutStationWeightPercent = loadDoubleConfig(configService, CFG_STATION_PATH_PASS_OTHER_OUT_STATION_WEIGHT_PERCENT, passOtherOutStationWeightPercent);
+ forceSkipPassOtherOutStation = loadBooleanConfig(configService, CFG_STATION_PATH_PASS_OTHER_OUT_STATION_FORCE_SKIP, false);
+ }
+ } catch (Exception ignore) {}
+
List<List<NavigateNode>> candidates = new ArrayList<>();
List<Integer> lens = new ArrayList<>();
List<Integer> tasksList = new ArrayList<>();
List<Double> congs = new ArrayList<>();
+ List<Integer> passOtherOutStationCounts = new ArrayList<>();
+ int skippedByPassOtherOutStation = 0;
for (List<NavigateNode> path : allList) {
if (path == null || path.isEmpty()) {
@@ -252,13 +293,27 @@
}
}
double cong = len <= 0 ? 0.0 : (double) tasks / (double) len;
+ int passOtherOutStationCount = countPassOtherOutStations(path, outStationIdSet);
+ if (forceSkipPassOtherOutStation && passOtherOutStationCount > 0) {
+ skippedByPassOtherOutStation++;
+ News.info("[WCS Debug] 绔欑偣璺緞鍊欓�夊凡璺宠繃锛屽洜缁忚繃鍏朵粬鍑哄簱绔欑偣,startStationId={},endStationId={},passOtherOutStationCount={}",
+ extractStationId(path.get(0)),
+ extractStationId(path.get(path.size() - 1)),
+ passOtherOutStationCount);
+ continue;
+ }
candidates.add(path);
lens.add(len);
tasksList.add(tasks);
congs.add(cong);
+ passOtherOutStationCounts.add(passOtherOutStationCount);
}
if (candidates.isEmpty()) {
+ if (forceSkipPassOtherOutStation && skippedByPassOtherOutStation > 0) {
+ News.info("[WCS Debug] 鎵�鏈夌珯鐐硅矾寰勫�欓�夊潎鍥犵粡杩囧叾浠栧嚭搴撶珯鐐硅寮哄埗璺宠繃");
+ return new ArrayList<>();
+ }
return allList.get(0);
}
@@ -266,59 +321,50 @@
int maxLen = Integer.MIN_VALUE;
double minCong = Double.MAX_VALUE;
double maxCong = -Double.MAX_VALUE;
+ int minPassOtherOutStationCount = Integer.MAX_VALUE;
+ int maxPassOtherOutStationCount = Integer.MIN_VALUE;
for (int i = 0; i < candidates.size(); i++) {
int l = lens.get(i);
double c = congs.get(i);
+ int p = passOtherOutStationCounts.get(i);
if (l < minLen) minLen = l;
if (l > maxLen) maxLen = l;
if (c < minCong) minCong = c;
if (c > maxCong) maxCong = c;
+ if (p < minPassOtherOutStationCount) minPassOtherOutStationCount = p;
+ if (p > maxPassOtherOutStationCount) maxPassOtherOutStationCount = p;
}
- //闀垮害鏉冮噸鐧惧垎姣�
- double lenWeightPercent = 50.0;
- //鎷ュ牭鏉冮噸鐧惧垎姣�
- double congWeightPercent = 50.0;
- try {
- ConfigService configService = SpringUtils.getBean(ConfigService.class);
- if (configService != null) {
- Config cfgLen = configService.selectOne(new EntityWrapper<Config>().eq("code", "stationPathLenWeightPercent"));
- if (cfgLen != null && cfgLen.getValue() != null) {
- String v = cfgLen.getValue().trim();
- if (v.endsWith("%")) v = v.substring(0, v.length() - 1);
- try { lenWeightPercent = Double.parseDouble(v); } catch (Exception ignore) {}
- }
- Config cfgCong = configService.selectOne(new EntityWrapper<Config>().eq("code", "stationPathCongWeightPercent"));
- if (cfgCong != null && cfgCong.getValue() != null) {
- String v = cfgCong.getValue().trim();
- if (v.endsWith("%")) v = v.substring(0, v.length() - 1);
- try { congWeightPercent = Double.parseDouble(v); } catch (Exception ignore) {}
- }
- }
- } catch (Exception ignore) {}
-
- double weightSum = lenWeightPercent + congWeightPercent;
+ double weightSum = lenWeightPercent + congWeightPercent + passOtherOutStationWeightPercent;
double lenW = weightSum <= 0 ? 0.5 : lenWeightPercent / weightSum;
double congW = weightSum <= 0 ? 0.5 : congWeightPercent / weightSum;
+ double passOtherOutStationW = weightSum <= 0 ? 0.0 : passOtherOutStationWeightPercent / weightSum;
List<NavigateNode> best = null;
double bestCost = Double.MAX_VALUE;
+ int bestPassOtherOutStationCount = Integer.MAX_VALUE;
int bestTasks = Integer.MAX_VALUE;
int bestLen = Integer.MAX_VALUE;
for (int i = 0; i < candidates.size(); i++) {
int l = lens.get(i);
int t = tasksList.get(i);
double c = congs.get(i);
+ int p = passOtherOutStationCounts.get(i);
//褰掍竴鍖�
double lenNorm = (maxLen - minLen) <= 0 ? 0.0 : (l - minLen) / (double) (maxLen - minLen);
double congNorm = (maxCong - minCong) <= 0 ? 0.0 : (c - minCong) / (double) (maxCong - minCong);
+ double passOtherOutStationNorm = (maxPassOtherOutStationCount - minPassOtherOutStationCount) <= 0
+ ? 0.0
+ : (p - minPassOtherOutStationCount) / (double) (maxPassOtherOutStationCount - minPassOtherOutStationCount);
//鑾峰彇鏉冮噸
- double cost = lenNorm * lenW + congNorm * congW;
+ double cost = lenNorm * lenW + congNorm * congW + passOtherOutStationNorm * passOtherOutStationW;
if (cost < bestCost
- || (cost == bestCost && t < bestTasks)
- || (cost == bestCost && t == bestTasks && l < bestLen)) {
+ || (cost == bestCost && p < bestPassOtherOutStationCount)
+ || (cost == bestCost && p == bestPassOtherOutStationCount && t < bestTasks)
+ || (cost == bestCost && p == bestPassOtherOutStationCount && t == bestTasks && l < bestLen)) {
best = candidates.get(i);
bestCost = cost;
+ bestPassOtherOutStationCount = p;
bestTasks = t;
bestLen = l;
}
@@ -330,6 +376,102 @@
return best;
}
+ private Set<Integer> loadAllOutStationIdSet() {
+ Set<Integer> outStationIdSet = new HashSet<>();
+ try {
+ BasDevpService basDevpService = SpringUtils.getBean(BasDevpService.class);
+ if (basDevpService == null) {
+ return outStationIdSet;
+ }
+ List<BasDevp> basDevpList = basDevpService.list(new QueryWrapper<BasDevp>().eq("status", 1));
+ for (BasDevp basDevp : basDevpList) {
+ List<StationObjModel> outStationList = basDevp.getOutStationList$();
+ for (StationObjModel stationObjModel : outStationList) {
+ if (stationObjModel != null && stationObjModel.getStationId() != null) {
+ outStationIdSet.add(stationObjModel.getStationId());
+ }
+ }
+ }
+ } catch (Exception ignore) {}
+ return outStationIdSet;
+ }
+
+ private int countPassOtherOutStations(List<NavigateNode> path, Set<Integer> outStationIdSet) {
+ if (path == null || path.size() < 3 || outStationIdSet == null || outStationIdSet.isEmpty()) {
+ return 0;
+ }
+ Integer startStationId = extractStationId(path.get(0));
+ Integer endStationId = extractStationId(path.get(path.size() - 1));
+ Set<Integer> hitStationIdSet = new HashSet<>();
+ for (int i = 1; i < path.size() - 1; i++) {
+ Integer stationId = extractStationId(path.get(i));
+ if (stationId == null) {
+ continue;
+ }
+ if (startStationId != null && startStationId.equals(stationId)) {
+ continue;
+ }
+ if (endStationId != null && endStationId.equals(stationId)) {
+ continue;
+ }
+ if (outStationIdSet.contains(stationId)) {
+ hitStationIdSet.add(stationId);
+ }
+ }
+ return hitStationIdSet.size();
+ }
+
+ private Integer extractStationId(NavigateNode node) {
+ if (node == null || node.getNodeValue() == null) {
+ return null;
+ }
+ try {
+ JSONObject value = JSON.parseObject(node.getNodeValue());
+ if (value == null) {
+ return null;
+ }
+ return value.getInteger("stationId");
+ } catch (Exception ignore) {}
+ return null;
+ }
+
+ private double loadDoubleConfig(ConfigService configService, String code, double defaultValue) {
+ if (configService == null || code == null) {
+ return defaultValue;
+ }
+ Config config = configService.getOne(new QueryWrapper<Config>().eq("code", code));
+ if (config == null || config.getValue() == null) {
+ return defaultValue;
+ }
+ String value = config.getValue().trim();
+ if (value.endsWith("%")) {
+ value = value.substring(0, value.length() - 1);
+ }
+ try {
+ return Double.parseDouble(value);
+ } catch (Exception ignore) {}
+ return defaultValue;
+ }
+
+ private boolean loadBooleanConfig(ConfigService configService, String code, boolean defaultValue) {
+ if (configService == null || code == null) {
+ return defaultValue;
+ }
+ Config config = configService.getOne(new QueryWrapper<Config>().eq("code", code));
+ if (config == null || config.getValue() == null) {
+ return defaultValue;
+ }
+ String value = config.getValue().trim();
+ if (value.isEmpty()) {
+ return defaultValue;
+ }
+ return "1".equals(value)
+ || "true".equalsIgnoreCase(value)
+ || "yes".equalsIgnoreCase(value)
+ || "y".equalsIgnoreCase(value)
+ || "on".equalsIgnoreCase(value);
+ }
+
//鍒ゆ柇褰撳墠鑺傜偣鍒颁笅涓�涓妭鐐规槸鍚︿负鎷愮偣
public HashMap<String,Object> searchInflectionPoint(NavigateNode currentNode, NavigateNode fatherNode, NavigateNode nextNode) {
HashMap<String, Object> map = new HashMap<>();
--
Gitblit v1.9.1