Astar path search

Source: Internet
Author: User
Abstract:

There is a type of problem in artificial intelligence that involves definite solutions, such as paths and wuziqi. Such problems are very suitable for the use of search to solve. Path search is a very interesting problem, which is a basic problem in AI. I have been reading artificial intelligence-a modern approach recently. The most impressive part of the search is astar.AlgorithmThis is also the most commonly used in game development. So let's make a summary. I will go through this article tomorrow.

Path search algorithm: Dijkstra:

The Dijkstra shortest path algorithm has been mentioned in university Data Structure textbooks. I will not go into details here. However, in order to compare it with the following algorithms, I Google a graph to directly display the search process of the Dijkstra algorithm:

In the figure, the center is taken as the starting point, and the radiation is constantly searched out of the center (each time the point closest to the starting point), expanding outward in a circle until approaching the target point to complete the path search.

Best-first-Search:

BSF selects the node closest to the target for each expansion. Dijkstra selects the node closest to the data starting point each time. The difference is that the distance from the start point is always known, and the distance from the end point can only be estimated. Therefore, BSF provides a heuristic function H. Common heuristic functions H include:

    • Calculate the absolute distance from the current node to the target point based on the absolute distance (this path is not available at this time, and may be blocked)
    • Based on the direction, if the target is in the East, it will only expand to the southeast, east, and Northeast directions. In the case of few obstacles, BSF can quickly and directly search for the target. If the path direction is changed due to obstruction, BSF does not necessarily find the nearest path.
A Star Algorithm

The A star algorithm combines Dijkstra accuracy and BSF speed. When searching for a path, the heuristic function H is used to calculate the distance between the current node and the target node, while the distance from the Start Node to the current node is known, then, the minimum node F = G + H is selected each time. Astar always tries to find the shortest path, and the performance is close to BSF when there are few obstacles.

Principle of A-Star Algorithm

 

A Star Algorithm Implementation Main logic implementation:

 Int Astar_t: search_path (uint32_t from_index, uint32_t to_index, vector <uint32_t> & Path _)
{
// ! Save nodes to be extended in the Open Table
// ! Visited saves the accessed nodes for this search. After the search is completed, the status of the accessed nodes is restored to the default status.
Open_table_t open;
Vector <map_node_t *> visited;

Search_node_t current;
Search_node_t neighbor_node;
Vector <map_node_t *> neighbors;

// ! First, add the start point to the Open table.
Current. set_pos_index (from_index );
Open. insert (current );

Visited. push_back (m_map.get_node (current. get_pos_index ()));

// ! Large Loop until open is empty (the target cannot be found) or the target is found
While ( False = Open. Empty ()){
Open. pop_first (current );

If (Current. get_pos_index () = to_index)
{
Break ;
}

// ! Add to close table
M_map.get_node (current. get_pos_index ()-> set_closed ();

// ! Find all neighboring nodes of the current node. The function implementation may be different in different games.
// ! Some games can take diagonal lines, while some cannot. For example, a tank war cannot take diagonal lines.
M_map.get_neighbors (current. get_pos_index (), neighbors );

For (Size_t I = 0 ; I <neighbors. Size (); ++ I)
{
Map_node_t * neighbor_map_node = neighbors [I];
Neighbor_node.set_pos_index (neighbor_map_node-> get_pos_index ());

// ! Calculate the G and H values of the vertex.
Neighbor_node.set_gval (m_map.distance (current. get_pos_index (), neighbor_map_node-> get_pos_index ()));
Neighbor_node.set_hval (m_map.heuristic (neighbor_map_node-> get_pos_index (), to_index ));

// ! If this point is already in the Open table, check the G value. If the G value is smaller, it indicates that the current path is closer and the Open table is updated.
If ( True = Neighbor_map_node-> is_open ())
{
If (Neighbor_node.get_gval () <neighbor_map_node-> get_gval ())
{
Open. Update (neighbor_map_node-> get_fval (), neighbor_node );
Neighbor_map_node-> set_gval (neighbor_node.get_gval ());
Neighbor_map_node-> set_hval (neighbor_node.get_hval ());
Neighbor_map_node-> set_parrent (current. get_pos_index ());
}
}
// ! If the vertex is neither open nor close, add it directly to open
Else If ( False = Neighbor_map_node-> is_closed ())
{
Open. insert (neighbor_node );
Neighbor_map_node-> set_open ();
Neighbor_map_node-> set_parrent (current. get_pos_index ());
Visited. push_back (neighbor_map_node );
}
// ! If it is already in close, simply skip
Else {}// ! Closed ignore
}
Neighbors. Clear ();
}

// ! Find the target and traverse it in reverse order to obtain the complete path.
If (Current. get_pos_index () = to_index)
{
Path _. push_back (current. get_pos_index ());
Uint32_t next = m_map.get_node (current. get_pos_index ()-> get_parrent ();
While (Next! = From_index)
{
Path _. push_back (next );
Next = m_map.get_node (next)-> get_parrent ();
}
Path _. push_back (from_index );
}

// ! Finally, the status of all accessed nodes is clear to prepare for the next search
For (Size_t I = 0 ; I <visited. Size (); ++ I)
{
Visited [I]-> clear ();
}
Visited. Clear ();
Return 0 ;
}

 

A star Data Structure
    1. Open Table: maintains the nodes to be extended. The minimum node F = G + H is found each time, which is implemented by pop_first.

The Open table is sorted in ascending order of f = G + H, and is a multimap

Typedef multimap <uint32_t, search_node_t> table_t;
Struct Open_table_t
{
Table_t nodes;
Bool Empty (){ Return Nodes. Empty ();}
Int Pop_first (search_node_t & RET)
{
Table_t: iterator it = nodes. Begin ();
Ret = it-> second;
Nodes. Erase (it );
Return 0 ;
}
Void Insert ( Const Search_node_t & node _)
{
Nodes. insert (make_pair (node _. get_fval (), node _));
}
Void Update (uint32_t old _, Const Search_node_t & node _)
{
Pair <table_t: iterator, table_t: iterator> ret = nodes. Sort _range (old _);
Table_t: iterator it = ret. first;
For (; It! = Ret. Second; ++ it)
{
If (IT-> second = node _)
{
// ! Can be optimized. If the previous one is smaller than this node, it needs to be deleted.
Nodes. Erase (it );
}
}
This -> Insert (node _);
}
};

 

2. Map Manager

The Map Manager records all MAP information, records adjacent coordinate information of a coordinate, and records whether a coordinate is accessible, map width, height, distance between two points, and so on.Maintain a two-dimensional array in the Map Manager.

Map_mgr_t (uint32_t width _, uint32_t height _):
M_map_nodes (null ),
M_width (width _),
M_height (height _)
{
M_map_nodes = (map_node_t *) malloc (m_width * m_height *Sizeof(Map_node_t ));
For(Uint32_t I =0; I <m_height; ++ I)
{
For(Uint32_t J =0; J <m_width; ++ J)
{
New(M_map_nodes + I * m_width + J) map_node_t (I * m_width + J );
}
}
}
  3. The method for getting a neighbor node is as follows, and the restriction cannot be skewed. Different games may have different implementations.

 
 Void Get_neighbors (uint32_t POS _, vector <map_node_t *> & RET _)
{
Map_node_t * TMP = m_map_nodes + POS _- 1 ;
If (TMP> = m_map_nodes & TMP <m_map_nodes + m_height * m_width & TMP-> is_can_pass ())
{
RET _. push_back (TMP );
}
TMP = m_map_nodes + POS _ + 1 ;
If (TMP> = m_map_nodes & TMP <m_map_nodes + m_height * m_width & TMP-> is_can_pass ())
{
RET _. push_back (TMP );
}
TMP = m_map_nodes + POS _-m_width;
If (TMP> = m_map_nodes & TMP <m_map_nodes + m_height * m_width & TMP-> is_can_pass ())
{
RET _. push_back (TMP );
}
TMP = m_map_nodes + POS _ + m_width;
If (TMP> = m_map_nodes & TMP <m_map_nodes + m_height * m_width & TMP-> is_can_pass ())
{
RET _. push_back (TMP );
}
}
  4. heuristic functions

Because it cannot be skewed, the heuristic function H only obtains the offset and of X and Y.

 
Uint32_t heuristic (uint32_t from _, uint32_t _)
{
Return This-> Distance (from _, _);
}


Todo:
    1. Astar_t should be templated. heuristic, distance, and get_neighbors should all be customizable.
    2. Performance parameter testing, such as the worst-case search overhead on a 1000*1000 Map
    3. Open Table update can also be optimized. If the updated G value is smaller than the previous node of the iterator, deletion and insertion are required.

 

Source code: Http://ffown.googlecode.com/svn/trunk/fflib/ext/algorithm/astar2/

 

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.