为了更好地理解A星算法,自己手撸了一段91行的代码来实现A星算法
可能代码风格不是很好,因为这也就是一上午写出来的,只是简单实现了A星
过两天准备好好改动一下代码使其更易读,再好好备注一下。
#python3.7.3
import numpy as np
#设置地图和障碍,障碍物为1
tarmap=np.zeros((24,24))
tarmap.astype(np.int32)
tarmap[2][0:5]=1
tarmap[0:5,6]=1
tarmap[5,3:10]=1
tarmap[7,1:20]=1
def showMap(tarmap):#打印地图
for i in tarmap:
print(i)
showMap(tarmap)
class node:#每一个节点的初始化,有一个打印节点坐标和F值的方法
def __init__(self,point,end,father=None):
self.x=point[0]
self.y=point[1]
self.father=father
if father==None:
self.G=None
self.H=None
self.F=None
else:
self.G=(10 if abs(father.x-self.x)+abs(father.y-self.y)==1 else 14)
self.H=abs(end[0]-self.x)*10+abs(end[1]-self.y)*10
self.F=self.G+self.H
def show(self):
print([self.x,self.y],self.F)
openlist=[]
closelist=[]
start=[0,0]
end=[23,23]
def findMinF(openlist):#在openlist中找到最小F的节点
minF=999999999
minIndex=0
for i,j in enumerate(openlist):
if j.F==None:
continue
if j.F<minF:
minF,minIndex=j.F,i
return openlist[minIndex]
def nodeIn(point,openlist):#查看节点是否在openlist中
for i in openlist:
if point.x==i.x and point.y==i.y:
return i
return False
def listAppend(point,openlist,tarmap):#将当前节点的邻近节点更新并加入到openlist中
points=[]
temp=[-1,0,1]
for i in temp:
for j in temp:
points.append([point.x+i,point.y+j])
points.pop(4)
for i in points:
if 23>=i[0]>=0 and 23>=i[1]>=0:
t=node(i,end,point)
t1=nodeIn(t,openlist)
t2=nodeIn(t,closelist)
if tarmap[i[0],i[1]]==1 or t2 is not False:
continue
if t1 and t1.G>t.G:
openlist.remove(t1)
openlist.append(t)
if t1 is False:
openlist.append(t)
def getres(res,tarmap):#从终点找到来时的路径并将路径画到原来的地图上
reslist=[]
cur=res
while [cur.x,cur.y]!=start:
reslist.append([cur.x,cur.y])
cur=cur.father
reslist.append([cur.x,cur.y])
for i in reslist:
tarmap[i[0],i[1]]=2
showMap(tarmap)
return reslist
#实际操作
openlist.append(node(start,end))
while openlist!=[] or nodeIn(node(end,end),closelist) is False:
temp=findMinF(openlist)
openlist.remove(temp)
closelist.append(temp)
listAppend(temp,openlist,tarmap)
print('-----------------------------')
res=nodeIn(node(end,end),closelist)
reslist=getres(res,tarmap)