BFS, bi-directional BFS and A * Table of Contents 1. BFS 2. Bidirectional BFS 3. A * algorithm
It is useless to say no practice, we from the well-known POJ 2243 this topic: The main idea: given a starting point and an end, according to the Knight's Way (Go Day), from the beginning to the end of the minimum move how many times
Set A to seek the beginning of the road, B is the destination end. 1 BFS
BFS is actually a degenerate a * algorithm, because he has no heuristic function to do the guidance Memory time 144K 407MS
The simple code is as follows:
#include <iostream> #include <queue> using namespace std;
Char ss[3];
Char ee[3];
typedef struct Node {int x;
int y;
int steps;
}node;
int d[8][2]={{-2,1},{-2,-1},{-1,-2},{-1,2},{2,-1},{2,1},{1,-2},{1,2}};
int visited[8][8];
node S;
Node E; int in (node N) {if (n.x<0| | n.y<0| | n.x>7| |
N.Y>7) return 0;
return 1;
} void BFs () {queue<node>q;
memset (visited,0,sizeof (visited));
Q.push (s);
Visited[s.x][s.y]=1;
while (!q.empty ()) {node St=q.front ();
Q.pop (); if (st.x==e.x&&st.y==e.y) {printf ("To get from%s to%s takes%d Knight moves.\n", Ss,ee,st.ste
PS);
Break
for (int i=0;i<8;++i) {node T;
T.X=ST.X+D[I][0];
T.Y=ST.Y+D[I][1];
if (in (t) &&visited[t.x][t.y]==0) {visited[t.x][t.y]=1;
t.steps=st.steps+1; Q.push (t);
int main (int argc, char *argv[]) {while (scanf ("%s%s", Ss,ee) ==2) {s.x=ss[0]-' a ';
s.y=ss[1]-' 1 ';
e.x=ee[0]-' a ';
e.y=ee[1]-' 1 ';
BFS ();
return 0;
}
2 bidirectional BFS
Two-way BFS is to use two queues, one queue to save from the beginning of the state, and another to save from the end point to start the search forward state, Bidirectional BFS is mainly to distinguish whether each lattice is searched from the starting point or from the end point. Each passing lattice node saves the number of steps that are passed through the grid, so that if the two sides intersect together, the result Memory time 144K 141MS
Obviously save time.
#include <iostream> #include <queue> using namespace std;
Char ss[3];
Char ee[3];
typedef struct Node {int x;
int y;
int steps;
}node;
int d[8][2]={{-2,1},{-2,-1},{-1,-2},{-1,2},{2,-1},{2,1},{1,-2},{1,2}};
int visited[8][8];
int color[8][8];//distinguishes which queue the current position is looking for node s;
Node E; int in (node N) {if (n.x<0| | n.y<0| | n.x>7| |
N.Y>7) return 0;
return 1; int BFs () {queue<node>qf;
I've found that if you put QF and QB out there, it saves a lot of time, 16MS queue<node>qb;
memset (visited,0,sizeof (visited));
memset (color,0,sizeof (color));
Qf.push (s);
Qb.push (e);
visited[s.x][s.y]=0;
Visited[e.x][e.y]=1;
color[s.x][s.y]=1;//coloring color[e.x][e.y]=2; while (!qf.empty () | |!
Qb.empty ()) {if (!qf.empty ()) {node St=qf.front ();
Qf.pop ();
for (int i=0;i<8;++i) {node T;
T.X=ST.X+D[I][0];
T.Y=ST.Y+D[I][1]; if (in (t)) {if (color[t.x][t.y]==0) {Visited[t.x]
[T.y]=visited[st.x][st.y]+1;
Color[t.x][t.y]=1;
Qf.push (t);
else if (color[t.x][t.y]==2) {return VISITED[ST.X][ST.Y]+VISITED[T.X][T.Y]; }} if (!qb.empty ()) {node St=qb.f
Ront ();
Qb.pop ();
for (int i=0;i<8;++i) {node T;
T.X=ST.X+D[I][0];
T.Y=ST.Y+D[I][1]; if (in (t)) {if (color[t.x][t.y]==0) {visited[t.x][t.y]=visited[
st.x][st.y]+1;
color[t.x][t.y]=2;
Qb.push (t); else if (color[t.x][t.y]==1) {returnVISITED[ST.X][ST.Y]+VISITED[T.X][T.Y];
int main (int argc, char *argv[]) {//Freopen ("In.txt", "R", stdin);
while (scanf ("%s%s", Ss,ee) ==2) {s.x=ss[0]-' a ';
s.y=ss[1]-' 1 ';
e.x=ee[0]-' a ';
e.y=ee[1]-' 1 ';
s.steps=0;
E.steps=1;
if (s.x==e.x&&s.y==e.y) printf ("To get from%s to%s takes 0 Knight moves.\n", Ss,ee);
else printf ("To get from%s to%s takes%d Knight moves.\n", Ss,ee,bfs ());
return 0;
}
3 A * algorithm
The key to choosing which squares to pass through the path is the following equation: F = g + H here: G = from beginning A, along the resulting path, move to the grid to specify the movement cost of the squares. H = The estimated move cost of moving from that square on the grid to end B. This is often called heuristic, and may be a bit confusing to you. The reason for this is that it's just a guess. We have no way of knowing the length of the path beforehand, as there may be obstacles (walls, water, etc.) on the road.
A * algorithm step is: To add the starting grid to the open list. Repeat the following: Find the grid with the lowest F value in the Open list. We call it the current lattice. Switch it to the close list. To each of the adjacent squares. If it is not available or is already in the closed list, skip it. The reverse is as follows. If it's not in the open list, add it. Take the current grid as the parent node of the grid. Record the f,g of this lattice, and the H value. If it is already in the open list, it is better to check the new path with the G value for reference. A lower g value means a better path. If so, change the parent node of the lattice to the current grid and recalculate the G and F values of the lattice. If you keep your open list sorted by F value, you may need to sort the open list again after the change. Stop, when you add the target to the close list, the path is found, or the target is not found, the open list is empty. At this point, the path does not exist. Save the path. Start with the target grid and move along the parent node of each cell until you return to the starting grid. This is your path.
It can be said that BFS is a special case of a * algorithm. For a BFS algorithm, each node extended from the current node (if not accessed) is put into the queue for further expansion. That is to say BFS's estimated function h is always equal to 0, without a little heuristic information, you can think that BFS is the "worst" * algorithm.
Select the minimum valuation: If you have studied the data structure, you should be able to know that the minimum priority queue (also known as the least binary heap) should be used for selecting the smallest valued node each time. In the C + + STL has the ready-made data structure priorityqueue, may use directly. Of course, don't forget to overload the comparison operator for the custom node. Memory Time 154K 47MS
But the above optimized bidirectional BFS (16MS)
#include <iostream> #include <queue> #include <stdlib.h> using namespace std;
Char ss[3];
Char ee[3];
typedef struct Node {int x;
int y;
int steps;
int g;
int h;
int F;
friend BOOL operator < (const node & a,const node &b);
}node; inline BOOL operator < (const node & a,const node &b) {return a.f>b.f;} int d[8][2]={{-2,1},{-2,-1},{-
1,-2},{-1,2},{2,-1},{2,1},{1,-2},{1,2}};
int visited[8][8];
node S;
Node E; int in (node N) {if (n.x<0| | n.y<0| | n.x>7| |
N.Y>7) return 0;
return 1; int heuristic (const node &a) {return (ABS (a.x-e.x) +abs (a.y-e.y)) *10;} Manhattan (Manhattan) valuation function priority_queue<node> q; Minimum priority queue (open list) Here's a bit of an optimization strategy, because I found that if you put Q//In the Astar function, the code runs 157MS, and the outside is 47MS,
There is a significant difference int Astar () {while (!q.empty ()) Q.pop ();
memset (visited,0,sizeof (visited));
Q.push (s); while (!q.empty ()) {node front=q.top ();
Node T;
Q.pop ();
Visited[front.x][front.y]=1;
if (front.x==e.x && front.y==e.y) return front.steps;
for (int i=0;i<8;i++) {t.x=front.x+d[i][0];
T.Y=FRONT.Y+D[I][1];
if (in (t) && visited[t.x][t.y]==0) {t.g=23+front.g;
T.h=heuristic (t);
T.f=t.g+t.h;
t.steps=front.steps+1;
Q.push (t);
int main (int argc, char *argv[]) {//freopen ("In.txt", "R", stdin);
while (scanf ("%s%s", Ss,ee) ==2) {s.x=ss[0]-' a ';
s.y=ss[1]-' 1 ';
e.x=ee[0]-' a ';
e.y=ee[1]-' 1 ';
s.steps=0;
s.g=0;
S.h=heuristic (s);
S.f=s.g+s.h;
if (s.x==e.x&&s.y==e.y) printf ("To get from%s to%s takes 0 Knight moves.\n", Ss,ee); else printf ("To get from%s to%s takes%d Knight moves.\n", Ss,ee,asTar ());
return 0;
}
This article extracts the most basic BFS and bidirectional BFS and the basic principle of a *, because the principle is not very difficult to understand and a graphical process, so you can grasp the principle of a one-time (although the text is quite brief, but there seems to be nothing to say), the rest of the hands-on problem. If you have any suggestions or criticisms and supplements, please leave a message, thank you for more information, please go to the Internet.
Author:kirchhoff
Created:2014-11-14 Fri 17:43
Emacs 24.4.1 (ORG mode 8.2.10)
Validate