算法-使用递归求解迷宫问题
题目要求:
现有一个迷宫,四周都被围起来了,只能从一个入口进入,计算出一条通道使得从入口可以安全到达出口。在迷宫中行走的方向可以是(北,东北,东,东南,南,西南,西,西北)八个方向,迷宫图案如下:
[
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
[0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1],
[1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1],
[1, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1],
[1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 0, 0, 1],
[1, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1],
[1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1],
[1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1],
[1, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1],
[1, 0, 0, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1],
[1, 1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 1],
[1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 1],
[1, 0, 1, 0, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0],
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
]
入口位置在第二行第一列的位置,出口位置在倒数第二行最后一列的位置。中间是0的位置表示可以到达,其他位置被堵死。
解决思路:
假设在该迷宫中的某一点,其有八个方向可供选择,那么,遍历这八个方向,探测这周边八个方向是否是可达的,如果可达,那再以可达的点为当前点,继续遍历八个方向检测其周边的方向是否可达。设置一个标记表,只要是走过的点,都将标记位设置为1,这样是为了不走之前走过的老路。这样递归下去,直到到达我们想要出去的迷宫的出口处位置时,到达递归的最大深度,之后一层一层反向打印出之前走过的位置。。。
解决代码:
#!/usr/bin/env python
# encoding:utf-8
# __author__: huxianglin
# date: 2016-09-04
# blog: http://huxianglin.cnblogs.com/ http://xianglinhu.blog.51cto.com/
MAZE = [
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
[0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1],
[1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1],
[1, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1],
[1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 0, 0, 1],
[1, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1],
[1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1],
[1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1],
[1, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1],
[1, 0, 0, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1],
[1, 1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 1],
[1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 1],
[1, 0, 1, 0, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0],
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
]
MOVE = [[0, -1, "N"], [1, -1, "NE"], [1, 0, "E"], [1, 1, "SE"], [0, 1, "S"], [-1, 1, "SW"], [-1, 0, "W"],
[-1, -1, "NW"]]
def seek_path(x, y): # x,y作为横纵坐标传递进来
if x == LINE-1 and y == ROW-2: # 出口地址
return True
for i in range(8): # 循环找八个方向看哪个方向有路
line, row, direction = x+MOVE[i][0], y+MOVE[i][1], MOVE[i][2] # 将当前位置的移动后的坐标以及移动方向赋值给新变量用来递归
if MAZE[row][line] == 0 and mark[row][line] == 0: # 移动后的坐标是通的并且之前没走过
mark[row][line] = 1 # 将该新位置坐标标记为已走过
if seek_path(line, row): # 将新坐标传递到递归函数中进行下一步递归
print("横向移动:%s,纵向移动:%s,方向:%s" % (MOVE[i][0], MOVE[i][1], direction))
path.append(["横向移动:%s" % MOVE[i][0], "纵向移动:%s" % MOVE[i][1], "方向:%s" % direction,
"坐标:(%s,%s)" % (line, row)])
return True
if __name__ == "__main__":
LINE, ROW = len(MAZE[0]), len(MAZE)
mark = []
# for i in range(14):
# mark.append([0 for j in range(17)])
mark = [[0 for v in range(len(MAZE[0]))] for m in range(len(MAZE))] # 列表推导试生成mark列表
path = []
mark[1][0] = 1
if seek_path(0, 1):
print("迷宫走完了...下面是每一步的详细情况:")
path.reverse()
for i in path:
print(i)
源代码

浙公网安备 33010602011771号