Implement the A-star algorithm

v2-d58044ead3cbb0d8fb1caafd05fe252d_1200x500

【renew】

The A* algorithm is slightly modified, using BFS (sorting the open table by F value), and adding an evaluation function to measure whether a random point on the line segment from the current point to the end point is a wall or a visited node , Returns 1 if yes, 0 otherwise.

function path_add_barrial_tracing(state, pt1, pt2)
	local xabs, yabs = math.abs(pt1.x - pt2.x), math.abs(pt1.y - pt2.y)
	if xabs == 0 or yabs == 0 then return 0 end
	local xr, yr = math.ceil(math.random(1,xabs)), math.ceil(math.random(1,yabs))
	local v = path_get_point(state, {x= xr, y= yr})
	if v ~= 1 then return 1 else return 0 end
end

Effect picture:

v2-83901d530c81b9ffa6b5c754fbbaeb75_hd

-----------------------------------------------------

write in front

I have seen similar articles that visualize the pathfinding algorithm.

Thinking about integrating them into the game framework, generally speaking, the integration difficulty is relatively low.

Realize ideas

TableLayout has been implemented previously, and the length and width can be set to evenly arrange the elements in the container. The squares in the title map are also implemented in this way.

Only breadth traversal BFS and depth traversal DFS are implemented, both of which are classic traversal algorithms.

In the book, two tables, open and closed, are generally used. Here, for the simplicity of the diagram, one table is used. The structure of the graph is represented by a two-dimensional matrix, 1 means unvisited, 3 and 4 mean the start and end points, 2 means the wall, and 6 and above means visited. Then each visit only needs to mark the value in the matrix.

  • BFS is to add the adjacent unvisited blocks of the currently visited block to the end of the list, and each time the block to be accessed is taken from the head of the list. Since the added blocks are not accessible for a period of time, it may cause the table to grow rapidly in size. Therefore, the efficiency of BFS is relatively poor, it will traverse all the squares and find the global optimal solution. The submerged city in "The Day After Tomorrow" is also the embodiment of BFS.
  • DFS adds the adjacent unvisited blocks of the current block to the head of the table each time, and fetches blocks from the head of the table each time. So unlike BFS, newly added blocks are accessed immediately, so the size of the table does not increase rapidly. It finds solutions quickly, but not necessarily globally optimal. The way lightning grows in life is DFS.

The two algorithms are only different in the way of adding tables. DFS is added to the head, and BFS is added to the tail.

The main difficulty here is that the color of the squares is gradual, black near the starting point (red), and sky blue far away. The calculation method is to find the distance from any point to the starting point, and then convert it to RGB according to HSL. The hue of HSL is fixed, and the brightness can be adjusted to achieve a gradient effect.

-------------------------------------------------

The (pseudo)A* algorithm is implemented below.

v2-21a4c9f2c5b8ec365f4dcaefff1832d6_hd

Both BFS and DFS methods have shortcomings: BFS can find the global optimum, but it needs to visit all positions once, which is time-consuming; DFS is fast, but it is only a local optimum, and how DFS selects the nodes to be expanded is not clearly specified .

A* is an improvement on the above approach. A* gives an evaluation function F. F=G+H. G is the current amount of movement, H is the estimated distance to be moved, and the sum of the two is the estimated value of the current nodule. Of course, the smaller the value, the more likely it is to take this path.

The solution is simple: let G = accumulated moving distance; let H = the Hamiltonian distance from the current position to the end point . When expanding the nodes, the selected nodes are sorted by the F value, so that the one with the smallest F value is expanded first, thereby saving time.

The implementation of A* generally uses the open and closed tables. It sorts the nodes in the open table according to F, and selects the least expensive expansion. That is to say, the A* algorithm sorts the nodes in the open table every time, and the expansion of A* is similar to BFS. Why is it based on BFS? Because the open table node generated by BFS is the outline of the currently traversed node , this is a bit like the minimum spanning tree algorithm, which selects the node with the least cost from the current outline to expand. The only thing that affects the efficiency of A* is how F is calculated.

PS: Due to laziness, implementing A* is different from the above! The above is to sort open, and I only sort the adjacent nodes of the current node, so the algorithm effect is definitely not as good as A*. Furthermore, the goal of this series is to do GUI, and algorithm visualization is just a demo.

Staged summary

The key to the A* algorithm is to set up an evaluation function, just like AlphaGo's estimation of the situation. It uses a method similar to the minimum spanning tree (think of the grid as a graph connected up, down, left and right), but the selection rule of the minimum spanning tree is determined (the path length is determined), and the selection rule of A* is uncertain (evaluation function is not precise). This results in a minimum spanning tree yielding an optimal solution, while A* may not necessarily yield an optimal solution.

Backed up by http://zhuanlan.zhihu.com/p/25593280 .

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325153653&siteId=291194637