From 45052042f06689096093fc86cae36560b2eeb1f0 Mon Sep 17 00:00:00 2001
From: Junjie <fallin.jie@qq.com>
Date: 星期四, 02 四月 2026 15:38:48 +0800
Subject: [PATCH] #优化运行速度

---
 src/main/java/com/zy/core/utils/station/StationOutboundDecisionSupport.java |   87 +++++++++++++++++++++++++++++++++----------
 1 files changed, 67 insertions(+), 20 deletions(-)

diff --git a/src/main/java/com/zy/core/utils/station/StationOutboundDecisionSupport.java b/src/main/java/com/zy/core/utils/station/StationOutboundDecisionSupport.java
index 3a1450c..02018dd 100644
--- a/src/main/java/com/zy/core/utils/station/StationOutboundDecisionSupport.java
+++ b/src/main/java/com/zy/core/utils/station/StationOutboundDecisionSupport.java
@@ -116,6 +116,7 @@
         if (wrkMast == null || wrkMast.getStaNo() == null) {
             return null;
         }
+        DecisionPathCache decisionPathCache = new DecisionPathCache();
         if (!shouldApplyOutOrder(wrkMast, outOrderStationIds)) {
             return OutOrderDispatchDecision.direct(wrkMast.getStaNo());
         }
@@ -124,13 +125,14 @@
                 wrkMast.getSourceStaNo(),
                 wrkMast.getStaNo(),
                 outOrderStationIds,
-                pathLenFactor
+                pathLenFactor,
+                decisionPathCache
         );
         if (dispatchStationId == null) {
             return null;
         }
-        if (isCurrentOutOrderDispatchStation(currentStationId, wrkMast, outOrderStationIds, pathLenFactor)) {
-            return resolveCurrentOutOrderDispatchDecision(currentStationId, wrkMast, outOrderStationIds, pathLenFactor);
+        if (isCurrentOutOrderDispatchStation(currentStationId, wrkMast, outOrderStationIds, pathLenFactor, decisionPathCache)) {
+            return resolveCurrentOutOrderDispatchDecision(currentStationId, wrkMast, outOrderStationIds, pathLenFactor, decisionPathCache);
         }
         if (!Objects.equals(dispatchStationId, wrkMast.getStaNo())
                 && isCurrentOutOrderStation(currentStationId, outOrderStationIds)
@@ -197,12 +199,35 @@
                                                         Integer sourceStationId,
                                                         Integer targetStationId,
                                                         Double pathLenFactor) {
+        return calcOutboundNavigatePath(wrkMast, sourceStationId, targetStationId, pathLenFactor, null);
+    }
+
+    private List<NavigateNode> calcOutboundNavigatePath(WrkMast wrkMast,
+                                                        Integer sourceStationId,
+                                                        Integer targetStationId,
+                                                        Double pathLenFactor,
+                                                        DecisionPathCache decisionPathCache) {
         Double normalizedFactor = normalizePathLenFactor(pathLenFactor);
         Integer currentTaskNo = wrkMast == null ? null : wrkMast.getWrkNo();
-        if (currentTaskNo == null) {
-            return navigateUtils.calcOptimalPathByStationId(sourceStationId, targetStationId, null, normalizedFactor);
+        if (decisionPathCache == null) {
+            if (currentTaskNo == null) {
+                return navigateUtils.calcOptimalPathByStationId(sourceStationId, targetStationId, null, normalizedFactor);
+            }
+            return navigateUtils.calcOptimalPathByStationId(sourceStationId, targetStationId, currentTaskNo, normalizedFactor);
         }
-        return navigateUtils.calcOptimalPathByStationId(sourceStationId, targetStationId, currentTaskNo, normalizedFactor);
+        String cacheKey = buildPathCacheKey(currentTaskNo, sourceStationId, targetStationId, normalizedFactor);
+        List<NavigateNode> cachedPath = decisionPathCache.pathMap.get(cacheKey);
+        if (cachedPath != null) {
+            return cachedPath;
+        }
+        List<NavigateNode> path = currentTaskNo == null
+                ? navigateUtils.calcOptimalPathByStationId(sourceStationId, targetStationId, null, normalizedFactor)
+                : navigateUtils.calcOptimalPathByStationId(sourceStationId, targetStationId, currentTaskNo, normalizedFactor);
+        if (path == null) {
+            path = Collections.emptyList();
+        }
+        decisionPathCache.pathMap.put(cacheKey, path);
+        return path;
     }
 
     private boolean isBatchOutboundTaskWithSeq(WrkMast wrkMast) {
@@ -246,7 +271,8 @@
     private boolean isCurrentOutOrderDispatchStation(Integer currentStationId,
                                                      WrkMast wrkMast,
                                                      List<Integer> outOrderStationIds,
-                                                     Double pathLenFactor) {
+                                                     Double pathLenFactor,
+                                                     DecisionPathCache decisionPathCache) {
         if (!shouldApplyOutOrder(wrkMast, outOrderStationIds) || currentStationId == null) {
             return false;
         }
@@ -255,7 +281,8 @@
                 wrkMast.getSourceStaNo(),
                 wrkMast.getStaNo(),
                 outOrderStationIds,
-                pathLenFactor
+                pathLenFactor,
+                decisionPathCache
         );
         return dispatchStationId != null
                 && !Objects.equals(dispatchStationId, wrkMast.getStaNo())
@@ -272,8 +299,9 @@
     private OutOrderDispatchDecision resolveCurrentOutOrderDispatchDecision(Integer currentStationId,
                                                                            WrkMast wrkMast,
                                                                            List<Integer> outOrderStationIds,
-                                                                           Double pathLenFactor) {
-        if (!isCurrentOutOrderDispatchStation(currentStationId, wrkMast, outOrderStationIds, pathLenFactor)) {
+                                                                           Double pathLenFactor,
+                                                                           DecisionPathCache decisionPathCache) {
+        if (!isCurrentOutOrderDispatchStation(currentStationId, wrkMast, outOrderStationIds, pathLenFactor, decisionPathCache)) {
             return null;
         }
 
@@ -299,7 +327,7 @@
 
         List<NavigateNode> initPath;
         try {
-            initPath = calcOutboundNavigatePath(wrkMast, wrkMast.getSourceStaNo(), wrkMast.getStaNo(), pathLenFactor);
+            initPath = calcOutboundNavigatePath(wrkMast, wrkMast.getSourceStaNo(), wrkMast.getStaNo(), pathLenFactor, decisionPathCache);
         } catch (Exception e) {
             News.taskInfo(wrkMast.getWrkNo(), "鎵规:{} 璁$畻鎺掑簭璺緞澶辫触锛屽綋鍓嶇珯鐐�={}", wrkMast.getBatch(), currentStationId);
             return null;
@@ -310,7 +338,7 @@
                 ? currentBatchSeq.equals(wrkMast.getBatchSeq())
                 : Integer.valueOf(seq + 1).equals(wrkMast.getBatchSeq());
         if (toTarget) {
-            if (hasReachableOutReleaseSlot(wrkMast, currentStationId, wrkMast.getStaNo(), pathLenFactor)) {
+            if (hasReachableOutReleaseSlot(wrkMast, currentStationId, wrkMast.getStaNo(), pathLenFactor, decisionPathCache)) {
                 return OutOrderDispatchDecision.direct(wrkMast.getStaNo());
             }
             StationTaskLoopService.LoopEvaluation loopEvaluation = evaluateOutOrderLoop(
@@ -323,7 +351,8 @@
                     currentStationId,
                     outOrderStationIds,
                     loopEvaluation.getExpectedLoopIssueCount(),
-                    pathLenFactor
+                    pathLenFactor,
+                    decisionPathCache
             );
             if (circleTarget == null) {
                 News.taskInfo(wrkMast.getWrkNo(), "鐩爣绔欏綋鍓嶄笉鍙繘锛屼笖鏈壘鍒板彲鎵ц鐨勪笅涓�鎺掑簭妫�娴嬬偣锛屽綋鍓嶇珯鐐�={}", currentStationId);
@@ -342,7 +371,8 @@
                 currentStationId,
                 outOrderStationIds,
                 loopEvaluation.getExpectedLoopIssueCount(),
-                pathLenFactor
+                pathLenFactor,
+                decisionPathCache
         );
         if (circleTarget == null) {
             News.taskInfo(wrkMast.getWrkNo(), "鏈壘鍒板彲鎵ц鐨勪笅涓�鎺掑簭妫�娴嬬偣锛屽綋鍓嶇珯鐐�={}", currentStationId);
@@ -377,7 +407,8 @@
                                                   Integer sourceStationId,
                                                   Integer finalTargetStationId,
                                                   List<Integer> outOrderList,
-                                                  Double pathLenFactor) {
+                                                  Double pathLenFactor,
+                                                  DecisionPathCache decisionPathCache) {
         if (finalTargetStationId == null) {
             return null;
         }
@@ -386,7 +417,7 @@
         }
 
         try {
-            List<NavigateNode> nodes = calcOutboundNavigatePath(wrkMast, sourceStationId, finalTargetStationId, pathLenFactor);
+            List<NavigateNode> nodes = calcOutboundNavigatePath(wrkMast, sourceStationId, finalTargetStationId, pathLenFactor, decisionPathCache);
             for (int i = nodes.size() - 1; i >= 0; i--) {
                 Integer stationId = getStationIdFromNode(nodes.get(i));
                 if (stationId == null) {
@@ -407,13 +438,14 @@
     private boolean hasReachableOutReleaseSlot(WrkMast wrkMast,
                                                Integer currentStationId,
                                                Integer finalTargetStationId,
-                                               Double pathLenFactor) {
+                                               Double pathLenFactor,
+                                               DecisionPathCache decisionPathCache) {
         if (currentStationId == null || finalTargetStationId == null) {
             return true;
         }
 
         try {
-            List<NavigateNode> nodes = calcOutboundNavigatePath(wrkMast, currentStationId, finalTargetStationId, pathLenFactor);
+            List<NavigateNode> nodes = calcOutboundNavigatePath(wrkMast, currentStationId, finalTargetStationId, pathLenFactor, decisionPathCache);
             if (nodes == null || nodes.isEmpty()) {
                 return true;
             }
@@ -462,7 +494,8 @@
                                                  Integer currentStationId,
                                                  List<Integer> orderedOutStationList,
                                                  Integer expectedLoopIssueCount,
-                                                 Double pathLenFactor) {
+                                                 Double pathLenFactor,
+                                                 DecisionPathCache decisionPathCache) {
         if (currentStationId == null || orderedOutStationList == null || orderedOutStationList.size() <= 1) {
             return null;
         }
@@ -477,7 +510,7 @@
                 continue;
             }
             try {
-                List<NavigateNode> path = calcOutboundNavigatePath(wrkMast, currentStationId, candidateStationId, pathLenFactor);
+                List<NavigateNode> path = calcOutboundNavigatePath(wrkMast, currentStationId, candidateStationId, pathLenFactor, decisionPathCache);
                 if (path != null && !path.isEmpty()) {
                     candidateList.add(new CircleTargetCandidate(candidateStationId, path.size(), offset));
                 }
@@ -609,7 +642,21 @@
         return pathLenFactor;
     }
 
+    private String buildPathCacheKey(Integer currentTaskNo,
+                                     Integer sourceStationId,
+                                     Integer targetStationId,
+                                     Double normalizedFactor) {
+        return String.valueOf(currentTaskNo) + "->"
+                + String.valueOf(sourceStationId) + "->"
+                + String.valueOf(targetStationId) + "@"
+                + String.format(java.util.Locale.ROOT, "%.4f", normalizedFactor == null ? 0.0d : normalizedFactor);
+    }
+
     private boolean isBlank(String value) {
         return value == null || value.trim().isEmpty();
     }
+
+    private static class DecisionPathCache {
+        private final Map<String, List<NavigateNode>> pathMap = new HashMap<>();
+    }
 }

--
Gitblit v1.9.1