算法之使用遞歸求解迷宮問題


 

題目要求:

現有一個迷宮,四周都被圍起來了,只能從一個入口進入,計算出一條通道使得從入口可以安全到達出口。在迷宮中行走的方向可以是(北,東北,東,東南,南,西南,西,西北)八個方向,迷宮圖案如下:

 1 [
 2     [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
 3     [0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1],
 4     [1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1],
 5     [1, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1],
 6     [1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 0, 0, 1],
 7     [1, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1],
 8     [1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1],
 9     [1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1],
10     [1, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1],
11     [1, 0, 0, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1],
12     [1, 1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 1],
13     [1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 1],
14     [1, 0, 1, 0, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0],
15     [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
16 ]

入口位置在第二行第一列的位置,出口位置在倒數第二行最后一列的位置。中間是0的位置表示可以到達,其他位置被堵死。

 

解決思路:

假設在該迷宮中的某一點,其有八個方向可供選擇,那么,遍歷這八個方向,探測這周邊八個方向是否是可達的,如果可達,那再以可達的點為當前點,繼續遍歷八個方向檢測其周邊的方向是否可達。設置一個標記表,只要是走過的點,都將標記位設置為1,這樣是為了不走之前走過的老路。這樣遞歸下去,直到到達我們想要出去的迷宮的出口處位置時,到達遞歸的最大深度,之后一層一層反向打印出之前走過的位置。。。

 1 #!/usr/bin/env python
 2 # encoding:utf-8
 3 # __author__: huxianglin
 4 # date: 2016-09-04
 5 # blog: http://huxianglin.cnblogs.com/ http://xianglinhu.blog.51cto.com/
 6 
 7 MAZE = [
 8     [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
 9     [0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1],
10     [1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1],
11     [1, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1],
12     [1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 0, 0, 1],
13     [1, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1],
14     [1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1],
15     [1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1],
16     [1, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1],
17     [1, 0, 0, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1],
18     [1, 1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 1],
19     [1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 1],
20     [1, 0, 1, 0, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0],
21     [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
22 ]
23 
24 MOVE = [[0, -1, "N"], [1, -1, "NE"], [1, 0, "E"], [1, 1, "SE"], [0, 1, "S"], [-1, 1, "SW"], [-1, 0, "W"],
25         [-1, -1, "NW"]]
26 
27 
28 def seek_path(x, y):  # x,y作為橫縱坐標傳遞進來
29     if x == LINE-1 and y == ROW-2:  # 出口地址
30         return True
31     for i in range(8):  # 循環找八個方向看哪個方向有路
32         line, row, direction = x+MOVE[i][0], y+MOVE[i][1], MOVE[i][2]  # 將當前位置的移動后的坐標以及移動方向賦值給新變量用來遞歸
33         if MAZE[row][line] == 0 and mark[row][line] == 0:  # 移動后的坐標是通的並且之前沒走過
34             mark[row][line] = 1  # 將該新位置坐標標記為已走過
35             if seek_path(line, row):  # 將新坐標傳遞到遞歸函數中進行下一步遞歸
36                 print("橫向移動:%s,縱向移動:%s,方向:%s" % (MOVE[i][0], MOVE[i][1], direction))
37                 path.append(["橫向移動:%s" % MOVE[i][0], "縱向移動:%s" % MOVE[i][1], "方向:%s" % direction,
38                              "坐標:(%s,%s)" % (line, row)])
39                 return True
40 
41 if __name__ == "__main__":
42     LINE, ROW = len(MAZE[0]), len(MAZE)
43     mark = []
44     # for i in range(14):
45     #     mark.append([0 for j in range(17)])
46     mark = [[0 for v in range(len(MAZE[0]))] for m in range(len(MAZE))]  # 列表推導試生成mark列表
47     path = []
48     mark[1][0] = 1
49     if seek_path(0, 1):
50         print("迷宮走完了...下面是每一步的詳細情況:")
51     path.reverse()
52     for i in path:
53         print(i)
源代碼

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM