| | |
| | | private StationTaskTraceRegistry stationTaskTraceRegistry; |
| | | |
| | | public synchronized List<NavigateNode> calcByStationId(Integer startStationId, Integer endStationId) { |
| | | return calcByStationId(startStationId, endStationId, null); |
| | | return calcByStationId(startStationId, endStationId, null, false); |
| | | } |
| | | |
| | | public synchronized List<NavigateNode> calcByStationId(Integer startStationId, Integer endStationId, Integer currentTaskNo) { |
| | | return calcByStationId(startStationId, endStationId, currentTaskNo, false); |
| | | } |
| | | |
| | | public synchronized List<NavigateNode> calcReachablePathByStationId(Integer startStationId, Integer endStationId) { |
| | | return calcByStationId(startStationId, endStationId, null, true); |
| | | } |
| | | |
| | | private synchronized List<NavigateNode> calcByStationId(Integer startStationId, |
| | | Integer endStationId, |
| | | Integer currentTaskNo, |
| | | boolean reachabilityOnly) { |
| | | BasStation startStation = basStationService.getById(startStationId); |
| | | if (startStation == null) { |
| | | throw new CoolException("未找到该 起点 对应的站点数据"); |
| | |
| | | |
| | | startTime = System.currentTimeMillis(); |
| | | News.info("[WCS Debug] 站点路径权重开始分析,startStationId={},endStationId={}", startStationId, endStationId); |
| | | List<NavigateNode> list = findStationBestPathTwoStage(allList, resolvedPolicy, currentTaskNo); |
| | | List<NavigateNode> list = reachabilityOnly |
| | | ? findStationReachablePath(allList, resolvedPolicy, startStationId, endStationId) |
| | | : findStationBestPathTwoStage(allList, resolvedPolicy, currentTaskNo, startStationId, endStationId); |
| | | News.info("[WCS Debug] 站点路径权重分析完成,耗时:{}ms", System.currentTimeMillis() - startTime); |
| | | |
| | | //去重 |
| | |
| | | return new StationPathResolvedPolicy(); |
| | | } |
| | | |
| | | private List<NavigateNode> findStationReachablePath(List<List<NavigateNode>> allList, |
| | | StationPathResolvedPolicy resolvedPolicy, |
| | | Integer startStationId, |
| | | Integer endStationId) { |
| | | if (allList == null || allList.isEmpty()) { |
| | | return new ArrayList<>(); |
| | | } |
| | | |
| | | StationPathRuleConfig ruleConfig = resolvedPolicy.getRuleConfig() == null |
| | | ? new StationPathRuleConfig() |
| | | : resolvedPolicy.getRuleConfig(); |
| | | |
| | | List<List<NavigateNode>> filteredCandidates = applyRuleFilters(allList, ruleConfig, true); |
| | | if (filteredCandidates.isEmpty() && hasWaypoint(ruleConfig) && !strictWaypoint(ruleConfig)) { |
| | | filteredCandidates = applyRuleFilters(allList, ruleConfig, false); |
| | | News.info("[WCS Debug] 站点路径可达性规则已降级,忽略关键途经点约束后重试"); |
| | | } |
| | | if (filteredCandidates.isEmpty()) { |
| | | if (resolvedPolicy.matchedRule()) { |
| | | News.warn("站点路径规则命中但无可达路径,ruleCode={},startStationId={},endStationId={}", |
| | | resolvedPolicy.getRuleEntity() == null ? "" : resolvedPolicy.getRuleEntity().getRuleCode(), |
| | | startStationId, endStationId); |
| | | return new ArrayList<>(); |
| | | } |
| | | filteredCandidates = allList; |
| | | } |
| | | |
| | | filteredCandidates.sort((left, right) -> compareReachabilityPath(left, right)); |
| | | return filteredCandidates.isEmpty() ? new ArrayList<>() : filteredCandidates.get(0); |
| | | } |
| | | |
| | | private List<NavigateNode> findStationBestPathTwoStage(List<List<NavigateNode>> allList, |
| | | StationPathResolvedPolicy resolvedPolicy, |
| | | Integer currentTaskNo) { |
| | | Integer currentTaskNo, |
| | | Integer startStationId, |
| | | Integer endStationId) { |
| | | if (allList == null || allList.isEmpty()) { |
| | | return new ArrayList<>(); |
| | | } |
| | |
| | | if (metricsList.isEmpty()) { |
| | | if (globalPolicy.forceSkipPassOtherOutStation && skippedByOtherOutStation > 0) { |
| | | News.warn("[WCS Debug] 站点路径候选全部被过滤,因经过其他出库站点,startStationId={},endStationId={}", |
| | | resolvedPolicy.getRuleEntity() == null ? null : resolvedPolicy.getRuleEntity().getStartStationId(), |
| | | resolvedPolicy.getRuleEntity() == null ? null : resolvedPolicy.getRuleEntity().getEndStationId()); |
| | | startStationId, endStationId); |
| | | } else if (skippedByLoopMergeGuard > 0) { |
| | | News.warn("[WCS Debug] 站点路径候选全部被过滤,因分叉口插入环线主干会影响主干道,startStationId={},endStationId={}", |
| | | resolvedPolicy.getRuleEntity() == null ? null : resolvedPolicy.getRuleEntity().getStartStationId(), |
| | | resolvedPolicy.getRuleEntity() == null ? null : resolvedPolicy.getRuleEntity().getEndStationId()); |
| | | startStationId, endStationId); |
| | | } |
| | | return new ArrayList<>(); |
| | | } |
| | |
| | | return count; |
| | | } |
| | | |
| | | private int compareReachabilityPath(List<NavigateNode> left, List<NavigateNode> right) { |
| | | int leftLen = left == null ? Integer.MAX_VALUE : left.size(); |
| | | int rightLen = right == null ? Integer.MAX_VALUE : right.size(); |
| | | int leftTurnCount = countTurnCount(left); |
| | | int rightTurnCount = countTurnCount(right); |
| | | int leftLiftCount = countLiftTransferCount(left); |
| | | int rightLiftCount = countLiftTransferCount(right); |
| | | return compareDouble(leftLen, rightLen, leftTurnCount, rightTurnCount, leftLiftCount, rightLiftCount); |
| | | } |
| | | |
| | | private int countLiftTransferCount(List<NavigateNode> path) { |
| | | int count = 0; |
| | | for (NavigateNode node : safeList(path)) { |