A * path finding algorithm

Source: Internet
Author: User
Tags array definition

A * Brief introduction

Figure search technology in game programming everywhere, regardless of what type of game, figure search method inevitably become the foundation of game AI. For example, the following Dream West tour of their own initiative to find someone's function



A * search algorithm is a kind of graph search algorithm. Commonly known as a-star algorithm. This is a path that has multiple nodes on the graphics plane. Find the lowest pass cost algorithm. Often used for mobile computing of in-game NPCs. or online game bot for mobile computing.


Starting from Dijkstra single source shortest circuit algorithm

The Dijkstra (Dijkstra) algorithm is a typical shortest path routing algorithm. The shortest path used to calculate one node to all other nodes.

The main feature is to extend from the center of the starting point to the outer layer. Until the end of the extension. The Dijkstra algorithm can derive the optimal solution of the shortest path, but it is inefficient because it traverses a lot of compute nodes.
The Dijkstra algorithm is a typical shortest-path algorithm. In a very many professional courses as the basic content has a specific introduction. such as data structure, graph theory, operations research and so on.


The basic process of the algorithm is as follows:

Suppose there is a g=<v,e>. The source vertex is v0,u={v0},dist[i] records the shortest distance from V0 to I, Path[i] records a vertex in front of I from V0 to I path.

1. Select the vertex i with the lowest value of dist[i] from v-u and add I to u;

2. Update the dist value with the I directly adjacent vertex.

(Dist[j]=min{dist[j],dist[i]+matrix[i][j]})

3. Until u=v. Stop it.



C Language Implementation

DJK.C 2014.10.26 quan#include <stdio.h> #define INT_MAX 1000000#define maxn 1000//n-node count;//s-source node MAP[I][J]-The distance of I to J. I and J are Neighboring.//dist-record distance frome S//pre-record the prenodevoid djk (int n, int s, int map[maxn][max     N], int dist[maxn], int pre[maxn]) {int i,j,k;     int min;     int P[MAXN];          for (i = 1;i <= n;i++) {p[i] = 0;     if (i! = s) dist[i] = Map[s][i]; } Dist[s] = 0;     Array p as the mark for solution-set p[s] = 1;  for (i = 1;i <= n-1;i++) {min = Int_max;  K as the node which is the nearest to source and not marked k = 0; Find the node which is the nearest to source and not marked for (j = 1;j <= n;j++) {i                    F (!p[j]&&dist[j] < min) {min = dist[j];               K = J;  }}//no node available if (k = = 0) return;    First node      if (i = = 1) pre[k] = s;  Color the node p[k] = 1; Update Dist[j] for (j = 1; J <= N-1; j + +) {if (!p[j]&&map[k][j]! = Int_max&amp ; &dist[j] > Dist[k] + map[k][j]) {dist[j] = Dist[k] + map[k][j];//renew the Dista               NCE of Node J to the Solution-set pre[j] = k;     }}}}int Main () {int i,j,s = 2;     int n = 6;     int DIST[MAXN] = {0};     int PRE[MAXN] = {0};     int MAP[MAXN][MAXN];     Assign every path length to max.               for (i = 1; I <= N, i++) for (j = 1; J <= N; j + +) {Map[i][j] = Int_max;              }//assign the length of I to 0.      for (i = 1;i <= n;i++) {map[i][i] = 0;     } map[1][2] = 50;map[1][3] = 10;     MAP[1][5] = 45;map[2][3] = 15;     MAP[2][4] = 50;map[2][5] = 10;     MAP[3][1] = 20;map[3][4] = 15; MAP[4][2] = 20;map[4][5] = 35;     MAP[5][4] = 30;map[6][4] = 3;     DJK (n, 2, map, Dist, pre);     for (j = 1;j <= n;j++) {printf ("%d,%d:%d\n", S, J, Dist[j]); } return 0;}



Compile execution



A * algorithm

A * algorithm is an inspired search algorithm. Inspired search is the search in the state space to evaluate the location of each search, to get the best position. Then search from this location until the target. This can omit a large number of unnecessary search paths, improve efficiency. In an inspired search. The valuation of the position is very important.

Different valuations can have different effects.


The formula for A * algorithm is: F (n) =g (n) +h (n). G (n) represents the actual distance from the starting point to the random vertex N. H (n) represents the estimated distance from the random vertex N to the target vertex.

This formula follows the following characteristics:

Suppose H (n) is 0. Only g (n) is required, that is, the shortest path of starting point to random vertex n is obtained. is converted to single source shortest path problem. i.e. Dijkstra algorithm
assuming H (n) <= "N to the actual distance of the target", the optimal solution must be obtained.

And the smaller the H (N), the more nodes you need to compute. The less efficient the algorithm.


for function h (n), the method of estimating distances is often used:

Manhattan Distance: Defines the official meaning of the Manhattan distance for l1-distance or city block distance. That is, the sum of the distance from the projection of the axis generated by the two points on the fixed cartesian coordinates of Euclidean space. For example, on a plane. Coordinates (X1,Y1) point P1 with coordinates (x2, y2) points P2 the Manhattan distance: |x1-x2| + |y1-y2|.
Euclidean distance: is a usually used distance definition. It is the true distance between two points in m-dimensional space. The Euclidean distance in two and three-dimensional space is the distance between two points. For example, in the plane, the coordinates (X1,Y1) of the point P1 and coordinates (x2, y2) the point P2 Euclidean distance is: sqrt ((x1-x2) ^2+ (y1-y2) ^2).


Chebyshev Distance: is the maximum value of the difference between the two vectors. For example, in the plane, the coordinates (x1, y1) point P1 with the coordinates (x2, y2) of the point P2 the Chebyshev distance: Max (|x1-x2|, |y1-y2|).


The most important thing about a * algorithm is maintaining two lists, an open list, and a closed list. Algorithmic descriptive narratives such as the following

1, start from point A. and put it as a pending point into an "open list". Opening a list is like a shopping list. Although there is only one element in the list today. But there will be more of them later. Your path may pass through it including the squares, or it may not. Basically. This is a list of squares to check.
2, look for all reachable or accessible squares around the starting point, skipping walls, water, or other squares that cannot pass through the terrain.

Calculate the F,g,h. Add them to the open list. Save point A as a "parent square" for all of these squares. When we want to describe the narrative path, the data of the parent square is very important. The specific purpose of this will be explained later.


3. Remove point A from the open list. Add it to a "close list" and keep a list of all squares that do not need to be checked again.

4. Remove the node with the lowest F-value from the open list, and then add it to the close list.


5. Check all adjacent squares. Skip those that are already in the closed list or not (there are walls. The topography of the water. or other inaccessible terrain), calculate the f,g,h. Add them to the open list, assuming they're not there.

Use the selected squares as the parent of the new squares.
6. If an adjacent lattice is already open in the list, check to see if the path is better today. Other words. The check assumes that we have reached it with a new path. Whether the G value will be lower. Suppose not. Then do nothing.


Give a chestnut, for example, to



Now want to go from a to B, the middle of the black is a wall, cannot pass through. Set C to n points. Consider the f (n) of the C point




Here we use the Manhattan distance to calculate the estimate, the upper and lower left and right adjacent distance is 10. Diagonally adjacent is 14. Manhattan distance is in 10 units, for C. G (n) = A, h (n) = 40.


The next steps can be seen in the following animated demos.


Next is the C language implementation of the algorithm.

#include <stdio.h> #include <stdlib.h> #define Startnode1#define endnode2#define barrier3typedef struct Astarnode{int s_x;//Coordinate (finally output path required) int S_y;int s_g;//The distance from the beginning to this point (f can be obtained by G and H). Here F omitted. F=G+H) The ints_h;//revelation function predicts the distance from this point to the end of the Int s_style;//node type: The starting point. End point, obstacle struct Astarnode * s_parent;//parent node int s_is_in_closetable;//whether the int s_is_in_opentable;//in the close table is in the Open table} Astarnode, *pastarnode; Astarnode map_maze[10][10];//node array pastarnode open_table[100];//Open Table Pastarnode close_table[100];//close Table int Open_ node_count;//the number of nodes in the Open table int close_node_count;  The number of nodes in the close table Pastarnode path_stack[100];//save path stack int top = -1;//stack top//Swap two elements//void swap (int idx1, int idx2) {  Pastarnode tmp = open_table[idx1];open_table[idx1] = open_table[idx2];open_table[idx2] = tmp;} Heap adjustment//void adjust_heap (int/*i*/nindex) {int Curr = Nindex;int Child = Curr * 2 + 1;//get left kid idx (subscript starts from 0. All children are curr*2+1) int parent = (curr-1)/2;//Get parent idxif (NIndex < 0 | | NIndex >= open_node_count) {return;} Downward adjustmentThe whole (to be compared to the child and Cuur parent)//while (Children < Open_node_count) {//Keng Gen is the parent value less than the child value/if (Children + 1 < Open_node_count &amp ;& Open_table[child]->s_g + open_table[child]->s_h > open_table[child+1]->s_g + open_table[child+1]- >s_h) {++child;//infer left and right child size}if (open_table[curr]->s_g + open_table[curr]->s_h <= open_table[child]->s_g + Open_table[child]->s_h) {break;} Else{swap (Child, Curr);//Exchange Node Curr = child;//again infer the current child node, children = Curr * 2 + 1;//again infer left children}}if (curr! = NIndex) {return;} Adjust upwards (only cuur child and parent are needed)//while (Curr! = 0) {if (Open_table[curr]->s_g + open_table[curr]->s_h >= open_ Table[parent]->s_g + Open_table[parent]->s_h) {break;}  Else{swap (Curr, parent); Curr = Parent;parent = (curr-1)/2;}}}  Infer whether neighbor points can enter open Table//void insert_to_opentable (int x, int y, Pastarnode curr_node, Pastarnode end_node, int w) {int i;if ( Map_maze[x][y].s_style! = BARRIER)//Not an obstacle {if (!map_maze[x][y].s_is_in_closetable)//Not in the closed table {if (map_maze[x][y].s_is_ Inch_opentable)//in Open Table {//need to infer whether it is a more optimized path//if (Map_maze[x][y].s_g > Curr_node->s_g + W)//Assume more optimization {Map_maze[x][y].s_ g = curr_node->s_g + w;map_maze[x][y].s_parent = curr_node;for (i = 0; i < Open_node_count; ++i) {if (open_table[i ]->s_x = = Map_maze[x][y].s_x && open_table[i]->s_y = = map_maze[x][y].s_y) {break;}} Adjust_heap (i);//The following adjustment point}}else//not open {Map_maze[x][y].s_g = curr_node->s_g + W;map_maze[x][y].s_h = ABS (end_node-& GT;S_X-X) + ABS (end_node->s_y-y), map_maze[x][y].s_parent = Curr_node;map_maze[x][y].s_is_in_opentable = 1;open_ta ble[open_node_count++] = & (Map_maze[x][y]);}}}  Find a neighbor//pair up and down 8 neighbors to find//void Get_neighbors (Pastarnode curr_node, Pastarnode end_node) {int x = Curr_node->s_x;int y = curr_node->s_y;//below for 8 neighbors to process! if ((x + 1) >= 0 && (x + 1) < && y >= 0 && y <) {insert_to_opentable (x+ 1, y, Curr_node, End_node, 10);} if ((x-1) >= 0 && (x-1) < 10 && y >= 0 && y <) {insert_to_opentable (x-1, y, Curr_node, End_node, 10);} if (x >= 0 && x < && (y + 1) >= 0 && (y + 1) <) {insert_to_opentable (x, y+ 1, Curr_node, End_node, 10);} if (x >= 0 && x < && (y-1) >= 0 && (y-1) <) {insert_to_opentable (x, y 1, Curr_node, End_node, 10);} if ((x + 1) >= 0 && (x + 1) < && (y + 1) >= 0 && (y + 1) <) {Insert_to_ OpenTable (x+1, y+1, Curr_node, End_node, 14);} if ((x + 1) >= 0 && (x + 1) < && (y-1) >= 0 && (y-1) <) {Insert_to_ OpenTable (x+1, Y-1, Curr_node, End_node, 14);} if ((x-1) >= 0 && (x-1) < && (y + 1) >= 0 && (y + 1) <) {Insert_to_ OpenTable (X-1, y+1, Curr_node, End_node, 14);} if ((x-1) >= 0 && (x-1) < && (y-1) >= 0 &&Amp (y-1) <) {Insert_to_opentable (x-1, Y-1, Curr_node, End_node, 14);}} int main () {//Map array definition//astarnode *start_node;//start point astarnode *end_node;//end point Astarnode *curr_node;//current point int Is_fou nd;//find the path int maze[][10] ={//just for good assignment to map_maze{1,0,0,3,0,3,0,0,0,0},{0,0,3,0,0,3,0,3,0,3},{3,0,0,0,0,3,3,3,0,3}, {3,0,3,0,0,0,0,0,0,3},{3,0,0,0,0,3,0,0,0,3},{3,0,0,3,0,0,0,3,2,3},{3,0,0,0,0,3,3,0,0,0},{0,0,0,0,0,0,0,0,0,0},  {3,3,3,0,0,3,0,3,0,3},{3,0,0,0,0,3,3,3,0,3},};inti,j,x;//The following preparation point//for (i = 0; i <; ++i) {for (j = 0; j < 10; ++J) {map_maze[i][j].s_g = 0;map_maze[i][j].s_h = 0;map_maze[i][j].s_is_in_closetable = 0;map_maze[i][j].s_is_in_ OpenTable = 0;map_maze[i][j].s_style = maze[i][j];map_maze[i][j].s_x = I;map_maze[i][j].s_y = J;map_maze[i][j].s_ Parent = null;if (Map_maze[i][j].s_style = = startnode)//start {Start_node = & (Map_maze[i][j]);} else if (Map_maze[i][j].s_style = = Endnode)//end point {End_node = & (Map_maze[i][j]);} printf ("%d", maze[i][j]);} printf ("\ n");} The following uses a * algorithm to get the path//open_table[open_node_count++] = start_node;//start point increase open Table start_node->s_is_in_opentable = 1;// Add Open Table Start_node->s_g = 0;start_node->s_h = ABS (end_node->s_x-start_node->s_x) + ABS (End_node->s_y- start_node->s_y) start_node->s_parent = null;if (start_node->s_x = = End_node->s_x && start_node- >s_y = = end_node->s_y) {printf ("start = = end! \ n "); return 0;} Is_found = 0;while (1) {Curr_node = open_table[0];//The first point of the open table must be the point with the lowest F value (from the heap sort) open_table[0] = Open_table[--open_ node_count];//the last point to the first point. Then make heap adjustment adjust_heap (0);//Adjustment heap close_table[close_node_count++] = curr_node;//Current point add Close table Curr_node->s_is_in_ closetable = 1;//already in the close table if (curr_node->s_x = = End_node->s_x && curr_node->s_y = = end_node->s_y) The end point is in close. End {is_found = 1;break;} Get_neighbors (Curr_node, End_node);//handling of the neighbor if (Open_node_count = = 0)//no path arrives {is_found = 0;break;}} if (is_found) {printf ("Road founded!\n");p rintf ("Start NOde: (%d,%d) \ n ", Start_node->s_x, start_node->s_y);p rintf (" End node: (%d,%d) \ n ", End_node->s_x, end_node- >s_y); Curr_node = End_node;while (Curr_node) {Path_stack[++top] = Curr_node;curr_node = curr_node->s_parent;} while (Top > 0)//The following is the output path to see ~{if (Top > 0) {printf ("(%d,%d)--", Path_stack[top]->s_x, path_stack[top--]-> s_y);} Else{printf ("(%d,%d)", path_stack[top]->s_x, path_stack[top--]->s_y);}} printf ("(%d,%d)", path_stack[top]->s_x, path_stack[top]->s_y);} else{printf ("Find a Path");} Puts (""); return 0;}

Execution Result:



Relationships with other algorithms


A * algorithm that increments the minimum number of f (n) nodes from Openset each time to increase it in cloesedset. Extend adjacent nodes at the same time. Openset can be seen as a priority queue. The key value is f (n), the highest priority first-out.
The Dijkstra algorithm, each time the smallest node of G (N) is selected from Openset, increases it closedset, extending the neighboring node at the same time. The Openset can be viewed as a priority queue with a key value of g (n) and the highest priority first-out.


DFS algorithm. Each time from the Openset to select the latest increased node to increase its closedset, the same time to expand adjacent nodes, can be openset as a stack, LIFO.


BFS algorithm, each time from Opengset to select the first increased node to increase its closedset, the same time expand adjacent nodes. Openset can be regarded as a queue, FIFO.


References

A * pathfinding for beginners-http://www.gamedev.net/page/resources/_/technical/artificial-intelligence/ a-pathfinding-for-beginners-r2003

A * path search algorithm-http://blog.csdn.net/luckyxiaoqiang/article/details/6996963


Resources

A*,DIJKSTRA,BFS Path Search Algorithm Demo program-http://download.csdn.net/detail/walkinginthewind/3822153

A * path finding algorithm

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.