简体   繁体   中英

BFS Maze doesn't show shortest path only

I'm currently working on a little maze solver project where you find the shortest path in a maze so as to get a better understanding of path searching algorithms, like in this example the breadth-first search algorithm. My implementation of it uses a boolean visitation matrix to mark visited cells to avoid repeating steps, it then works in the following steps.

Step 1 - Uses visitation queue to holds the adjacent cells.

Step 2 - Removes the cell at the front of the queue and adds it to a visitation list, increments steps variable.

Step 3 - Checks adjacent cells and if they aren't walls and they aren't visited, they'll be added to the visitation queue.

Step 4 - Repeat steps 2 and step 3 until the entire queue is empty.

The breadth-first search implementation works and it turns paths(ie 0s) into visited paths(ie 2s) but I'm having the problem where I can't get it to decrements distance(variable) to goal and change dead end paths back 0s so that it only shows the shortest path and shortest amount of steps needed to reach it? Maybe some fresh new eyes will see what it is that I'm missing. Thanks in advance!

It turns out like this: BFS 有问题

Instead of this: BFS 固定

BFS Maze solver implementation

import java.util.LinkedList;
import java.util.Queue;

public class BFS {
    
    private static int distance = 0;
    
    // Solves given maze iteratively, input starting position in maze and size of the maze.
    public static boolean solve(int[][] maze, int x, int y, int sizeX, int sizeY) {
        
        boolean[][] visited = new boolean[sizeX][sizeY];
        Queue<Point> vQueue = new LinkedList<Point>();
        vQueue.add(new Point(x, y, null));
        
        while (!vQueue.isEmpty()) {
            distance++;
            Point p = vQueue.remove();
            visited[p.x][p.y] = true;
            
            // 3 is the cell the algorithm is supposed to find.
            if (maze[p.x][p.y] == 3) {
                maze[p.x][p.y] = 2;
                System.out.println("Shortest path has "+ distance + " steps.");
                return true;
            }
            
            maze[p.x][p.y] = 2;
            // Down.
            if (visited[p.x-1][p.y] == false && (maze[p.x-1][p.y] == 0 || maze[p.x-1][p.y] == 3)) {
                Point nextPoint = new Point(p.x-1, p.y, p);
                vQueue.add(nextPoint);
            }
            
            // Up.
            if (visited[p.x+1][p.y] == false  && (maze[p.x+1][p.y] == 0 || maze[p.x+1][p.y] == 3)) {
                Point nextPoint = new Point(p.x+1, p.y, p);
                vQueue.add(nextPoint);
            }
            
            // Right.
            if (visited[p.x][p.y+1] == false  && (maze[p.x][p.y+1] == 0 || maze[p.x][p.y+1] == 3)) {
                Point nextPoint = new Point(p.x, p.y+1, p);
                vQueue.add(nextPoint);
            }
            
            // Left.
            if (visited[p.x][y-1] == false  && (maze[p.x][p.y-1] == 0 || maze[p.x][p.y-1] == 3)) {
                Point nextPoint = new Point(p.x, p.y-1, p);
                vQueue.add(nextPoint);
            }
        }
        
        return false;
    }
    
    // Node class that holds current position and visitation list.
    private static class Point{
        int x;
        int y;
        Point parent;
        
        public Point(int x, int y, Point parent) {
            this.x = x;
            this.y = y;
            this.parent = parent;
        }
        
        
    }
    
}

Test Maze

public class TestMazeDFS {
    private static int[][] maze = {
            {1, 1, 1, 1, 1, 1, 1, 1, 1},        
            {1, 0, 0, 0, 0, 0, 0, 0, 1},
            {1, 0, 1, 0, 1, 1, 1, 1, 1},
            {1, 0, 1, 0, 0, 0, 0, 0, 1},
            {1, 1, 1, 1, 1, 0, 1, 0, 1},
            {1, 0, 0, 0, 1, 0, 1, 0, 1},
            {1, 0, 1, 1, 1, 1, 1, 0, 1},
            {1, 0, 0, 0, 0, 0, 0 ,3, 1},
            {1, 1, 1, 1, 1, 1, 1, 1, 1},
        };
    
    public int[][] getMaze(){
        
        return this.maze;
    }
    
    // prints the maze.
    public static void printMaze() {
        for (int i = 0; i < 9; i++) {
            for (int j = 0; j < 9; j++) {
//              if (maze[i][j] == 1) {
//                  System.out.print('#');
//              } else {
//                  System.out.print(' ');
//              }
                System.out.print(maze[i][j]);
            }
            System.out.println();
        }
        System.out.println();
    }
    
    public static void main(String[] args) {
        TestMazeDFS maze = new TestMazeDFS();
        boolean test = BFS.solve(maze.getMaze(), 1, 1, 9, 9);
        System.out.println(test);
        printMaze();
        
    }
}

I am not sure how you thought to output the shortest path. But an alternative approach would be to use an integer matrix, instead of a boolean matrix. Then record in each cell how far away from the start it is.

That is, when processing a point, read the current distance to the start from the integer matrix. Then determine all its valid neighbours that still have a distance 0 in their cells, write the current distance + 1 into those cells, and add them to the queue.

At the end, you can then find the shortest path by backtracking from goal, following the path that decreases with 1 every step.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM