python 自学,以一个常规的习题做自己这段时间的学习总结
问题描述:
给定迷宫,入口坐标和出口坐标,给出一条从入口到出口的坐标路径,并完成可视化。
例如:
迷宫
listMap=[
['1', '0', '1', '1', '1', '1', '1', '1', '1'],\
['1', '0', '0', '0', '1', '0', '1', '0', '1'],\
['1', '1', '1', '0', '1', '1', '1', '0', '1'],\
['1', '0', '0', '0', '0', '0', '0', '0', '1'],\
['1', '0', '0', '1', '1', '1', '1', '0', '1'],\
['1', '0', '0', '0', '0', '0', '0', '0', '1'],\
['1', '1', '1', '1', '1', '0', '1', '0', '1'],\
['1', '0', '0', '0', '0', '0', '0', '0', '1'],\
['1', '1', '1', '1', '1', '1', '1', '0', '1'] ]
1为墙,0为路径
入口坐标:(0,1)0为y,行号;1为x,列号;
出口坐标:(8,7)8为y,行号;7为x,列好。
坐标系:x水平向右,y垂直向下
======================系统输出如下==============
(0, 1)
(1, 1)
(1, 2)
(1, 3)
(2, 3)
(3, 3)
(3, 2)
(4, 2)
(5, 2)
(5, 3)
(5, 4)
(5, 5)
(6, 5)
(7, 5)
(7, 6)
(7, 7)
(8, 7)
1 * 1 1 1 1 1 1 1
1 * * * 1 0 1 0 1
1 1 1 * 1 1 1 0 1
1 0 * * 0 0 0 0 1
1 0 * 1 1 1 1 0 1
1 0 * * * * 0 0 1
1 1 1 1 1 * 1 0 1
1 0 0 0 0 * * * 1
1 1 1 1 1 1 1 * 1
============================================
思路:自然路径探测。
函数:findChild。
从fthPoint 走到CurrentPoint,然后根据CurrentPoint向4个方向探测,如果这4个方向的坐标不是fthPoint,且该3个方向的坐标不是1,则将CurrentPoint存入字典的key里面,将它的3个方向中为0的坐标存入字典的value里面。然后从这三个方向的坐标中选一个,作为新的CurrentPoint,原先的CurrentPoint作为fthPoint,继续探测,直到某一个坐标为出口坐标。
回溯函数:back
在上面的CurrentPoint没有为0的子坐标,则说明这条路径不通,从字典中删除父节点,如果父节点的父节点已经没有可用路径,则继续向上删除,如果有,选一个新的坐标,做findChild探测。
为保存当前节点的可用路径,定义结构体如下:
class itemValue:
def __init__(self):
self.fPoint=(0,1) #父节点坐标
self.dirs=[] # 不包含父节点的所有子节点,
地图和入口出口坐标定义如下:
listMap=[
['1', '0', '1', '1', '1', '1', '1', '1', '1'],\
['1', '0', '0', '0', '1', '0', '1', '0', '1'],\
['1', '1', '1', '0', '1', '1', '1', '0', '1'],\
['1', '0', '0', '0', '0', '0', '0', '0', '1'],\
['1', '0', '0', '1', '1', '1', '1', '0', '1'],\
['1', '0', '0', '0', '0', '0', '0', '0', '1'],\
['1', '1', '1', '1', '1', '0', '1', '0', '1'],\
['1', '0', '0', '0', '0', '0', '0', '0', '1'],\
['1', '1', '1', '1', '1', '1', '1', '0', '1'] ]
dictPath =dict()
endPoint = (8, 7) #8为y 行,7为x 列
查找子节点的函数如下:
def find_child(fthPoint,currPoint): #没有可用子节点,则返回失败,否则将可用子节点添加到dict
childItem=itemValue()
childItem.fPoint=fthPoint
point=(currPoint[0]+1,currPoint[1])
if point == endPoint:
childItem.dirs.append(point)
dictPath[currPoint] = childItem
return True
if point not in dictPath.keys():
if listMap[point[0]][point[1]] == '0':
childItem.dirs.append(point)
point = (currPoint[0] , currPoint[1]-1)
if point == endPoint:
childItem.dirs.append(point)
dictPath[currPoint] = childItem
return True
if point not in dictPath.keys():
if listMap[point[0]][point[1]] == '0':
childItem.dirs.append(point)
point = (currPoint[0]-1 , currPoint[1])
if point == endPoint:
childItem.dirs.append(point)
dictPath[currPoint] = childItem
return True
if point not in dictPath.keys():
if listMap[point[0]][point[1]] == '0':
childItem.dirs.append(point)
point = (currPoint[0], currPoint[1]+1)
if point == endPoint:
childItem.dirs.append(point)
dictPath[currPoint] = childItem
return True
if point not in dictPath.keys():
if listMap[point[0]][point[1]] == '0':
childItem.dirs.append(point)
if len(childItem.dirs)==0:
back(fthPoint)
else:
dictPath[currPoint] = childItem
point = childItem.dirs[0]
if(currPoint !=endPoint):find_child(currPoint,point)
else: return True
死胡同,回溯函数如下
def back(point):
value1=dictPath[point]
fthPoint =value1.fPoint;#找到当前点的父节点
if(fthPoint==point):
print("no path")
exit(0)
dictPath.pop(point)
fthValue = dictPath[fthPoint]
fthValue.dirs.remove(point)
if len(fthValue.dirs)==0:
back(fthPoint)
else:
value2 =dictPath[fthPoint]
currPoint =value2.dirs[0]
find_child(fthPoint,currPoint)
结果可视化和输出函数如下:
def main():
beginPoint=(0,1)
childPoint=(1,1)
itemValue0 =itemValue()
itemValue0.fPoint=beginPoint
itemValue0.dirs.append(childPoint)
dictPath[beginPoint]=itemValue0
find_child(beginPoint,childPoint)
childItem = itemValue()
dictPath[endPoint] = childItem
for key,value in dictPath.items():
print(key)
for y in range(len(listMap)):
for x in range(len(listMap[0])):
if (y,x) in dictPath.keys():
print(' * ',end='')
else:
print(" %s "%listMap[y][x],end='')
print()
return 1
main()