#
Junjie
18 小时以前 103ca74d9b67ce4f766b5f77451741a76fa696b9
src/main/java/com/zy/common/utils/NavigateUtils.java
@@ -73,20 +73,40 @@
    private StationTaskTraceRegistry stationTaskTraceRegistry;
    public synchronized List<NavigateNode> calcByStationId(Integer startStationId, Integer endStationId) {
        return calcByStationId(startStationId, endStationId, null, false);
        return calcByStationId(startStationId, endStationId, null, null, false);
    }
    public synchronized List<NavigateNode> calcByStationId(Integer startStationId,
                                                           Integer endStationId,
                                                           Double pathLenFactor) {
        return calcByStationId(startStationId, endStationId, null, pathLenFactor, false);
    }
    public synchronized List<NavigateNode> calcByStationId(Integer startStationId, Integer endStationId, Integer currentTaskNo) {
        return calcByStationId(startStationId, endStationId, currentTaskNo, false);
        return calcByStationId(startStationId, endStationId, currentTaskNo, null, false);
    }
    public synchronized List<NavigateNode> calcByStationId(Integer startStationId,
                                                           Integer endStationId,
                                                           Integer currentTaskNo,
                                                           Double pathLenFactor) {
        return calcByStationId(startStationId, endStationId, currentTaskNo, pathLenFactor, false);
    }
    public synchronized List<NavigateNode> calcReachablePathByStationId(Integer startStationId, Integer endStationId) {
        return calcByStationId(startStationId, endStationId, null, true);
        return calcByStationId(startStationId, endStationId, null, null, true);
    }
    public synchronized List<List<NavigateNode>> calcCandidatePathByStationId(Integer startStationId,
                                                                              Integer endStationId,
                                                                              Integer currentTaskNo) {
        return calcCandidatePathByStationId(startStationId, endStationId, currentTaskNo, null);
    }
    public synchronized List<List<NavigateNode>> calcCandidatePathByStationId(Integer startStationId,
                                                                              Integer endStationId,
                                                                              Integer currentTaskNo,
                                                                              Double pathLenFactor) {
        StationPathSearchContext context = buildStationPathSearchContext(startStationId, endStationId);
        if (context.allList.isEmpty()) {
            return new ArrayList<>();
@@ -96,6 +116,7 @@
                context.allList,
                context.resolvedPolicy,
                currentTaskNo,
                pathLenFactor,
                startStationId,
                endStationId
        );
@@ -118,6 +139,7 @@
    private synchronized List<NavigateNode> calcByStationId(Integer startStationId,
                                                            Integer endStationId,
                                                            Integer currentTaskNo,
                                                            Double pathLenFactor,
                                                            boolean reachabilityOnly) {
        StationPathSearchContext context = buildStationPathSearchContext(startStationId, endStationId);
        if (context.allList.isEmpty()) {
@@ -125,7 +147,7 @@
        }
        List<NavigateNode> list = reachabilityOnly
                ? findStationReachablePath(context.allList, context.resolvedPolicy, startStationId, endStationId)
                : findStationBestPathTwoStage(context.allList, context.resolvedPolicy, currentTaskNo, startStationId, endStationId);
                : findStationBestPathTwoStage(context.allList, context.resolvedPolicy, currentTaskNo, pathLenFactor, startStationId, endStationId);
        return normalizeStationPath(list);
    }
@@ -274,9 +296,10 @@
    private List<NavigateNode> findStationBestPathTwoStage(List<List<NavigateNode>> allList,
                                                           StationPathResolvedPolicy resolvedPolicy,
                                                           Integer currentTaskNo,
                                                           Double pathLenFactor,
                                                           Integer startStationId,
                                                           Integer endStationId) {
        List<List<NavigateNode>> orderedPathList = orderStationPathCandidates(allList, resolvedPolicy, currentTaskNo, startStationId, endStationId);
        List<List<NavigateNode>> orderedPathList = orderStationPathCandidates(allList, resolvedPolicy, currentTaskNo, pathLenFactor, startStationId, endStationId);
        if (orderedPathList.isEmpty()) {
            return new ArrayList<>();
        }
@@ -286,6 +309,7 @@
    private List<List<NavigateNode>> orderStationPathCandidates(List<List<NavigateNode>> allList,
                                                                StationPathResolvedPolicy resolvedPolicy,
                                                                Integer currentTaskNo,
                                                                Double pathLenFactor,
                                                                Integer startStationId,
                                                                Integer endStationId) {
        if (allList == null || allList.isEmpty()) {
@@ -358,7 +382,8 @@
            return new ArrayList<>();
        }
        metricsList.sort((a, b) -> compareDouble(a.staticCost, b.staticCost, a.turnCount, b.turnCount, a.pathLen, b.pathLen));
        applyPathLengthPreference(metricsList, profileConfig, globalPolicy, pathLenFactor);
        metricsList.sort((a, b) -> compareStaticCandidateMetrics(a, b, pathLenFactor));
        PathCandidateMetrics preferred = metricsList.get(0);
        int maxLen = (int) Math.ceil(preferred.pathLen * safeDouble(profileConfig.getS1MaxLenRatio(), 1.15d));
        int maxTurns = preferred.turnCount + safeInt(profileConfig.getS1MaxTurnDiff(), 1);
@@ -381,8 +406,8 @@
            primaryMetrics = new ArrayList<>(primaryMetrics.subList(0, topK));
        }
        primaryMetrics.sort((a, b) -> compareDouble(a.dynamicCost, b.dynamicCost, a.pathLen, b.pathLen, a.turnCount, b.turnCount));
        secondaryMetrics.sort((a, b) -> compareDouble(a.dynamicCost, b.dynamicCost, a.pathLen, b.pathLen, a.turnCount, b.turnCount));
        primaryMetrics.sort((a, b) -> compareDynamicCandidateMetrics(a, b, pathLenFactor));
        secondaryMetrics.sort((a, b) -> compareDynamicCandidateMetrics(a, b, pathLenFactor));
        List<PathCandidateMetrics> remainingMetrics = new ArrayList<>();
        for (PathCandidateMetrics metrics : metricsList) {
@@ -390,7 +415,7 @@
                remainingMetrics.add(metrics);
            }
        }
        remainingMetrics.sort((a, b) -> compareDouble(a.dynamicCost, b.dynamicCost, a.pathLen, b.pathLen, a.turnCount, b.turnCount));
        remainingMetrics.sort((a, b) -> compareDynamicCandidateMetrics(a, b, pathLenFactor));
        List<List<NavigateNode>> orderedPathList = new ArrayList<>();
        appendCandidatePathList(orderedPathList, primaryMetrics);
@@ -661,9 +686,9 @@
        double congWeightFactor = globalPolicy == null ? 1.0d : globalPolicy.congWeightFactor;
        double passOtherOutStationPenaltyWeight = globalPolicy == null ? 0.0d : globalPolicy.passOtherOutStationPenaltyWeight;
        metrics.staticCost =
                safeDouble(profileConfig.getS1LenWeight(), 1.0d) * lenWeightFactor * metrics.pathLen
                        + safeDouble(profileConfig.getS1TurnWeight(), 3.0d) * metrics.turnCount
        metrics.baseLengthWeight = safeDouble(profileConfig.getS1LenWeight(), 1.0d) * lenWeightFactor;
        metrics.otherStaticCost =
                safeDouble(profileConfig.getS1TurnWeight(), 3.0d) * metrics.turnCount
                        + safeDouble(profileConfig.getS1LiftWeight(), 8.0d) * metrics.liftTransferCount
                        + passOtherOutStationPenaltyWeight * metrics.passOtherOutStationCount
                        + softDeviationWeight * metrics.softDeviationCount;
@@ -704,6 +729,105 @@
        int leftLiftCount = countLiftTransferCount(left);
        int rightLiftCount = countLiftTransferCount(right);
        return compareDouble(leftLen, rightLen, leftTurnCount, rightTurnCount, leftLiftCount, rightLiftCount);
    }
    private void applyPathLengthPreference(List<PathCandidateMetrics> metricsList,
                                           StationPathProfileConfig profileConfig,
                                           PathGlobalPolicy globalPolicy,
                                           Double pathLenFactor) {
        if (metricsList == null || metricsList.isEmpty()) {
            return;
        }
        double normalizedFactor = normalizePathLenFactor(pathLenFactor);
        int minPathLen = Integer.MAX_VALUE;
        int maxPathLen = Integer.MIN_VALUE;
        for (PathCandidateMetrics metrics : metricsList) {
            if (metrics == null) {
                continue;
            }
            minPathLen = Math.min(minPathLen, metrics.pathLen);
            maxPathLen = Math.max(maxPathLen, metrics.pathLen);
        }
        if (minPathLen == Integer.MAX_VALUE || maxPathLen == Integer.MIN_VALUE) {
            return;
        }
        double targetPathLen = normalizedFactor <= 0.0d || maxPathLen <= minPathLen
                ? minPathLen
                : minPathLen + normalizedFactor * (maxPathLen - minPathLen);
        for (PathCandidateMetrics metrics : metricsList) {
            if (metrics == null) {
                continue;
            }
            metrics.pathLenPreferenceDistance = normalizedFactor <= 0.0d
                    ? metrics.pathLen
                    : Math.abs(metrics.pathLen - targetPathLen);
            metrics.staticCost = metrics.baseLengthWeight * metrics.pathLenPreferenceDistance + metrics.otherStaticCost;
        }
    }
    private int compareStaticCandidateMetrics(PathCandidateMetrics left,
                                              PathCandidateMetrics right,
                                              Double pathLenFactor) {
        if (left == right) {
            return 0;
        }
        if (left == null) {
            return 1;
        }
        if (right == null) {
            return -1;
        }
        int result = Double.compare(left.staticCost, right.staticCost);
        if (result != 0) {
            return result;
        }
        result = Double.compare(left.pathLenPreferenceDistance, right.pathLenPreferenceDistance);
        if (result != 0) {
            return result;
        }
        result = Integer.compare(left.turnCount, right.turnCount);
        if (result != 0) {
            return result;
        }
        return comparePathLenTie(left.pathLen, right.pathLen, pathLenFactor);
    }
    private int compareDynamicCandidateMetrics(PathCandidateMetrics left,
                                               PathCandidateMetrics right,
                                               Double pathLenFactor) {
        if (left == right) {
            return 0;
        }
        if (left == null) {
            return 1;
        }
        if (right == null) {
            return -1;
        }
        int result = Double.compare(left.dynamicCost, right.dynamicCost);
        if (result != 0) {
            return result;
        }
        result = Double.compare(left.pathLenPreferenceDistance, right.pathLenPreferenceDistance);
        if (result != 0) {
            return result;
        }
        result = comparePathLenTie(left.pathLen, right.pathLen, pathLenFactor);
        if (result != 0) {
            return result;
        }
        return Integer.compare(left.turnCount, right.turnCount);
    }
    private int comparePathLenTie(int leftPathLen, int rightPathLen, Double pathLenFactor) {
        double normalizedFactor = normalizePathLenFactor(pathLenFactor);
        if (normalizedFactor <= 0.0d) {
            return Integer.compare(leftPathLen, rightPathLen);
        }
        if (normalizedFactor >= 0.5d) {
            return Integer.compare(rightPathLen, leftPathLen);
        }
        return Integer.compare(leftPathLen, rightPathLen);
    }
    private int countLiftTransferCount(List<NavigateNode> path) {
@@ -1753,6 +1877,19 @@
        return value == null ? defaultValue : value;
    }
    private double normalizePathLenFactor(Double pathLenFactor) {
        if (pathLenFactor == null) {
            return 0.0d;
        }
        if (pathLenFactor < 0.0d) {
            return 0.0d;
        }
        if (pathLenFactor > 1.0d) {
            return 1.0d;
        }
        return pathLenFactor;
    }
    private boolean notBlank(String text) {
        return text != null && !text.trim().isEmpty();
    }
@@ -1935,6 +2072,9 @@
        private int runBlockCount;
        private int softDeviationCount;
        private double loopPenalty;
        private double baseLengthWeight;
        private double otherStaticCost;
        private double pathLenPreferenceDistance;
        private double staticCost;
        private double dynamicCost;
    }