17-BFS (breadth-first search algorithm)

 The BFS breadth-first search algorithm is the simplest graph search algorithm, which is often used to solve the shortest path problem of graphs with the same weight and constant.

Breadth-first algorithm (BFS)

BFS ( breadth-first search algorithm ) is different from DFS, which always finds leaf nodes once it searches. Its search logic is to search nodes layer by layer until the required data is found. Compared with DFS, BFS occupies more space, but it is still beneficial. Our commonly used shortest path algorithm comes from BFS.

 

The following is a common example to illustrate the application scenario of the BFS breadth search algorithm.

maze problem

Suppose we have a maze like the following, its entrance is on the upper left, and the exit is on the lower right. o is a grid that can be walked, and x is an obstacle that cannot be walked. Now our task is to find out the distance from the entrance to the exit. Need to go the shortest distance.

We can see that there are many paths from the entrance to the exit, but the distance between every two points is 1 (equal weight), but the red path is the shortest distance, and there are other lines like the green path:

 

We can try to use the BFS search algorithm: Assuming that the first point of the entry is the root node of the tree, our BFS search can be understood as searching for a node near the root node that meets the conditions (a point that can be moved once). In order to implement the above operations with code, we first need to make a chessboard and a dist array. Each element of the dist array stores the distance from the corresponding point on the chessboard to the entry node, and the l pair array stores the current value of each step. Point location:

#include<iostream>

using namespace std;

const int N = 100;
int n, m;
int chessboard[N][N];//棋盘布局
int dist[N][N];//当前点离起点的距离
pair<int, int> l[N];

int main()
{
	cin >> n >> m;
	for (int i = 0; i < n; i++)
	{
		for (int j = 0; j < m; j++)
		{
			cin >> chessboard[i][j];
		}
	}
	return 0;
}

The first step in the BFS function is to initialize the dist array first, that is, set the distance from each point to the root node of the entry to be -1, except that the root node itself is 0.

	for (int i = 0; i < n; i++)
	{
		for (int j = 0; j < m; j++)
			dist[i][j] = -1;
	}

We know that moving from one point to another, there are four situations for each type of movement, up, down, left, and right; each of our next moves requires four parts of the movement, but 1. The position that cannot be passed (with x obstacles) 2. The situation that has been passed before are discarded. Here we concretely instantiate the four operations into two arrays move_x and move_y, move_x[0], move_y[0] means to move one unit to the left; move_x[0], move_y[1] means to move one unit to the right; move_x[1 ], move_y[0] means move up one unit; move_x[1], move_y[1] mean move down one unit;

Every time we operate in the future, we only need to add the abscissa and ordinate of the current position to the array elements corresponding to the following table to represent four kinds of movements

	int move_x[4] = {-1,1,0,0};
	int move_y[4] = {0,0,1,-1};

We intend to put the current point of each step into a queue, so we also need to simulate a queue, of course, we can also use the queue in STL. Every time I take out the queue corresponding to a move on our chessboard, here we create a new pair, which stores the current position now_loct, and then assign the current element in the l array to this pair, and then assign The head of the l array is added, ready to receive the next new position.

Then this for loop is to try all four operations, and each new position is placed in another new team new-loct. However, only new positions that meet the six conditions are considered suitable and can be put into the queue. The six conditions are:

1. The new x position cannot cross the left border

2. The new y cannot be lower than the lower boundary

3. The new x position cannot exceed the right boundary

4. The new y cannot be higher than the upper boundary

5. The new position must be a walkable point on the chessboard

6. The new location cannot be the previous one

When the new position meets these conditions, it is valid, so update the total distance traveled between the new position and the old position, and put the new position into the queue.

while (hh <= tt)
	{
		pair<int, int> now_loct= l[hh++];
		//移动
		for (int p = 0; p < 4; p++)
		{
			pair<int, int>new_loct;
			new_loct.first = now_loct.first + move_x[p];
			new_loct.second = now_loct.second + move_y[p];
			if (new_loct.first >= 0 && new_loct.second >= 0 &&
				new_loct.first < n && new_loct.second < m &&
				chessboard[new_loct.first][new_loct.second] == 0 &&
				dist[new_loct.first][new_loct.second] == -1
				)
			{
				dist[new_loct.first][new_loct.second] = dist[now_loct.first]        [now_loct.second] + 1;
				l[++tt] = { new_loct.first,new_loct.second };
			}
		}
	}

Finally, return the distance of the lower right corner point (out point).

return dist[n-1][m-1];

So the total code is as follows:

#include<iostream>

using namespace std;

const int N = 100;
int n, m;
int chessboard[N][N];//棋盘布局
int dist[N][N];//当前点离起点的距离
pair<int, int> l[N];

int BFS()
{
	int hh=0, tt = 0;
	l[0] = { 0,0 };
	for (int i = 0; i < n; i++)
	{
		for (int j = 0; j < m; j++)
			dist[i][j] = -1;
	}
	dist[0][0] = 0;
	int move_x[4] = {-1,1,0,0};
	int move_y[4] = {0,0,1,-1};
	//模拟队列
	while (hh <= tt)
	{
		pair<int, int> now_loct= l[hh++];
		//移动
		for (int p = 0; p < 4; p++)
		{
			pair<int, int>new_loct;
			new_loct.first = now_loct.first + move_x[p];
			new_loct.second = now_loct.second + move_y[p];
			if (new_loct.first >= 0 && new_loct.second >= 0 &&
				new_loct.first < n && new_loct.second < m &&
				chessboard[new_loct.first][new_loct.second] == 0 &&
				dist[new_loct.first][new_loct.second] == -1
				)
			{
				dist[new_loct.first][new_loct.second] = dist[now_loct.first][now_loct.second] + 1;
				l[++tt] = { new_loct.first,new_loct.second };
			}
		}
	}
	return dist[n-1][m-1];
}

int main()
{
	cin >> n >> m;
	for (int i = 0; i < n; i++)
	{
		for (int j = 0; j < m; j++)
		{
			cin >> chessboard[i][j];
		}
	}
	cout<<BFS();
	return 0;
}

Guess you like

Origin blog.csdn.net/m0_61151031/article/details/129915157