Two days before the Spring festival holiday I accidentally saw a * 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. A friend who is learning a * can take it and toss it casually.
Email: [Email protected]
The code works as follows:
#!/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]ImportSys_2dmap = []start =NoneEnd =NoneOpen_list = {}close_list = {}map_border = () class Node: def __init__(This, father, X, y): ifX <0 orX >= map_border[0]orY <0 orY >= map_border[1]:RaiseException ("node position can ' t beyond the border!") This.father = Father This.x = x this.y = yifFather! =None: G2father = Calc_g (father, this)if notG2father:RaiseException ("Father is not valid!") this. G = G2father + father. G this. H = Calc_h (this, end) this. F = this. G + this. HElse: this. G =0This. H =0This. F =0 def reset_father(this, Father, New_g): ifFather! =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 andY1 = =0):return Ten # same Row if(x1==0 andY1 = =1):return Ten # same Col if(x1==1 andY1 = =1):return - # Cross Else:return 0 def calc_h(cur, end): returnABS (end.x-cur.x) + ABS (END.Y-CUR.Y)# NOTE This place can be a performance bottleneck def min_f_node(): ifLen (open_list) = =0:RaiseException ("not exist path!") _min =9999999999999999_k = (start.x, START.Y) forKvinchOpen_list.items ():if_min > V.F: _min = v.f _k = kreturnOpen_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 should pay attention to the situation of the boundary Try: _adjacent.append (node, node.x-1, Node.y-1))exceptException,e:Pass Try: _adjacent.append (node, node.x, Node.y-1))exceptException,e:Pass Try: _adjacent.append (node, node.x +1, Node.y-1))exceptException,e:Pass Try: _adjacent.append (node, node.x +1, NODE.Y))exceptException,e:Pass Try: _adjacent.append (node, node.x +1, Node.y +1))exceptException,e:Pass Try: _adjacent.append (node, node.x, Node.y +1))exceptException,e:Pass Try: _adjacent.append (node, node.x-1, Node.y +1))exceptException,e:Pass Try: _adjacent.append (node, node.x-1, NODE.Y))exceptException,e:Pass forAinch_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)inchClose_list:Continue if(A.X,A.Y) not inchopen_list:open_list[(A.X,A.Y)] = aElse: Exist_node = open_list[(a.x,a.y)] New_g = Calc_g (A, node) + node. GifNew_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 = StartTry: while notAddadjacentintoopen (the_node): The_node = Min_f_node ()exceptException,e:# Path not exist PrintEreturn False return True#======================================================================= def print_map(): Print ' Y ', forIinchXrange (Len (_2dmap)):PrintIPrint Print ' X 'row =0 forLinch_2dmap:Print '%3d '%row,"', row = row+1 forIinchLPrintIPrint def mark_path(node): ifNode.father = =None:return_2DMAP[NODE.X][NODE.Y] =' # 'Mark_path (Node.father) def preset_map(): GlobalStart,end,map_border _2dmap.append ('sx............. 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 forRowinch_2dmap:col_index =0 forNinchRowifn = =' X ': Block_node = node (None, Row_index, Col_index) close_list[(block_node.x, block_node.y)] = Block_nodeelifn = =' S ': Start = Node (None, Row_index, Col_index)elifn = =' E ': End = Node (None, Row_index, col_index) Col_index = Col_index +1Row_index = Row_index +1if__name__==' __main__ ':ifLen (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 = [['. ' forIinchXrange (y)] forIinchXrange (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_nodePrint "orignal map:"Print_map ()ifFind_the_path (Start, end): Mark_path (End.father)Print "Found road as follow:"Print_map ()
A * (a star) algorithm Python implementation