【问题标题】:Shortest path in a 2d array using Dijkstra's algorithm?使用 Dijkstra 算法的二维数组中的最短路径?
【发布时间】:2012-10-15 00:35:36
【问题描述】:

这是我第一次实现 Dijkstra 算法。好的,我有一个简单的 2D 9 x 9 数组:

起点是 1,我们正试图到达任何绿色方块。红色方块是墙壁或熔岩(满足您的想象)。

如何在 Java 中实现这一点?

计算机科学不是我的领域,因此我不是一个经验丰富的程序员,所以我可能不知道如何做一些堆栈推送,只知道循环和递归:(请尽量保持简单并耐心等待!

【问题讨论】:

    标签: java shortest-path dijkstra


    【解决方案1】:

    这里有一些 similiar 可以帮助您入门。然而,下面提出的解决方案试图到达右下角。您可以放松该条件以找到底行。您还需要稍微更改编码以获得代表该行的唯一值。

    public class MazeSolver {
    
        final static int TRIED = 2;
        final static int PATH = 3;
    
        // @formatter:off
        private static int[][] GRID = { 
            { 1, 1, 1, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1 },
            { 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0, 1 },
            { 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0 },
            { 1, 1, 1, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1 },
            { 1, 0, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1 },
            { 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1 },
            { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
            { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 } 
        };
        // @formatter:off
    
        public static void main(String[] args) {
            MazeSolver maze = new MazeSolver(GRID);
            boolean solved = maze.solve();
            System.out.println("Solved: " + solved);
            System.out.println(maze.toString());
        }
    
        private int[][] grid;
        private int height;
        private int width;
    
        private int[][] map;
    
        public MazeSolver(int[][] grid) {
            this.grid = grid;
            this.height = grid.length;
            this.width = grid[0].length;
    
            this.map = new int[height][width];
        }
    
        public boolean solve() {
            return traverse(0,0);
        }
    
        private boolean traverse(int i, int j) {
            if (!isValid(i,j)) {
                return false;
            }
    
            if ( isEnd(i, j) ) {
                map[i][j] = PATH;
                return true;
            } else {
                map[i][j] = TRIED;
            }
    
            // North
            if (traverse(i - 1, j)) {
                map[i-1][j] = PATH;
                return true;
            }
            // East
            if (traverse(i, j + 1)) {
                map[i][j + 1] = PATH;
                return true;
            }
            // South
            if (traverse(i + 1, j)) {
                map[i + 1][j] = PATH;
                return true;
            }
            // West
            if (traverse(i, j - 1)) {
                map[i][j - 1] = PATH;
                return true;
            }
    
            return false;
        }
    
        private boolean isEnd(int i, int j) {
            return i == height - 1 && j == width - 1;
        }
    
        private boolean isValid(int i, int j) {
            if (inRange(i, j) && isOpen(i, j) && !isTried(i, j)) {
                return true;
            }
    
            return false;
        }
    
        private boolean isOpen(int i, int j) {
            return grid[i][j] == 1;
        }
    
        private boolean isTried(int i, int j) {
            return map[i][j] == TRIED;
        }
    
        private boolean inRange(int i, int j) {
            return inHeight(i) && inWidth(j);
        }
    
        private boolean inHeight(int i) {
            return i >= 0 && i < height;
        }
    
        private boolean inWidth(int j) {
            return j >= 0 && j < width;
        }
    
        public String toString() {
            String s = "";
            for (int[] row : map) {
                s += Arrays.toString(row) + "\n";
            }
    
            return s;
        }
    
    }
    

    【讨论】:

    • 我个人没有信心将代码发布到显然是作业问题的地方。这可能会降低学习效果:)
    • @Vespasian:公平地说,这不是完整的解决方案。此外,为什么这“显然是一个作业问题”?无论如何,网络上有许多解决方案。
    • 不想冒犯你。对不起,如果听起来像这样。他提供的图片给我的印象。当然,您对解决方案是正确的。
    • 作为记录,近 10 年后,这对我真的很有帮助,我什至没有做作业;)只需扩展这里的内容即可找到最佳可行路径。
    【解决方案2】:

    我建议您先在这里用自然语言写下一种应用 dijkstras 算法(假设您首先知道它)的方法,然后开始将其转换为您的编程语言。

    您需要回答的基本问题:

    • 什么是节点?
    • 有什么联系?
    • 每个连接的权重是多少?

    一旦你这样做了,你应该能够找到一个(可能不是有效的)解决方案。

    【讨论】:

    • 可以找到一个有效的解决方案:Dijkstra!看我的回答
    【解决方案3】:

    最佳解决方案确实是使用Dijkstra 或具有不同完成条件的AStar。所以你需要写if(targetNodes.contains(u)) break;而不是if(target == u) break;

    (参见维基百科:如果我们只对顶点源和目标之间的最短路径感兴趣,如果 u = target,我们可以在第 13 行终止搜索。)

    这已经在我的项目中实现了......哦,这是家庭作业;)?

    【讨论】:

    • 嘿,我正在尝试在游戏中实现 Dijkstra,你能帮我解决这个问题吗question
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-07-30
    • 2021-04-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多