【问题标题】:Finding the Shortest Path in a 2D Integer Array Java在 2D 整数数组 Java 中查找最短路径
【发布时间】:2017-09-07 07:56:11
【问题描述】:

我正在制作一个蛇游戏,其中蛇穿过 2D int 数组作为其地形。存储在 2D 数组中的值表示穿越所需的时间(以秒为单位)。

例如,

int[][] MAP = { 
    { 1, 1, 1, 2, 2 },
    { 1, 2, 2, 2, 2 },
    { 3, 2, 2, 3, 1 },
    { 1, 1, 3, 2, 1 },
    { 1, 1, 3, 2, 1 }
 };

所以从map[0][0]map[0][4] 需要1 + 1 + 2 + 2 秒。我将如何制定一个算法来找到一条蛇从位置map[startX][startY]map[endX][endY] 的最短路径?

这不是家庭作业,我只是为了好玩而制作游戏,并想学习如何做到这一点。

【问题讨论】:

  • 似乎很容易使用具有最佳路径的蛮力进行修剪,并通过递归实现。您尝试了什么,问题出在哪里?
  • 你应该看看 A* 寻路。
  • 我查看了 A* 算法,但找不到任何解决方案,他们使用不同的值作为数组位置。大多数解决方案只有 1 和 0。
  • 这显然是一个约定俗成的问题;如果您在节点而不是边上有权重,您可以假设节点的所有入边都具有节点的权重。
  • 一个很好的 A* 寻路视频:here

标签: java arrays shortest-path dijkstra a-star


【解决方案1】:

这是一个在讨论“动态编程”时有点已知的问题,甚至类似于old post

不过,我没有找到同样打印最短路径的解决方案,所以:

public class FastestPathCalculator {

    private final int[][] map;

    public FastestPathCalculator(int[][] map) {
        this.map=map;
    }

    public static void main(String[] args) {
        int[][] map = new int[][]{
                {1, 1, 1, 4, 2},
                {1, 2, 5, 2, 2},
                {3, 2, 2, 3, 1},
                {1, 1, 3, 2, 1},
                {3, 1, 3, 2, 1}
        };

        FastestPathCalculator c = new FastestPathCalculator(map);
        boolean[] result = c.computeFastestPath(map);
        c.printPath(result);
    }

这里,布尔数组表示从 (0,0) 到 (4,4) 的步数。 TRUE 表示步骤向右,FALSE 表示向下。 在本例中,数组有 8 个单元格。

    public boolean[] computeFastestPath(int[][] map) {
        int pathLength = map.length + map[0].length - 2;
        boolean[] result = new boolean[pathLength];

        int[][] mapOfMinimalSums = buildMapOfMinimalSums();

        int x = map.length-1;
        int y = map[0].length-1;

        for (int i = pathLength - 1 ; i >= 0; i--) {
            if (x == 0)
                result[i] = true;
            else if (y == 0)
                result[i] = false;
            else if (mapOfMinimalSums[x][y] == map[x][y] + mapOfMinimalSums[x][y-1]) {
                result[i] = true;
                y--;
            }
            else {
                result[i] = false;
                x--;
            }
        }

        return result;
    }

    public void printPath(boolean[] result) {
        String[][] newPath = new String[map.length][map[0].length];
        int x = 0;
        int y = 0;

        newPath[x][y] = String.valueOf(map[x][y]);

        for (int i = 0 ; i < result.length; i++) {
            if (result[i]) {
                y++;
            } else {
                x++;
            }
            newPath[x][y] = String.valueOf(map[x][y]);
        }

        for (int i = 0 ; i < map.length; i++) {
            for (int j = 0 ; j < map[0].length; j++) {
                if (newPath[i][j] == null) {
                    System.out.print(" , ");
                } else {
                    System.out.print(newPath[i][j] + ", ");
                }
            }
            System.out.println();
        }
        System.out.println();
    }

    private int[][] buildMapOfMinimalSums() {
        int[][] mapOfSums = new int[map.length][map[0].length];
        for (int i = 0 ; i < map.length; i++) {
            for (int j = 0 ; j < map[0].length; j++) {
                if (i == 0 && j == 0)
                    mapOfSums[i][j] = map[i][j];
                else if (i == 0) {
                    mapOfSums[i][j] = mapOfSums[i][j - 1] + map[i][j];
                }
                else if (j == 0)
                    mapOfSums[i][j] = mapOfSums[i-1][j] + map[i][j];
                else
                    mapOfSums[i][j] = Math.min(mapOfSums[i-1][j], mapOfSums[i][j-1]) + map[i][j];
            }
        }
        return mapOfSums;
    }
}

【讨论】:

    猜你喜欢
    • 2012-01-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-11-12
    • 1970-01-01
    相关资源
    最近更新 更多