这一周的工作主要是将上一周改的python版代码调试正常。由于对python语言特定语法结构理解的还是不深,所以的遇到了很多坑,万幸最后还是一一填上了,随着不断的调试对于python的有了进一步的认识。先交代一下最大的坑,就是对于python嵌套列表的深拷贝浅拷贝的不了解和错误使用,导致代码运行时出现了各种诡异的现象。总结如下,共勉!

首先讲一下在应用嵌套列表时对于深浅拷贝个人理解

比如:a = [['c','d'],5,4,'g'],列表a是一个内部嵌套了一层列表['c','d']的列表,如果要将a中的数据拷贝到列表b中,以下给出3种操作方式,正确与否会详细说明,仅通过3种方式来交代深拷贝浅拷贝的区别:

1).b = a,这一种方式其实是将b映射到a的存储位置上,不是真正的拷贝,一旦b中的元素被修改,a中的元素也同样会被修改

2).b = a[:],这一种方式是浅拷贝。其实如果a内部没有嵌套列表,如 ['c','d',5,4,'g'],这种方式是正确的,因为浅拷贝会拷贝到列表a很浅的一部分,即最外层。这样b不会被映射到a的存储位置上,两者存储空间互不干扰。但是现在a内部嵌套了一个列表,再用浅拷贝操作,这样b中的元素会部分映射到a,猜也能猜到就是列表内部嵌套的一层['c','d']会被b与a共享,而列表中剩下的元素是存储在不同的位置,不会被共享。所以这样就会导致诡异的现象:你以为拷贝成功了,但只要修改一个列表中共享位置的元素,之前的副本中的元素全部也被修改,注意浅拷贝的另一种方式是b = copy.copy(a),但是需要在前面import copy工具箱。

3).b = copy.deepcopy(a),这一种方式是深拷贝,需要import copy工具箱,这种方式顾名思义,就是将列表中嵌套的列表也都拷贝到另一个存储位置上,所以要想只将a的元素的值复制一份给b,而不想a与b之间还有任何牵连需要进行深拷贝操作。

用python编的这套A*算法,基本步骤与c++版本一致,主要是由于python中有列表这种数据结构,所以将c++中结构体和类变量以嵌套列表的方式来表示,现以c++与python对比的方式将一些重要数据结构作出说明:

以chessboard棋盘这个概念的数据结构为例

c++中,我使用的是结构体来定义棋盘,具体如下:

结构体定义:

struct PARENT_POSITION//父指针
{int x;int y;
};
struct CHESS_BOARD_UNIT
{PARENT_POSITION ParentPosition;int g_value;int h_value;int f_value;char flag;//标识此单元是:2起点/3终点/1障碍物/0通路
};

结构体数组定义:

CHESS_BOARD_UNIT chessboard[chess_size][chess_size] = { 0 };//chessboard初始化为0

若操作地图上3行5列点的父指针的横坐标,操作如下:

chessboard[3][5].ParentPosition.x= 5

python中,我使用的是列表来定义棋盘,具体如下:

这里注意,与c++的区别是python定义列表不用预先分配好这个列表的大小,想用直接往里存就可以了。

chessboard = [] #用python定义就是如此简单!!!

而chessboard具体的数据结构必须是在存放完所有元素之后才能确定!实际上chessboard的每一个方格元素的结构是

A = [[parent.x,parent.y],g_value,h_value,f_value,flag],与c++版本中数据结构得顺序是一致的

以下将存放元素的具体代码贴出:

 i = 0 while i <20:j = 0while j<20:#将棋盘读入到flag中if 's' == chessboardTemp[i][j]: #检测并记录起始点坐标print('起始点坐标!!![%d,%d]'%(i,j))Start_x = iStart_y = jif 'e' == chessboardTemp[i][j]: #检测并记录终止点坐标print('终止点坐标!!![%d,%d]'%(i,j))End_x = iEnd_y = jif 'b' == chessboardTemp[i][j]: #检测并记录终止点坐标print('障碍点坐标!!![%d,%d]'%(i,j))item=[[0,0],0,0,0,chessboardTemp[i][j]]#结构:A = [[parent.x,parent.y],g_value,h_value,f_value,flag]#print(item[4])itemLine.append(copy.deepcopy(item)) #结构:B = [A,A,A,A,A....,A]一行20个,一定要传切片[:]!!!print(itemLine[j][4])j+=1print(fileLine)chessboard.append(copy.deepcopy(itemLine)) #结构:[B,B,B,B,...,B] 20列,一定要传切片!!!itemLine = []#超级大bug:将itemLine清空(查了一晚上!!!!)fileLine = ifile.readline()#读取下一行数据i+=1

说明一下这段代码的简单流程,chessboardTemp是一个列表,列表中的元素是从txt文件中读取的每一行字符串(即每行地图),两层循环的工作就是要将表示地图的每一个字符存放到 A = [[parent.x,parent.y],g_value,h_value,f_value,flag]的flag位置上。

item = [[0,0],0,0,0,chessboardTemp[i][j]]就相当于c++中棋盘中的一个方格的结构体,itemLine.append(copy.deepcopy(item))操作循环20次就是要将一行20个方格排列在一个列表里,构成chessboard的一行itemLine = [item,item,item,item,...,item]。

而chessboard.append(copy.deepcopy(itemLine))操作循环20次相当于chessboard = [itemLine,itemLine,itemLine,...,itemLine]

构成了chessboard的20行,即整个chessboard的数据结构就被建立起来了。

同样,若操作地图上3行5列点的父指针的横坐标,操作如下:

chessboard[3][5][0][0] = 5 #言简意赅!!!

现将寻路结果截图:

下面将python版本的全部代码贴出

注意:

1.此版本调试信息我忘了加开关,所以会在控制台打出大量调试信息,下一版再修正!

2.要预先在.py文件的相同目录下建立地图txt文件(代码中名为‘123.txt’),现将地图贴出:

########b###########
########b###########
##s#####b###########
########b########e##
########b###########
########b###########
######b#b###########
######b#bbbbbb######
######b######b######
#########b###b######
#########b###b######
#########b###b#bbb##
#########b##########
####################
####################
####################
####################
####################
####################
####################

代码:

#coding=utf-8
import copy
chess_size =  20
FILE_STORAGE_WAY =  '123.txt'    #随机数据文件存放路径Start_x = 0
Start_y = 0
End_x = 0
End_y = 0  OpenListPosition = 0 #指针标记open列表数组当前存放元素个数(position总指向最后一个元素的后一位置)
CloseListPosition = 0 #指针标记Close列表数组当前存放元素个数(position总指向最后一个元素的后一位置) OpenList = []#open列表(定义成数组形式)
CloseList = []#close列表chessboard = [] def openListIncraseSort():global OpenListPositionglobal OpenListflag = 0i = 0#for (int i = 0; i < OpenListPosition; i++)//冒泡法由大到小排序while i < OpenListPosition:#for (int j = 0; j < OpenListPosition - i; j++)j = 0while j<OpenListPosition - 1:##############- 1if OpenList[j][2] < OpenList[j + 1][2]:#若OpenList[j].f_value < OpenList[j + 1].f_value,交换,从大到小排列ChessUnit_x = OpenList[j][0]ChessUnit_y = OpenList[j][1]f_value    = OpenList[j][2]OpenList[j][0]= OpenList[j + 1][0]OpenList[j][1]= OpenList[j + 1][1]OpenList[j][2]= OpenList[j + 1][2]OpenList[j + 1][0] = ChessUnit_xOpenList[j + 1][1] = ChessUnit_yOpenList[j + 1][2] = f_valueflag = 1 #将交换标志位置1j+=1 #循环变量增加1#if#while2if (0 == flag):break #内层循环一次都没交换,说明已经排好序flag = 0 #将标志位重新清0i+=1 #循环变量增加1print('===调试用===openListIncraseSort()')#调试用,输出openListIncraseSortprint('===调试用===按f_value排序后的OpenList =')print(OpenList)def dealCurrentNeibors(CurrentUnit):#判断当前结点周围8个点状态,计算g、h、f值,将周围每个点的父指针指向当前结点global OpenListPositionglobal CloseListPositionglobal OpenListglobal CloseListglobal chessboardOpenListFlag = 0CloseListFlag = 0ObstacleEast = 0 #标识当前点东边是否有障碍物ObstacleSouth = 0    #标识当前点南边是否有障碍物ObstacleWest = 0 #标识当前点西边是否有障碍物ObstacleNorth = 0    #标识当前点北边是否有障碍物#CloseListUnit EastUnit, SourthEastUnit, SourthUnit, SourthWestUnit, WestUnit, NorthWestUnit, NorthUnit, NorthEastUnit;//东,东南,南,西南,西,西北,北,东北CurrentNeibors = []#列表,按顺序存放当前结点的东,东南,南,西南,西,西北,北,东北方向的邻结点OpenlistTemp = []#列表,存放openlist【x,y,f_value】中的【x,y】for temp in OpenList:OpenlistTemp.append([temp[0],temp[1]])print('===调试用===dealCurrentNeibors():OpenlistTemp=')#调试用,输出OpenlistTempprint(OpenlistTemp)#调试用,输出OpenlistTemp#东方y+1item = [CurrentUnit[0],CurrentUnit[1] + 1]CurrentNeibors.append(item)#东南方x+1,y+1item = [CurrentUnit[0] + 1,CurrentUnit[1] + 1]CurrentNeibors.append(item)#南方x+1item = [CurrentUnit[0] + 1,CurrentUnit[1]]CurrentNeibors.append(item)#西南方x+1,y-1item = [CurrentUnit[0] + 1,CurrentUnit[1]-1]CurrentNeibors.append(item)#西方y-1item = [CurrentUnit[0],CurrentUnit[1]-1]CurrentNeibors.append(item)#西北方x-1,y-1item = [CurrentUnit[0]-1,CurrentUnit[1]-1]CurrentNeibors.append(item)#北方x-1item = [CurrentUnit[0]-1,CurrentUnit[1]]CurrentNeibors.append(item)#东北方x-1,y+1item = [CurrentUnit[0]-1,CurrentUnit[1]+1]CurrentNeibors.append(item)print('===调试用===CurrentUnit=(%d,%d)'%(CurrentUnit[0],CurrentUnit[1]))#调试用    print(chessboard[6][6][4])print(chessboard[6][8][4])print('===调试用===dealCurrentNeibors():CurrentNeibors=')#调试用print(CurrentNeibors)#调试用#对当前方格东、南、西、北四个方向的临近方格依次检测i = 0while i<8:#当前中间结点到邻近结点的距离。约定:东南西北四个方向距离为10,四个斜方向距离为14if i%2 == 0:currenToNeibor = 10else:currenToNeibor = 14print('===调试用===dealCurrentNeibors():currenToNeibor=[%d]'%currenToNeibor)#调试用print('===调试用===dealCurrentNeibors():CurrentUnit[0]=[%d] CurrentUnit[1]=[%d]'%(CurrentUnit[0],CurrentUnit[1]))print('===调试用===dealCurrentNeibors():chessboard[CurrentUnit[0]][CurrentUnit[1]][1]=[%d]'%chessboard[CurrentUnit[0]][CurrentUnit[1]][1])         #超出边界点if CurrentNeibors[i][0] < 0 or CurrentNeibors[i][0]>19 or CurrentNeibors[i][1] < 0 or CurrentNeibors[i][1]>19:print('===调试用===dealCurrentNeibors():超出边界点!!!(%d,%d)'%(CurrentNeibors[i][0],CurrentNeibors[i][1]))#continue #结束判断# print('===调试用===dealCurrentNeibors():currenToNeibor=[%d],i=[%d]'%(currenToNeibor,i))#调试用# print('===调试用===dealCurrentNeibors():CurrentNeibors[%d][0]=[%d]'%(i,CurrentNeibors[i][0]))#调试用# print('===调试用===dealCurrentNeibors():CurrentNeibors[%d][1]=[%d]'%(i,CurrentNeibors[i][1]))#调试用# print('===调试用===dealCurrentNeibors():chessboard[CurrentNeibors[i][0]][CurrentNeibors[i][1]][4]=')# print(chessboard[CurrentNeibors[i][0]][CurrentNeibors[i][1]][4])#终点elif 'e' == chessboard[CurrentNeibors[i][0]][CurrentNeibors[i][1]][4]:#flagchessboard[CurrentNeibors[i][0]][CurrentNeibors[i][1]][0][0] = CurrentUnit[0]#[0][0]parent.xchessboard[CurrentNeibors[i][0]][CurrentNeibors[i][1]][0][1] = CurrentUnit[1]#[0][1]parent.yprint('===调试用===dealCurrentNeibors():找到终点!!!(%d,%d)'%(CurrentNeibors[i][0],CurrentNeibors[i][1]))#调试用return 1#障碍物点elif 'b' == chessboard[CurrentNeibors[i][0]][CurrentNeibors[i][1]][4]:#flagsprint('===调试用===dealCurrentNeibors():找到障碍物点!!!(%d,%d)'%(CurrentNeibors[i][0],CurrentNeibors[i][1]))#调试用if i == 0:ObstacleEast = 1 #标识当前点东边有障碍物print('===调试用===dealCurrentNeibors():ObstacleEast = %d'%ObstacleEast)elif i == 2:ObstacleSouth = 1 #标识当前点南边有障碍物print('===调试用===dealCurrentNeibors():ObstacleSouth = %d'%ObstacleSouth)elif i == 4:ObstacleWest = 1 #标识当前点西边有障碍物print('===调试用===dealCurrentNeibors():ObstacleWest = %d'%ObstacleWest)elif i == 6:ObstacleNorth = 1 #标识当前点北边有障碍物print('===调试用===dealCurrentNeibors():ObstacleNorth = %d'%ObstacleNorth)               #将该临近点与closelist中的点逐个比较elif CurrentNeibors[i] in CloseList:#python牛逼!print('===调试用===dealCurrentNeibors():CurrentNeibors[%d]是closelist中的点!!!(%d,%d)'%(i,CurrentNeibors[i][0],CurrentNeibors[i][1]))print('===调试用===dealCurrentNeibors():CloseList=')print(CloseList)#continue#结束判断#将该临近点与openlist中的点逐个比较elif CurrentNeibors[i] in OpenlistTemp:#python牛逼!print('===调试用===dealCurrentNeibors():CurrentNeibors[i] in OpenlistTemp:')#调试用print('===调试用===dealCurrentNeibors():CurrentNeibors[i]=')print(CurrentNeibors[i])print('===调试用===dealCurrentNeibors():OpenlistTemp=')print(OpenlistTemp)#若该临近点的g值大于从起点经由当前结点到该临近结点的g值,将该临近结点的父指针指向当前结点,并更改该临近结点的g值,f值if chessboard[CurrentNeibors[i][0]][CurrentNeibors[i][1]][1] > chessboard[CurrentUnit[0]][CurrentUnit[1]][1] + currenToNeibor:#将该临近结点的父指针指向当前结点chessboard[CurrentNeibors[i][0]][CurrentNeibors[i][1]][0][0] = CurrentUnit[0]#[0][0]parent.xchessboard[CurrentNeibors[i][0]][CurrentNeibors[i][1]][0][1] = CurrentUnit[1]#[0][1]parent.yprint('===调试用===dealCurrentNeibors():修改(%d,%d)结点的父节点(%d,%d)'%(CurrentNeibors[i][0],CurrentNeibors[i][1],CurrentUnit[0],CurrentUnit[1]))#更改该临近结点的g值,f值chessboard[CurrentNeibors[i][0]][CurrentNeibors[i][1]][1] = chessboard[CurrentUnit[0]][CurrentUnit[1]][1] + currenToNeibor#g_value+currenToNeiborchessboard[CurrentNeibors[i][0]][CurrentNeibors[i][1]][3] = chessboard[CurrentNeibors[i][0]][CurrentNeibors[i][1]][1] + chessboard[CurrentNeibors[i][0]][CurrentNeibors[i][1]][2]#[1]g[2]h[3]fcounter=0while len(OpenList)-counter > 0:#大bug,漏掉了此处,导致openlist中的f_value值没有被更新!!!注意修改list值不能用forif CurrentNeibors[i][0] == OpenList[counter][0] and CurrentNeibors[i][1] == OpenList[counter][1]:#找到openlist中要修改f_value的位置OpenList[counter][2] = chessboard[CurrentNeibors[i][0]][CurrentNeibors[i][1]][3]#更新openlist中的f值breakcounter+=1#可作为通路点elif '#' == chessboard[CurrentNeibors[i][0]][CurrentNeibors[i][1]][4]:#将邻居结点的指针指向当前结点print('===调试用===dealCurrentNeibors():CurrentUnit[0]=[%d] CurrentUnit[1]=[%d]'%(CurrentUnit[0],CurrentUnit[1]))print('===调试用===dealCurrentNeibors():chessboard[CurrentUnit[0]][CurrentUnit[1]][1]=[%d]'%chessboard[CurrentUnit[0]][CurrentUnit[1]][1])          chessboard[CurrentNeibors[i][0]][CurrentNeibors[i][1]][0][0] = CurrentUnit[0]#[0][0]parent.xchessboard[CurrentNeibors[i][0]][CurrentNeibors[i][1]][0][1] = CurrentUnit[1]#[0][1]parent.yprint('===调试用===dealCurrentNeibors():(%d,%d)结点的父节点为(%d,%d)'%(CurrentNeibors[i][0],CurrentNeibors[i][1],CurrentUnit[0],CurrentUnit[1]))#print('===调试用===dealCurrentNeibors():chessboard=')  #print(chessboard)  #计算该临近结点的g值,h值(曼哈顿距离),f值#temptest = chessboard[CurrentUnit[0]][CurrentUnit[1]][1][:] + currenToNeiborchessboard[CurrentNeibors[i][0]][CurrentNeibors[i][1]][1] = chessboard[CurrentUnit[0]][CurrentUnit[1]][1] + currenToNeibor#一条诡异的程序print(type(chessboard[CurrentNeibors[i][0]][CurrentNeibors[i][1]][1]))print(type(chessboard[CurrentUnit[0]][CurrentUnit[1]][1]))print(type(currenToNeibor))print('===调试用===dealCurrentNeibors():CurrentNeibors[i][0]=[%d] CurrentNeibors[i][1]=[%d]'%(CurrentNeibors[i][0],CurrentNeibors[i][1]))print('===调试用===dealCurrentNeibors():CurrentUnit[0]=[%d] CurrentUnit[1]=[%d]'%(CurrentUnit[0],CurrentUnit[1]))print('===调试用===dealCurrentNeibors():chessboard[CurrentUnit[0]][CurrentUnit[1]][1]=[%d]'%chessboard[CurrentUnit[0]][CurrentUnit[1]][1])          chessboard[CurrentNeibors[i][0]][CurrentNeibors[i][1]][2] = 10 * (abs(CurrentNeibors[i][0] - End_x) + abs(CurrentNeibors[i][1] - End_y))chessboard[CurrentNeibors[i][0]][CurrentNeibors[i][1]][3] = chessboard[CurrentNeibors[i][0]][CurrentNeibors[i][1]][1] + chessboard[CurrentNeibors[i][0]][CurrentNeibors[i][1]][2]print('===调试用===dealCurrentNeibors():g_value=[%d]'%chessboard[CurrentNeibors[i][0]][CurrentNeibors[i][1]][1])print('===调试用===dealCurrentNeibors():h_value=[%d]'%chessboard[CurrentNeibors[i][0]][CurrentNeibors[i][1]][2])print('===调试用===dealCurrentNeibors():f_value=[%d]'%chessboard[CurrentNeibors[i][0]][CurrentNeibors[i][1]][3])print('===调试用===dealCurrentNeibors():CurrentUnit[0]=[%d] CurrentUnit[1]=[%d]'%(CurrentUnit[0],CurrentUnit[1]))print('===调试用===dealCurrentNeibors():chessboard[CurrentUnit[0]][CurrentUnit[1]][1]=[%d]'%chessboard[CurrentUnit[0]][CurrentUnit[1]][1])         #将该临近点存入openlist中temp = [CurrentNeibors[i][0],CurrentNeibors[i][1],chessboard[CurrentNeibors[i][0]][CurrentNeibors[i][1]][3]]OpenList.append(temp) print('===调试用===dealCurrentNeibors():OpenList.append(temp),temp=')print(temp)print('===调试用===dealCurrentNeibors():OpenList.append(temp),OpenList')print(OpenList)OpenListPosition+=1print('===调试用===dealCurrentNeibors():CurrentUnit[0]=[%d] CurrentUnit[1]=[%d]'%(CurrentUnit[0],CurrentUnit[1]))print('===调试用===dealCurrentNeibors():chessboard[CurrentUnit[0]][CurrentUnit[1]][1]=[%d]'%chessboard[CurrentUnit[0]][CurrentUnit[1]][1])         #print('===调试用===OpenList.append(temp),OpenListPosition = [%d]',%OpenListPosition)i+=2#循环变量增加2#对当前方格东南、西南、西北、东北四个方向的临近方格依次检测i = 1while i < 8 :#i+=2#循环变量增加2#当前中间结点到邻近结点的距离。约定:东南西北四个方向距离为10,四个斜方向距离为14if i%2 == 0:currenToNeibor = 10else:currenToNeibor = 14print('===调试用===dealCurrentNeibors():ObstacleEast = %d'%ObstacleEast)print('===调试用===dealCurrentNeibors():ObstacleSouth = %d'%ObstacleSouth)print('===调试用===dealCurrentNeibors():ObstacleWest = %d'%ObstacleWest)print('===调试用===dealCurrentNeibors():ObstacleNorth = %d'%ObstacleNorth)#print('===调试用===i=[%d]'%i)#调试用print('===调试用===dealCurrentNeibors():currenToNeibor=[%d]'%currenToNeibor)#调试用if 1 == ObstacleEast  and (1 == i or 7 == i): #若东方格是障碍物,则东南、东北都不能通行print('===调试用===i=[%d]'%i)#调试用i+=2continueif 1 == ObstacleSouth and (1 == i or 3 == i): #若南方格是障碍物,则东南、西南都不能通行print('===调试用===i=[%d]'%i)#调试用i+=2continueif 1 == ObstacleWest and (3 == i or 5 == i): #若西方格是障碍物,则西南、西北都不能通行print('===调试用===i=[%d]'%i)#调试用i+=2continueif 1 == ObstacleNorth and (5 == i or 7 == i): #若北方格是障碍物,则西北、东北都不能通行print('===调试用===i=[%d]'%i)#调试用i+=2continue#超出边界点if CurrentNeibors[i][0] < 0 or CurrentNeibors[i][0]>19 or CurrentNeibors[i][1] < 0 or CurrentNeibors[i][1]>19:print('===调试用===dealCurrentNeibors():超出边界点!!!(%d,%d)'%(CurrentNeibors[i][0],CurrentNeibors[i][1]))#continue #结束判断#终点elif 'e' == chessboard[CurrentNeibors[i][0]][CurrentNeibors[i][1]][4]:#flagchessboard[CurrentNeibors[i][0]][CurrentNeibors[i][1]][0][0] = CurrentUnit[0]#[0][0]parent.xchessboard[CurrentNeibors[i][0]][CurrentNeibors[i][1]][0][1] = CurrentUnit[1]#[0][1]parent.yprint('===调试用===dealCurrentNeibors():找到终点!!![%d][%d]'%(CurrentNeibors[i][0],CurrentNeibors[i][1]))#调试用          return 1#障碍物点elif 'b' == chessboard[CurrentNeibors[i][0]][CurrentNeibors[i][1]][4]:#flagsprint('===调试用===dealCurrentNeibors():找到障碍物点!!![%d][%d]'%(CurrentNeibors[i][0],CurrentNeibors[i][1]))#调试用#将该临近点与closelist中的点逐个比较elif CurrentNeibors[i] in CloseList:#python牛逼!print('===调试用===dealCurrentNeibors():CurrentNeibors[%d]是closelist中的点!!!(%d,%d)'%(i,CurrentNeibors[i][0],CurrentNeibors[i][1]))#continue#结束判断#将该临近点与openlist中的点逐个比较elif CurrentNeibors[i] in OpenlistTemp:#python牛逼!print('===调试用===dealCurrentNeibors():CurrentNeibors[i] in OpenlistTemp:')#调试用print('===调试用===dealCurrentNeibors():CurrentNeibors[i]=')print(CurrentNeibors[i])print('===调试用===dealCurrentNeibors():OpenlistTemp=')print(OpenlistTemp)#若该临近点的g值大于从起点经由当前结点到该临近结点的g值,将该临近结点的父指针指向当前结点,并更改该临近结点的g值,f值if chessboard[CurrentNeibors[i][0]][CurrentNeibors[i][1]][1] > chessboard[CurrentUnit[0]][CurrentUnit[1]][1] + currenToNeibor:#将该临近结点的父指针指向当前结点chessboard[CurrentNeibors[i][0]][CurrentNeibors[i][1]][0][0] = CurrentUnit[0]#[0][0]parent.xchessboard[CurrentNeibors[i][0]][CurrentNeibors[i][1]][0][1] = CurrentUnit[1]#[0][1]parent.yprint('===调试用===dealCurrentNeibors():修改(%d,%d)结点的父节点(%d,%d)'%(CurrentNeibors[i][0],CurrentNeibors[i][1],CurrentUnit[0],CurrentUnit[1]))#更改该临近结点的g值,f值chessboard[CurrentNeibors[i][0]][CurrentNeibors[i][1]][1] = chessboard[CurrentUnit[0]][CurrentUnit[1]][1] + currenToNeibor#g_value+currenToNeiborchessboard[CurrentNeibors[i][0]][CurrentNeibors[i][1]][3] = chessboard[CurrentNeibors[i][0]][CurrentNeibors[i][1]][1] + chessboard[CurrentNeibors[i][0]][CurrentNeibors[i][1]][2]#[1]g[2]h[3]fcounter=0while len(OpenList)-counter > 0:#大bug,漏掉了此处,导致openlist中的f_value值没有被更新!!!注意修改list值不能用forif CurrentNeibors[i][0] == OpenList[counter][0] and CurrentNeibors[i][1] == OpenList[counter][1]:#找到openlist中要修改f_value的位置OpenList[counter][2] = chessboard[CurrentNeibors[i][0]][CurrentNeibors[i][1]][3]#更新openlist中的f值breakcounter+=1#可作为通路点elif '#' == chessboard[CurrentNeibors[i][0]][CurrentNeibors[i][1]][4]:#flag#将邻居结点的指针指向当前结点chessboard[CurrentNeibors[i][0]][CurrentNeibors[i][1]][0][0] = CurrentUnit[0]#[0][0]parent.xchessboard[CurrentNeibors[i][0]][CurrentNeibors[i][1]][0][1] = CurrentUnit[1]#[0][1]parent.yprint('===调试用===dealCurrentNeibors():(%d,%d)结点的父节点为(%d,%d)'%(CurrentNeibors[i][0],CurrentNeibors[i][1],CurrentUnit[0],CurrentUnit[1]))#计算该临近结点的g值,h值(曼哈顿距离),f值chessboard[CurrentNeibors[i][0]][CurrentNeibors[i][1]][1] = chessboard[CurrentUnit[0]][CurrentUnit[1]][1] + currenToNeiborprint('===调试用===dealCurrentNeibors():CurrentUnit[0]=[%d] CurrentUnit[1]=[%d]'%(CurrentUnit[0],CurrentUnit[1]))print('===调试用===dealCurrentNeibors():chessboard[CurrentUnit[0]][CurrentUnit[1]][1]=[%d]'%chessboard[CurrentUnit[0]][CurrentUnit[1]][1])           chessboard[CurrentNeibors[i][0]][CurrentNeibors[i][1]][2] = 10 * (abs(CurrentNeibors[i][0] - End_x) + abs(CurrentNeibors[i][1] - End_y))chessboard[CurrentNeibors[i][0]][CurrentNeibors[i][1]][3] = chessboard[CurrentNeibors[i][0]][CurrentNeibors[i][1]][1] + chessboard[CurrentNeibors[i][0]][CurrentNeibors[i][1]][2]print('===调试用===dealCurrentNeibors():g_value=[%d]'%chessboard[CurrentNeibors[i][0]][CurrentNeibors[i][1]][1])print('===调试用===dealCurrentNeibors():h_value=[%d]'%chessboard[CurrentNeibors[i][0]][CurrentNeibors[i][1]][2])print('===调试用===dealCurrentNeibors():f_value=[%d]'%chessboard[CurrentNeibors[i][0]][CurrentNeibors[i][1]][3])#将该临近点存入openlist中temp = [CurrentNeibors[i][0],CurrentNeibors[i][1],chessboard[CurrentNeibors[i][0]][CurrentNeibors[i][1]][3]]OpenList.append(temp) print('===调试用===dealCurrentNeibors():OpenList.append(temp),temp=')print(temp)print('===调试用===dealCurrentNeibors():OpenList.append(temp),OpenList')print(OpenList)OpenListPosition+=1# print('===调试用===OpenList.append(temp),OpenListPosition = [%d]',%OpenListPosition)i+=2#循环变量增加2return 0def FileReadMatrix():   #将文件中的数据读回至chess_size*chess_size矩阵global Start_xglobal Start_yglobal End_xglobal End_yitemLine = []fileLine = []chessboardTemp = []ifile = open(FILE_STORAGE_WAY,'r') #作为只读文件打开fileLine = ifile.readline()while len(fileLine)>0:#将迷宫从txt文件中读入到chessboardTemp列表中print(fileLine)print(fileLine[0:20])chessboardTemp.append(fileLine[0:20])fileLine = ifile.readline()print(chessboardTemp)print(chessboardTemp[2][2])i = 0 while i <20:j = 0while j<20:#将棋盘读入到flag中if 's' == chessboardTemp[i][j]: #检测并记录起始点坐标print('起始点坐标!!![%d,%d]'%(i,j))Start_x = iStart_y = jif 'e' == chessboardTemp[i][j]: #检测并记录终止点坐标print('终止点坐标!!![%d,%d]'%(i,j))End_x = iEnd_y = jif 'b' == chessboardTemp[i][j]: #检测并记录终止点坐标print('障碍点坐标!!![%d,%d]'%(i,j))item = [[0,0],0,0,0,chessboardTemp[i][j]]#结构:A = [[parent.x,parent.y],g_value,h_value,f_value,flag]#print(item[4])itemLine.append(copy.deepcopy(item)) #结构:B = [A,A,A,A,A....,A]一行20个,一定要传切片[:]!!!print(itemLine[j][4])j+=1print(fileLine)chessboard.append(copy.deepcopy(itemLine)) #结构:[B,B,B,B,...,B] 20列,一定要传切片!!!itemLine = []#超级大bug:将itemLine清空(查了一晚上!!!!)fileLine = ifile.readline()#读取下一行数据i+=1print(chessboard[2][2][4])#print(chessboard[6][8][4])#print(chessboard)
def printPath():PathUnit = []#逆序存放单路径结点(终点->起点)PathUnitList = []#逆序存放所有路径结点(终点->起点)#获取终点的坐标                               PathUnit = [End_x,End_y]#cout << "(" << PathUnit.ChessUnit_x << "," << PathUnit.ChessUnit_y << ")" << endl;//输出终点坐标print('(%d,%d)'%(PathUnit[0],PathUnit[1]))    #记录从end起第一个最佳路径结点PathUnit = [chessboard[End_x][End_y][0][0],chessboard[End_x][End_y][0][1]]i = 0 #循环变量while not(PathUnit[0] == Start_x and PathUnit[1] == Start_y): #记录从终点到起点之间的最佳路径PathUnitList.append(copy.deepcopy(PathUnit))#重大bug!!!必须传拷贝,不然循环插入到会修改上一次PathUnit的值chessboard[PathUnitList[i][0]][PathUnitList[i][1]][4] = '*'#将最佳路径点用"*"表示#cout << "(" << PathUnitList[i].ChessUnit_x << "," << PathUnitList[i].ChessUnit_y << ")" << endl;//输出路径结点坐标#输出路径结点坐标print('(%d,%d)'%(PathUnit[0],PathUnit[1])) #获取当前结点的父节点坐标                                                                       PathUnit[0] = chessboard[PathUnitList[i][0]][PathUnitList[i][1]][0][0]PathUnit[1] = chessboard[PathUnitList[i][0]][PathUnitList[i][1]][0][1]i+=1#cout << "(" << Start_x << "," << Start_y << ")" << endl;//输出终点坐标print('(%d,%d)'%(Start_x,Start_y)) #输出终点坐标'''for (int i = 0; i < chess_size; i++){for (int j = 0; j < chess_size; j++){cout << chessboard[i][j].flag;}cout << endl;}'''temp =''i=0while i<20:j=0while j<20:temp += chessboard[i][j][4]j+=1print(temp)temp =''#清空行输出变量i+=1def main():global OpenListPositionglobal CloseListPositionglobal OpenListglobal CloseListglobal Start_xglobal Start_yFileReadMatrix()item = [Start_x,Start_y,0]#将起始点x坐标,y坐标,f值封装到列表item中print(item)OpenList.append(item)#将item插入到Openlist中OpenListPosition += 1#将起始结点存入openlist,position标记为1(position总指向最后一个元素的后一位置)while OpenListPosition > 0: #若openlist不为空openListIncraseSort() #openlist列表按f值大小降序排序(将最小f值点放在最后,这样只需将position减1就代表移出该点)#将openlist中f值最小的点移入closelist中item = [OpenList[OpenListPosition - 1][0],OpenList[OpenListPosition - 1][1]]CloseList.append(item)# print(CloseList)#调试用#openlist移出f值最小元素,清除原位置该元素信息OpenList.pop()#移除openlist中最后的那个元素print('===调试用===main():移除最小元素之后的openlist=')print(OpenList)OpenListPosition  -= 1 #将OpenListPosition减1,表示从openlist中移出最后一点,即f值最小的点#print(OpenListPosition)CloseListPosition += 1 #将ClosePosition加1,记录closelist中增加一个元素#将f最小结点信息插入到CurrentUnit中CurrentUnit = [CloseList[CloseListPosition - 1][0],CloseList[CloseListPosition - 1][1]]print('===调试用===main():CloseListPosition=[%d]'%CloseListPosition)print('===调试用===main():CloseList=')print('===调试用===main():CloseList=')print(CloseList)#判断当前结点周围8个点状态,计算g、h、f值,将周围每个点的父指针指向当前结点if dealCurrentNeibors(CurrentUnit) == 1:print('===调试用===main():找到终点,跳出循环')print('===调试用===main():找到终点,跳出循环')print('===调试用===main():找到终点,跳出循环')break#dealCurrentNeibors(CurrentUnit)print('===调试用===OpenListPosition=[%d]'%OpenListPosition)#whileprintPath()#return 0main()

A*寻路算法python版(第二版)相关推荐

  1. Python 程序设计(第二版)董付国_清华大学出版社_习题答案与分析【针对8.4及其之前的】

    更多精彩内容:(没有设置公众号获得,麻烦动动小手~谢谢) CSDN下载:Python编程无师自通电子书,[美]科里·奥尔索夫(Cory Althoff)-文档类-CSDN下载 百度云:链接:https ...

  2. 从零开始学习python-《从零开始学 Python》(第二版)

    老齐 · 更新于 2018-11-28 11:00:43 <零基础学 Python>(第二版) Python 是一种面向对象.解释型计算机程序设计语言,由 Guido van Rossum ...

  3. python编程入门 适合于零基础朋友-《从零开始学 Python》(第二版)

    老齐 · 更新于 2018-11-28 11:00:43 <零基础学 Python>(第二版) Python 是一种面向对象.解释型计算机程序设计语言,由 Guido van Rossum ...

  4. Python 程序设计(第二版)董付国_清华大学出版社_习题答案【未处理1-9章】

    CSDN下载:https://download.csdn.net/download/weixin_42859280/11254583 百度云:链接:https://pan.baidu.com/s/1i ...

  5. 数据结构C语言版第二版第六章原创总结

    数据结构C语言版第二版第六章原创总结 图章节原创总结

  6. 零基础入门学python 第二版-《零基础入门学习Python》第二版和第一版的区别在哪里呢?...

    第一版 时光荏苒,一晃间,距离<零基础入门学习 Python>出版(2016年11月)已经过去两年多了,在这段时间里, Python 逐步走入了大家的视野,这门语言因其简洁的语法风格,在云 ...

  7. 零基础学python鱼c-《零基础入门学习Python》第二版和第一版的区别在哪里呢?...

    第一版 时光荏苒,一晃间,距离<零基础入门学习 Python>出版(2016年11月)已经过去两年多了,在这段时间里, Python 逐步走入了大家的视野,这门语言因其简洁的语法风格,在云 ...

  8. 学习参考《父与子的编程之旅python【第二版】》高清中文版PDF+高清英文版PDF+源代码...

    对于初步接触编程语言的朋友,推荐看一看<父与子的编程之旅第2版>,对于完全编程零基础的很友好! 图文并茂,过多的文字堆垒很容易让人产生厌倦情绪,也更容易让人产生放弃的想法.使用了大量插图, ...

  9. python机器学习第二版(读书笔记)

    第一章 赋予计算机从数据中学习的能力 每一行:代表一个样本,行向量用上标表示:每一列:代表一个维度,列向量用下标表示. numpy:多维矩阵的存储和操作数据,pandas:基于numpy,提供更高级操 ...

最新文章

  1. 数据分析之Pandas分组操作总结
  2. python字符串find函数-Python字符串的方法,查找和替换
  3. Java内存模型深度解析:基础部分--转
  4. zcmu-2149(归并排序)
  5. 转载:由图片SEO想起
  6. 第九章 Libgdx内存管理
  7. 如何使用Spring Security和Basic身份验证保护Jersey REST服务
  8. Android:SharedPreferences详解+示例
  9. 透彻解析云原生在数字化转型中的应用实践,PaaS功不可没
  10. 详解汇编里的单步中断-T使用寄存器标志位TF和IF
  11. 配置项setOption -- title
  12. ziplist之详细分析
  13. linux系统如何查看tomcat版本,【Linux查看tomcat版本】
  14. oracle function详解,Oracle函数用法详解
  15. 【ClearCase使用】之图解merge
  16. 关于sematic segmentation的几篇论文(二)
  17. 为何贩卖焦虑的文章如此受欢迎???
  18. surface usb启动_Surface Book 2开发人员印象和USB-C的魔力
  19. 区块链蕴含的变革力量
  20. 正则表达式 RegExp

热门文章

  1. keil如何添加h文件_被Keil坑了一天!实在太意外了!用Keil的来瞅瞅看
  2. 基于JAVA郑州卷烟厂库存管理系统计算机毕业设计源码+系统+mysql数据库+lw文档+部署
  3. 微信小程序之父子间组件传参
  4. NLP创业破局,如何摘取更高处的果实
  5. 数据库高并发解决方案(二)部署优化
  6. zk - zookeeper主节点、从节点、客户端三者之间的交互
  7. 酷睿是图拉丁的孙子[经典理论]
  8. View与ViewGroup
  9. 西门子在华启动“零碳先锋计划”;希尔顿欢朋在华项目签约数突破600 | 美通社头条...
  10. ECS与EDAS什么意思?