#
Junjie
20 小时以前 96f987b030f4c961a985f07079ba12abd865fdb2
src/main/java/com/zy/common/utils/NavigateSolution.java
@@ -10,6 +10,8 @@
import com.zy.common.model.NavigateNode;
import com.zy.core.enums.MapNodeType;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.BiFunction;
/**
 * A*算法实现类
@@ -23,9 +25,9 @@
    //用来存放已经出现过的结点。
    Map<String, Integer> bestGMap = new HashMap<>();
    public List<List<NavigateNode>> getStationMap() {
    public List<List<NavigateNode>> getStationMap(int lev) {
        BasMapService basMapService = SpringUtils.getBean(BasMapService.class);
        BasMap basMap = basMapService.selectOne(new EntityWrapper<BasMap>().eq("lev", 1));
        BasMap basMap = basMapService.selectOne(new EntityWrapper<BasMap>().eq("lev", lev));
        if (basMap == null) {
            throw new CoolException("地图不存在");
        }
@@ -63,9 +65,9 @@
        return navigateNodeList;
    }
    public List<List<NavigateNode>> getRgvTrackMap() {
    public List<List<NavigateNode>> getRgvTrackMap(int lev) {
        BasMapService basMapService = SpringUtils.getBean(BasMapService.class);
        BasMap basMap = basMapService.selectOne(new EntityWrapper<BasMap>().eq("lev", 1));
        BasMap basMap = basMapService.selectOne(new EntityWrapper<BasMap>().eq("lev", lev));
        if (basMap == null) {
            throw new CoolException("地图不存在");
        }
@@ -157,6 +159,115 @@
        return null;
    }
    public List<List<NavigateNode>> allSimplePaths(
            List<List<NavigateNode>> map,
            NavigateNode start,
            NavigateNode end,
            int maxDepth,    // 最大步数(边数). 建议:50/100/200;<=0 表示不限制(不建议)
            int maxPaths,    // 最大返回条数. 建议:100/500/2000;<=0 表示不限制(不建议)
            int maxCost      // 最大总代价(含拐点惩罚). <=0 表示不限制
    ) {
        List<List<NavigateNode>> results = new ArrayList<>();
        if (map == null || map.isEmpty() || map.get(0).isEmpty()) return results;
        if (start == null || end == null) return results;
        if (start.getValue() == MapNodeType.DISABLE.id || end.getValue() == MapNodeType.DISABLE.id) return results;
        // visited 用坐标 key,避免 NavigateNode equals/hashCode 不可靠导致重复判断失效
        Set<String> visited = new HashSet<>(map.size() * map.get(0).size() * 2);
        LinkedList<NavigateNode> path = new LinkedList<>();
        String startKey = keyOf(start);
        visited.add(startKey);
        path.add(start);
        AtomicInteger pathCount = new AtomicInteger(0);
        dfsAllSimplePaths(map, start, end,
                visited, path, results,
                0,  // depth
                0,  // cost
                maxDepth, maxPaths, maxCost,
                pathCount
        );
        return results;
    }
    /**
     * DFS + 回溯:枚举所有简单路径(路径中不允许重复节点)
     */
    private void dfsAllSimplePaths(
            List<List<NavigateNode>> map,
            NavigateNode current,
            NavigateNode end,
            Set<String> visited,
            LinkedList<NavigateNode> path,
            List<List<NavigateNode>> results,
            int depth,     // 当前步数(边数)
            int cost,      // 当前总代价(你可以认为是 g)
            int maxDepth,
            int maxPaths,
            int maxCost,
            AtomicInteger pathCount
    ) {
        // 防爆:条数限制
        if (maxPaths > 0 && pathCount.get() >= maxPaths) return;
        // 到达终点:收集路径
        if (current.getX() == end.getX() && current.getY() == end.getY()) {
            results.add(new ArrayList<>(path));
            pathCount.incrementAndGet();
            return;
        }
        // 防爆:深度限制(depth 表示已走的边数)
        if (maxDepth > 0 && depth >= maxDepth) return;
        // 扩展邻居(严格复用你自己的可行走方向规则)
        ArrayList<NavigateNode> neighbors = extend_current_node(map, current);
        if (neighbors == null || neighbors.isEmpty()) return;
        for (NavigateNode next : neighbors) {
            // 防爆:条数限制
            if (maxPaths > 0 && pathCount.get() >= maxPaths) return;
            if (next == null) continue;
            if (next.getValue() == MapNodeType.DISABLE.id) continue;
            String nk = keyOf(next);
            // 简单路径:不允许重复节点
            if (visited.contains(nk)) continue;
            // 你的代价规则:每步 1 + 拐点惩罚
            int stepCost = 1 + calcNodeExtraCost(current, next, end);
            int newCost = cost + stepCost;
            // 防爆:总代价限制
            if (maxCost > 0 && newCost > maxCost) continue;
            // 进入
            visited.add(nk);
            path.addLast(next);
            dfsAllSimplePaths(map, next, end,
                    visited, path, results,
                    depth + 1,
                    newCost,
                    maxDepth, maxPaths, maxCost,
                    pathCount
            );
            // 回溯
            path.removeLast();
            visited.remove(nk);
        }
    }
    private String keyOf(NavigateNode n) {
        return n.getX() + "_" + n.getY();
    }
    public ArrayList<NavigateNode> extend_current_node(List<List<NavigateNode>> map, NavigateNode current_node) {
        //获取当前结点的x, y
        int x = current_node.getX();