BFS wide search to solve the maze problem java implementation

content

1. Examples

Topic description

enter

output

Test Data 

2. Thought analysis

basic idea

Specific steps

 Code

3.BFS summary

Solving ideas:

Notice


1. Examples

Topic description

The maze consists of n rows and m columns of cells, each of which is either an open space or an obstacle. Among them, 1 represents an open space, which can be walked through, and 2 represents an obstacle. Given start coordinates startx, starty and end coordinates endx, endy. Now please find the shortest path length from the start point to the end point.

enter

The first line contains two integers n,m (1<=n,m<=1000). The next n lines, each containing m integers (values ​​1 or 2), represent this two-dimensional maze. The next line contains four integers startx, starty, endx, and endy, which represent the start and end coordinates, respectively.

output

If it is possible to get from the given start point to the end point, output the shortest path length, otherwise output NO. 

Test Data 

enter

5 4
1 1 2 1
1 1 1 1
1 1 2 1
1 2 1 1
1 1 1 2
Output

7

 watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5rGC5LiN6ISx5Y-R,size_20,color_FFFFFF,t_70,g_se,x_16

2. Thought analysis

basic idea

This question belongs to a more classic BFS graph breadth-first search algorithm example. Similar to a hierarchical search process, breadth-first search requires the use of a queue to maintain the order of visited nodes in order to visit their neighbors in that order . That is, it starts to spread from the given starting point to the surrounding , and judges whether it can reach the end point. If not, continue the BFS wide search until the end point can be reached or all nodes have been traversed. Define a flag variable to mark whether the end point is reached before searching.

Specific steps

1) Visit the initial node p and mark the node p as visited.

2) Node p enters the queue

3) When the queue is not empty, continue to execute, otherwise the algorithm ends.

4) Get out of the queue to get the head node first

5) Find the adjacent node newp in the first direction of the node first.

6) If the adjacent node newp of the node first does not exist, go to step 3: otherwise, execute the following three steps in a loop:
        6.1 If the node newp has not been visited and can go through, visit the node newp and mark it as access.
        6.2 The node newp is put into the queue
        6.3 The next adjacent node newp after the newp adjacent node of the node first is searched. Go to step 6

 Code

import java.util.LinkedList;
import java.util.Scanner;

public class Main {
	//n*m的地图,(startx,starty)起点坐标,(endx,endy)终点坐标
	static int n, m, startx, starty, endx, endy;
	static int[][] map;//地图
	static boolean[][] vistied;//标记当前点是否已经走过
	static int[][] step = { { 1, 0 }, { 0, 1 }, { -1, 0 }, { 0, -1 } };
	/*
	 * 上下左右移动遍历搜索 1 ,0 表示 x + 1 ,y + 0 向右移动,其他同理 如果为八向连通 则加上, { 1, 1 }, { 1, -1 }, {
	 * -1, 1 }, { -1, -1 } 代表斜向移动
	 */
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		n = sc.nextInt();
		m = sc.nextInt();
		map = new int[n + 2][m + 2];//+2是为了防止点在边界时,四方向移动造成下标出现-1越界。
		vistied = new boolean[n + 2][m + 2];
		// 录入数据图  下标(1~n)*(1~m)
		for (int i = 1; i <= n; i++) {
			for (int j = 1; j <= m; j++) {
				map[i][j] = sc.nextInt();
			}
		}
		//录入起点和终点坐标
		startx = sc.nextInt();
		starty = sc.nextInt();
		endx = sc.nextInt();
		endy = sc.nextInt();
		bfs(startx, starty);//BFS广搜
	}

	private static void bfs(int x, int y) {
		point p = new point(x, y, 0);//初始化point类封装x,y坐标以及step步数
		LinkedList<point> queue = new LinkedList<point>();//需要用到的队列
		queue.add(p);//将当前点入队列
		vistied[x][y] = true;//标记成已访问
		boolean flag = false;//是否达到终点标记
		//只要队列不为空,就说明还有路可走
		while (!queue.isEmpty()) {
			point first = queue.getFirst();//取出队列的第一个点
			if (first.x == endx && first.y == endy) {//判断当前点是否与终点坐标重合
				System.out.println(first.step);//打印需要走的步数
				flag = true;//标记已经到达终点
				break;//结束BFS
			}
			//未到达终点则进行上下左右四个方向移动
			for (int i = 0; i < 4; i++) {
				//横纵坐标变换实现位置移动
				int newx = first.x + step[i][0];
				int newy = first.y + step[i][1];
				int newstep = first.step + 1;//每一动一次步数要+1
				//判断移动后的新位置可以走,并且没走过
				if (map[newx][newy] == 1 && vistied[newx][newy] == false) {
					point newp = new point(newx, newy, newstep);//封装数据
					queue.add(newp);//入队列
					vistied[newx][newy] = true;//标记已经走过
				}
			}
			queue.removeFirst();//四个方向判断完成后,要将队首元素出列
		}
		if (!flag)//如果无法到达终点提示
			System.out.println("NO");
	}
}
//定义一个位置点的class,方便封装数据入队列
class point {
	int x;
	int y;
	int step;//从起点走到当前点需要走的步数

	public point(int x, int y, int step) {
		this.x = x;
		this.y = y;
		this.step = step;
	}
}

3.BFS summary

Solving ideas:

Add the expandable node of the team head node into the team, if there is no expandable node, the team head node is dequeued. Repeat the above steps until the target position is reached or the queue is empty.

Notice

The one that bfs finds first must be the shortest . But if it is a weighted edge, there will be a problem . The bfs returns the solution with the least number of edges, but because of the weighting, the distance from this solution to the root node is not necessarily the shortest. For example, 1000+1000 has only two segments, and 1+1+1+1 has 4 segments. Since bfs returns the solution with the least number of passing edges, the solution with a total length of 2000 will be returned here , which is obviously not the path with the shortest distance. BFS applies to queues.

Guess you like

Origin blog.csdn.net/qq_52360069/article/details/123508684