Python使用回溯法子集樹模板解決迷宮問題示例

2022-10-04 20:54:18 字數 1927 閱讀 7376

問題

給定乙個迷宮,入口已知。問是否有路徑從入口到出口,若有則輸出一條這樣的路徑。注意移動可以從上、下、左、右、上左、上右、下左、下右八個方向進行。迷宮輸入0表示可走,輸入1表示牆。為方便起見,用1將迷宮圍起來避免邊界問題。

分析考慮到左、右是相對的,因此修改為:北、東北、東、東南、南、西南、西、西北八個方向。在任意一格內,有8個方向可以選擇,亦即8種狀態可選。因此從入口格仔開始,每進入一格都要遍歷這8種狀態。

顯然,可以套用回溯法的子集樹模板。

注意,解的長度是不固定的。

**# 迷宮(1是牆,0是通路)

maze = [[1,1,1,1,1,1,1,1,1,1],

[0,0,1,0,1,1,1,1,0,1],

[1,1,0,1,0,1,1,0,1,1],

[1,0,1,1,1,0,0,1,1,1],

[1,1,1,0,0,1,1,0,1,1],

[1,1,0,1,1,1,1,1,0,1],

[1,0,1,0,0,1,1,1,1,0],

[1,1,1,1,1,0,1,1,1,1]]

m, n = 8, 10 # 8行,10列

entry = (1,0) # 迷宮入口

path = [entry] # 乙個解(路徑)

paths = # 一組解

# 移動的方向(順時針8個:n, en, e, es, s, ws, w, wn)

directions = [(-1,0),(-1,1),(0,1),(1,1),(1,0),(1,-1),(0,-1),(-1,-1)]

# 衝突檢測

def conflict(nx, ny):

global m,n,maze

# 是否在迷宮中,以及是否可通行

if 0 <= nx < m and 0 <= ny < n and maze[nx][ny]==0:

return false

return true

# 套用子集樹模板

def walk(x, y): # 到達(x,y)格仔

global entry,m,n,maze,path,paths,directions

if (x,y) != entry and (x % (m-1) ==0 or y % (n-1) == 0): # 出口

#print(path)

paths.append(path[:]) # 直接儲存,未做最優化

else:

for d in directions: # 遍歷8個方向(亦即8個狀態)

nx, ny = x+d[0], y+d[1]

path.append((nx,ny)) # 儲存,新座標入棧

if not conflict(nx, ny): # 剪枝

maze[nx][ny] = 2 # 標記,已訪問(奇怪,此兩句只能放在if區塊內!)

walk(nx, ny)

maze[程式設計客棧nx][ny] = 0 # 回溯,恢復

path.pop() # 回溯,出棧

# 解的視覺化(根據乙個解x,復原迷宮路徑,'2'表示通路)

def show(path):

gl程式設計客棧obal maze

import www.cppcns.compprint, copy

maze2 = copy.deepcopy(maze)

for p in path:

maze2[p[0]][p[1]] = 2 # 通路

pprint.pprint(maze) # 原迷宮

print()

pprint.pprint(maze2) # 帶通路的迷宮

# 測試

walk(1,0)

print(paths[-1], '\n') # 看看最後一條路徑

show(paths[-1])

效果圖

Python使用回溯法子集樹模板解決爬樓梯問題示例

問題 某樓梯有n層台階,每步只能走1級台階,或2級台階。從下向上爬樓梯,有多少種爬法?分析這個問題之前用分治法解決過。但是,這裡我要用回溯法www.cppcns.com子集樹模板解決它。祭出元素 狀態空間分析 每一步是乙個元素,可走的步數 1,2 就是其狀態空間。不難看出,元素不固定,狀態空間固定。...

python 用回溯法(子集樹)解n皇后問題

n皇后問題 如何能夠在 n n 的西洋棋棋盤上放置n個皇后,使得任何乙個皇后都無法直接吃掉其他的皇后。為了達到此目的,任兩個皇后都不能處於同一條橫行 縱行或斜線上。def backtrack t,n 核心 if t n output return else for i in range n a t ...

Python 回溯法 子集樹模組系列 八皇后問題

案例 八皇后問題是乙個以西洋棋為背景的問題 如何能夠在 8 8 的西洋棋棋盤上放置八個皇后,使得任何乙個皇后都無法直接吃掉其他的皇后?為了達到此目的,任兩個皇后都不能處於同一條橫行 縱行或斜線上。八皇后問題可以推廣為更一般的n皇后擺放問題 這時棋盤的大小變為n n,而皇后個數也變成n。當且僅當 n ...