<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
在迷宮問題中,給定入口和出口,要求找到路徑。本文將討論三種求解方法,遞迴求解、回溯求解和佇列求解。
在介紹具體演演算法之前,先考慮將迷宮數位化。這裡將迷宮用一個二維的list儲存(即list巢狀在list裡),將不可到達的位置用1表示,可到達的位置用0表示,並將已經到過的位置用2表示。
遞迴求解的基本思路是:
在整個計算開始時,把迷宮的人口(序對)作為檢查的當前位置,演演算法過程就是:
dirs=[(0,1),(1,0),(0,-1),(-1,0)] #當前位置四個方向的偏移量 path=[] #存找到的路徑 def mark(maze,pos): #給迷宮maze的位置pos標"2"表示「倒過了」 maze[pos[0]][pos[1]]=2 def passable(maze,pos): #檢查迷宮maze的位置pos是否可通行 return maze[pos[0]][pos[1]]==0 def find_path(maze,pos,end): mark(maze,pos) if pos==end: print(pos,end=" ") #已到達出口,輸出這個位置。成功結束 path.append(pos) return True for i in range(4): #否則按四個方向順序檢查 nextp=pos[0]+dirs[i][0],pos[1]+dirs[i][1] #考慮下一個可能方向 if passable(maze,nextp): #不可行的相鄰位置不管 if find_path(maze,nextp,end):#如果從nextp可達出口,輸出這個位置,成功結束 print(pos,end=" ") path.append(pos) return True return False def see_path(maze,path): #使尋找到的路徑視覺化 for i,p in enumerate(path): if i==0: maze[p[0]][p[1]] ="E" elif i==len(path)-1: maze[p[0]][p[1]]="S" else: maze[p[0]][p[1]] =3 print("n") for r in maze: for c in r: if c==3: print(' 33[0;31m'+"*"+" "+' 33[0m',end="") elif c=="S" or c=="E": print(' 33[0;34m'+c+" " + ' 33[0m', end="") elif c==2: print(' 33[0;32m'+"#"+" "+' 33[0m',end="") elif c==1: print(' 33[0;;40m'+" "*2+' 33[0m',end="") else: print(" "*2,end="") print() if __name__ == '__main__': maze=[[1,1,1,1,1,1,1,1,1,1,1,1,1,1], [1,0,0,0,1,1,0,0,0,1,0,0,0,1], [1,0,1,0,0,0,0,1,0,1,0,1,0,1], [1,0,1,0,1,1,1,1,0,1,0,1,0,1], [1,0,1,0,0,0,0,0,0,1,1,1,0,1], [1,0,1,1,1,1,1,1,1,1,0,0,0,1], [1,0,1,0,0,0,0,0,0,0,0,1,0,1], [1,0,0,0,1,1,1,0,1,0,1,1,0,1], [1,0,1,0,1,0,1,0,1,0,1,0,0,1], [1,0,1,0,1,0,1,0,1,1,1,1,0,1], [1,0,1,0,0,0,1,0,0,1,0,0,0,1], [1,1,1,1,1,1,1,1,1,1,1,1,1,1]] start=(1,1) end=(10,12) find_path(maze,start,end) see_path(maze,path)
程式碼中see_path函數可以在控制檯直觀列印出找到的路徑,列印結果如下:
S是入口位置 ,E是出口位置,*代表找到的路徑,#代表探索過的路徑。
在回溯解法中,主要是用棧來儲存可以探索的位置。利用棧後進先出的特點,在一條分路上探索失敗時,回到最近一次儲存的可探索位置。這是一種深度優先搜尋的方法。
def maze_solver(maze,start,end): if start==end: print(start) return st=SStack() mark(maze,start) st.push((start,0)) #入口和方向0的序對入棧 while not st.is_empty(): #走不通時回退 pos,nxt=st.pop() #取棧頂及其檢查方向 for i in range(nxt,4): #依次檢查未檢查方向,算出下一位置 nextp = pos[0] + dirs[i][0], pos[1] + dirs[i][1] if nextp==end: print_path(end,pos,st) #到達出口,列印位置 return if passable(maze,nextp): #遇到未探索的新位置 st.push((pos,i+1)) #原位置和下一方向入棧 mark(maze,nextp) st.push((nextp,0)) #新位置入棧 break #退出內層迴圈,下次迭代將以新棧頂作為當前位置繼續 print("找不到路徑")
佇列求解演演算法中,以佇列儲存可以探索的位置。利用佇列先進先出的特點,實現在每個分支上同時進行搜尋路徑,直到找到出口。這是一種廣度優先搜尋的方法。
def maze_solver_queue(maze,start,end): path.append(start) if start==end: print("找到路徑") return qu=SQueue() mark(maze,start) qu.enqueue(start) #start位置入隊 while not qu.is_empty(): #還有候選位置 pos=qu.dequeue() #取出下一位置 for i in range(4): #檢查每個方向 nextp = pos[0] + dirs[i][0], pos[1] + dirs[i][1] if passable(maze,nextp): #找到新的探索方向 if nextp==end: #是出口,成功 print("找到路徑") path.append(end) return mark(maze,nextp) qu.enqueue(nextp) #新位置入隊 path.append(nextp) print("未找到路徑")
但佇列求解方法,不能直接得出找到的具體路徑,要得到找到的路徑還需要其他儲存結構(如連結串列)。
到此這篇關於使用python求解迷宮問題的三種實現方法的文章就介紹到這了,更多相關python求解迷宮問題內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45