算法-使用递归求解迷宫问题
题目要求:
现有一个迷宫,四周都被围起来了,只能从一个入口进入,计算出一条通道使得从入口可以安全到达出口。在迷宫中行走的方向可以是(北,东北,东,东南,南,西南,西,西北)八个方向,迷宫图案如下:
[ [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) 源代码