Two days before the Spring Festival holiday I happened to see the a\* algorithm (a\* algorithm is a heuristic map pathfinding algorithm), it feels very interesting. Just before the holiday did not have anything, it took an afternoon to write the skeleton of the algorithm, and spent half a day to perfect the screen output details and debugging completed.
This implementation is just a whim, without considering performance and scalability issues. The friend who is learning a\* algorithm can take to casually toss.
Email: [Email protected]
The code works as follows:
"' Pytho
#!/usr/bin/python?
# Vim:set Fileencoding=utf-8
# Two days before the Spring Festival holiday I happened to see a * algorithm, it feels very interesting. Just before the holiday.
# and nothing, it took an afternoon to write the skeleton of the algorithm, and spent half a day
# time to perfect the details of the screen output and debug done.
# This implementation is just a whim, without considering performance and scalability issues. Is
# in the study of a A * friend can take to casually toss.
# email: [Email protected]
Import Sys
_2dmap = []
Start = None
End = None
Open_list = {}
Close_list = {}
Map_border = ()
Class Node:
Def __init__ (this, father, X, y):
If x < 0 or x >= map_border[0] or y < 0 or y >= map_border[1]:
Raise Exception ("node position can ' t beyond the border!")
This.father = Father
This.x = X
This.y = y
If father! = None:
G2father = Calc_g (father, this)
If not g2father:
Raise Exception ("Father is not valid!")
This. G = G2father + father. G
This. H = Calc_h (this, end)
This. F = this. G + this. H
Else
This. G = 0
This. H = 0
This. F = 0
Def reset_father (this, Father, New_g):
If father! = None:
This. G = New_g
This. F = this. G + this. H
This.father = Father
def calc_g (Node1, Node2):
X1 = ABS (node1.x-node2.x)
Y1 = ABS (NODE1.Y-NODE2.Y)
if (x1== 1 and Y1 = = 0):
Return Ten # same row
if (x1== 0 and Y1 = = 1):
Return Ten # same COL
if (x1== 1 and Y1 = = 1):
Return # Cross
Else
return 0
def calc_h (cur, end):
Return ABS (end.x-cur.x) + ABS (END.Y-CUR.Y)
# NOTE This place can be a performance bottleneck
Def min_f_node ():
If Len (open_list) = = 0:
Raise Exception ("not exist path!")
_min = 9999999999999999
_k = (start.x, START.Y)
For k,v in Open_list.items ():
If _min > V.F:
_min = V.F
_k = k
return Open_list[_k]
# Add the adjacent node to the open list, if you find the end point description found the path
def addadjacentintoopen (node):
# Move the node from the open list to the closed list.
Open_list.pop ((node.x, NODE.Y))
close_list[(node.x, node.y)] = node
_adjacent = []
# Adjacent nodes are not aware of the boundary condition
Try
_adjacent.append (node, node.x-1, Node.y-1)
Except Exception,e:
Pass
Try
_adjacent.append (node, node.x, Node.y-1)
Except Exception,e:
Pass
Try
_adjacent.append (node, node.x + 1, node.y-1))
Except Exception,e:
Pass
Try
_adjacent.append (node, node.x + 1, node.y))
Except Exception,e:
Pass
Try
_adjacent.append (node, node.x + 1, node.y + 1))
Except Exception,e:
Pass
Try
_adjacent.append (node, node.x, Node.y + 1))
Except Exception,e:
Pass
Try
_adjacent.append (node, node.x-1, Node.y + 1))
Except Exception,e:
Pass
Try
_adjacent.append (node, node.x-1, Node.y)
Except Exception,e:
Pass
For a in _adjacent:
if (a.x,a.y) = = (End.X, end.y):
New_g = Calc_g (A, node) + node. G
End.reset_father (node, new_g)
Print "Find path finish!"
Return True
if (A.X,A.Y) in close_list:
Continue
if (A.X,A.Y) not in Open_list:
open_list[(A.X,A.Y)] = a
Else
Exist_node = open_list[(A.X,A.Y)]
New_g = Calc_g (A, node) + node. G
If New_g < Exist_node. G:
Exist_node.reset_father (node, new_g)
Return False
Def find_the_path (Start, end):
open_list[(Start.x, start.y)] = start
The_node = Start
Try
While not Addadjacentintoopen (The_node):
The_node = Min_f_node ()
Except Exception,e:
# Path not exist
Print E
Return False
Return True
#=======================================================================
Def print_map ():
print ' Y ',
For i in Xrange (Len (_2dmap)):
Print I,
Print
print ' X '
Row = 0
For L in _2dmap:
print '%3d '%row, ',
row = Row+1
For I in L:
Print I,
Print
def mark_path (node):
if Node.father = = None:
Return
_2DMAP[NODE.X][NODE.Y] = ' # '
Mark_path (Node.father)
Def preset_map ():
Global Start,end,map_border
_2dmap.append (' S x............. X ..... Split ())
_2dmap.append ('. X............. X ..... Split ())
_2dmap.append ('. X............. X ..... Split ())
_2dmap.append ('. .............. X ..... Split ())
_2dmap.append ('. .............. X ..... Split ())
_2dmap.append ('. ...................'. Split ())
_2dmap.append ('. .............. x x x x. '. Split ())
_2dmap.append ('. .............. X ..... Split ())
_2dmap.append ('. .............. X. x x x '. Split ())
_2dmap.append ('. .............. X. X. .‘. Split ())
_2dmap.append ('. .............. X ..... Split ())
_2dmap.append ('. .............. X. X. .‘. Split ())
_2dmap.append ('. .............. X. X. .‘. Split ())
_2dmap.append ('. .............. X. X. .‘. Split ())
_2dmap.append ('. .............. X. X. .‘. Split ())
_2dmap.append ('. .............. X. X. E '. Split ())
Map_border = (len (_2dmap), Len (_2dmap[0]))
Row_index = 0
For row in _2dmap:
Col_index = 0
For n in row:
if n = = ' X ':
Block_node = node (None, Row_index, Col_index)
close_list[(block_node.x, block_node.y)] = Block_node
elif n = = ' S ':
Start = Node (None, Row_index, Col_index)
elif n = = ' E ':
End = Node (None, Row_index, Col_index)
Col_index = Col_index + 1
Row_index = Row_index + 1
If __name__== ' __main__ ':
If Len (SYS.ARGV) < 3:
Preset_map ()
Else
x = Int (sys.argv[1])
y = Int (sys.argv[2])
Map_border = (x, y)
_start = raw_input (' pls input start point: ')
_end = raw_input (' pls input end point: ')
_start = _start.split (', ')
_end = _end.split (', ')
_start = (int (_start[0]), int (_start[1]))
_end = (int (_end[0]), int (_end[1]))
Start = Node (None, _start[0], _start[1])
End = Node (None, _end[0], _end[1])
# Gen Map
_2dmap = [['. ' For I, xrange (y)] for I in xrange (x)]
# Put start and end
_2DMAP[_START[0]][_START[1]] = ' S '
_2DMAP[_END[0]][_END[1]] = ' E '
# input Blocks
While True:
_block = raw_input (' input block: ')
If not _block:
Break
_block = _block.split (', ')
_block = (int (_block[0]), int (_block[1]))
_2DMAP[_BLOCK[0]][_BLOCK[1]] = ' X '
Block_node = node (None, _block[0], _block[1])
close_list[(block_node.x, block_node.y)] = Block_node
Print "orignal map:"
Print_map ()
If Find_the_path (Start, end):
Mark_path (End.father)
Print "Found road as follow:"
Print_map ()
```
From for notes (Wiz)
A * (a star) algorithm Python implementation