Кратчайший путь скольжения между бинарными клетками - PullRequest
0 голосов
/ 28 февраля 2020

Я пытался найти кратчайший путь скольжения между двоичными ячейками (0 или 1) в двоичной сетке / матрице. Это немного отличается от кратчайшего пути в соседней матрице (вверх, вниз, влево, вправо). Я использую BFS, чтобы найти кратчайший путь в соседней матрице. Точно так же я думаю, что могу скользить в макс. Смежных направлениях, посещать одновременно или посещать после макс. Смежного слайда, но ни один из них не кажется правильным. Если я пытаюсь скользить в максимально соседнем направлении, то у меня нет кратчайшего пути скольжения. Как еще я могу подойти к этому?

import java.util.LinkedList;

public class ShortestSlidingPathBetweenCellsBFS {

    static final int BINARY_BLOCK = 1;

    private static class Cell  {
        int x;
        int y;
        int dist;   //distance
        Cell prev;  //parent / last visited cell in the path

        Cell(int x, int y, int dist, Cell prev) {
            this.x = x;
            this.y = y;
            this.dist = dist;
            this.prev = prev;
        }

        @Override
        public String toString(){
            return "(" + x + "," + y + ")";
        }
    }

    //BFS, Time O(n^2), Space O(n^2)
    public static void shortestPath(int[][] matrix, int[] start, int[] end) {
        int sx = start[0], sy = start[1];
        int dx = end[0], dy = end[1];

        //if start or end value is 0, return
        if (matrix[sx][sy] == BINARY_BLOCK || matrix[dx][dy] == BINARY_BLOCK)
            return;

        int m = matrix.length;
        int n = matrix[0].length;
        Cell[][] cells = new Cell[m][n];
        for (int i = 0; i < m; i++) {
            for (int j = 0; j < n; j++) {
                if (matrix[i][j] != BINARY_BLOCK) { // if cell can be visited
                    cells[i][j] = new Cell(i, j, Integer.MAX_VALUE, null); // init cell element with default Cell
                }
            }
        }

        LinkedList<Cell> queue = new LinkedList<>();
        Cell src = cells[sx][sy];
        src.dist = 0;
        queue.add(src);
        Cell dest = null;
        Cell present; // present cell
        // while queue
        while ((present = queue.poll()) != null) {
            //find destination
            if (present.x == dx && present.y == dy) {
                dest = present;
                break;
            }

            while (present.x != BINARY_BLOCK) {
                present.x -= 1;
            }
            visit(cells, queue, present.x, present.y, present);

            // moving down
            while (present.x != BINARY_BLOCK) {
                present.x += 1;
            }
            visit(cells, queue, present.x, present.y, present);

            // moving left
            while (present.y != BINARY_BLOCK) {
                present.y -= 1;
            }
            visit(cells, queue, present.x, present.y, present);

            //moving right
            while (present.y != BINARY_BLOCK) {
                present.y += 1;
            }
        }

        if (dest == null) {
            return;
        } else { // print out shortest path
            LinkedList<Cell> path = new LinkedList<>();
            present = dest;
            do {
                path.addFirst(present);
            } while ((present = present.prev) != null);
            System.out.println(path);
        }
    }

    //function to update cell visiting status
    static void visit(Cell[][] cells, LinkedList<Cell> queue, int x, int y, Cell parent) {
        if (x < 0 || x >= cells.length || y < 0 || y >= cells[0].length || cells[x][y] == null) {
            return;
        }

        int dist = parent.dist + 1;
        Cell present = cells[x][y];
        if (dist < present.dist) {
            present.dist = dist;
            present.prev = parent;
            queue.add(present);
        }
    }

    public static void main(String[] args) {
        int[][] matrix1 = {
                {0, 0, 1, 0},
                {1, 0, 0, 0},
                {0, 0, 0, 0},
                {1, 1, 0, 0}
        };
        int[] start1 = {1, 1};
        int[] end1 = {3, 3};
        shortestPath(matrix1, start1, end1);

        int[][] matrix2 = {
                {0, 0, 1, 0},
                {1, 0, 1, 0},
                {0, 0, 0, 0},
                {1, 1, 0, 0}
        };
        int[] start2 = {1, 1};
        int[] end2 = {3, 3};
        shortestPath(matrix2, start2, end2);
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...