BFS, two-way BFS and A *

Source: Internet
Author: User

BFS, bidirectional BFs and a*table of Contents
    • 1. BFS
    • 2. Two-way BFS
    • 3. A * algorithm

It is useless to say or not to practise. We start with the well-known POJ 2243 topic: Given a starting point and an end point. The minimum number of moves from the starting point to the end point, according to the Knight's Walk (the word of the day)

watermark/2/text/ahr0cdovl2jsb2cuy3nkbi5uzxqvd2rraxjjaghvzmy=/font/5a6l5l2t/fontsize/400/fill/i0jbqkfcma==/ Dissolve/70/gravity/center ">

Set A to the start of the pathfinding and B as the destination end point.

1BFS

BFS is in fact a degenerate * algorithm. As he has no revelation function to guide

Time
Memory
144K 407MS

Simple code such as the following:

#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&GT;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.steps            );        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;}
2Two-way BFS

A two-way BFS is a two queue. A queue is saved from the beginning of the start of the state, there is a state to save from the end of the forward search, the two-way BFS is mainly to distinguish between each grid from the beginning of the search or from the end of the search. The number of steps that each pass through the lattice node is saved to the grid. So if both sides intersect, the sum is the result.

Time
Memory
144K 141MS

Obvious time-saving

#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 the current position from which queue was searched for node S;node e;int in (node N) {if (n.x<0| | n.y<0| | n.x>7| |    N.Y&GT;7) return 0; return 1;}                          int BFs () {queue<node>qf; I found that if I put the QF and QB outside.    The time saved is amazing and takes 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.front ();            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) {return VISITED[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;}
3A * algorithm

The key to choosing which squares to pass through in 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 = Estimated movement cost of moving from that square on the grid to end B.

      This is often called a revelation, and may confuse you.

      The reason for this is because it's just a push. We have no way of knowing the length of the path beforehand, because there may be various obstacles (wall, water). And so on).

The * algorithm steps are:

    • Add the start grid to the open list.

    • Repeat for example the following work:
      • Look for 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 lattices?
        • Suppose it is not passed or is already in the closed list, skipping it. Instead, for example, the following.
        • Let's say it's not in the open list, add it.

          Use the current grid as the parent node for this grid. Record the f,g, and H values for this grid.

        • Suppose it is already in the open list. Check if the new path is better with the G value. A lower G-value means a better path. Suppose so, the parent node of this lattice is changed to the current grid, and the G and F values of this lattice are computed again. Suppose you keep your open list sorted by F-value, and you may need to sort the open list again after the change.
      • Stop it. When you
        • The target is added to the close list. The path is then found. Or
        • No target is found, the open list is empty.

          At this time, the path does not exist.

    • Save the path. Start with the target and move along the parent node of each cell until you return to the start grid.

      This is your path.

To be able to say this, BFS is a special case of a * algorithm.

For a BFS algorithm, each node that is extended from the current node (assuming no access has been asked) is put into the queue for further expansion. In other words, the expected function H of BFS is always equal to 0. There is no hint of information. Can feel that BFS is the "worst" a * algorithm.

Select the minimum estimate: If you have learned the data structure. You should be able to know the node that selects the minimum value for each time. The minimum priority queue (also called the Least-squares heap) should be used. In C + + STL There is a ready-made data structure priorityqueue. can be used directly. Of course, don't forget to reload the comparison operator that defines the node.

Time
Memory
154K 47MS

Just above optimized two-way 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&GT;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) There's a bit of an optimization strategy here, because I found the hypothesis to put Q//in the Astar function. The code runs up to 157MS, and the outside word is 47MS.    There are notable differences in the 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 main implementation of BFS and two-way BFS and the basic principle of a *. Because the principle is not very difficult to understand and graphical process, so can master the principle of one-time (although the introduction of the text is quite brief, just as if there is nothing to say). The remaining hands-on problem.

If you have any suggestions or criticisms and additions, please leave a message stating that it is appreciated that many other references please visit the Internet.

Author:kirchhoff

Created:2014-11-14 Fri 17:43

Emacs 24.4.1 (ORG mode 8.2.10)

Uri=referer ">validate

Copyright notice: This article Bo Master original articles, blogs, without consent may not be reproduced.

BFS, two-way BFS and A *

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.