迷宮問題求解實現

1.思路:可以敏銳的察覺,迷宮這個問題可以採用遞歸的思路

  • 查詢當前位置是否是出口
  • 是:返回True
  •  否:繼續查找本位置的四個鄰邊位置
  • 用for 循環 每一個鄰邊位置都要找
  • if 一旦有找到,立即停止搜尋。返回True
  • 在程序最後還沒有返回True
  • 只好返回 Flase

從這個遞歸過程,讓我再一次深刻認識到遞歸的實現過程:

  • 從最簡單的情況開始,返回結果
  • 如果沒有到達,最簡單的情況,找到本次情況的下一個情況(有時,不止下一個情況,可能是很多情況並列,比如本題:這個時候就要用if 語句(排除已經訪問過的),或者for 循環來一個一個情況執行),在每一個情況內部:調用函數自己

2.基於遞歸的求解代碼:

# 1.表示迷宮 maze抽象化形成矩陣
#2.利用好遞歸性質
maze=[[0,0,1,1,1],[1,0,1,0,0],[0,0,1,0,0],[1,0,0,1,0],[0,0,0,0,0],[0,1,1,0,1]]

def mark(maze,pos):
    maze[pos[0]][pos[1]]=2
    

def findit(maze,start,end):
    dir1=((-1,0),(0,1),(1,0),(0,-1))
    #print("調用了幾次find每次的起點是:",start)
    if start==end:
        print(start) # 注意這裏是無法返回值的
    else:
        mark(maze,start)
        start1=start[:]  # 這裏最容易寫成 star1=start
        #print("出現一次")
        for i in range(0,4):
          #  print("四個方向 ",start1)
            start[0]=start1[0]  # 用於保留本次循環起點
            start[1]=start1[1]  
            (start[0],start[1])=(start[0]+dir1[i][0],start[1]+dir1[i][1])
            #print("最後",start)
            if 0<=start[0]<=len(maze)-1 and 0<=start[1]<=len(maze[0])-1:
                if maze[start[0]][start[1]]==0:
                    findit(maze,start,end)
                    
findit(maze,[1,3],[5,3])

3. 基於堆棧的非遞歸深度優先方法

#利用棧的回溯法,(遞歸的人工實現)

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

def mark(maze,pos):
    maze[pos[0]][pos[1]]=2

def findit(maze,pos,end): # 參數 迷宮矩陣 運動點 終點
    dir1=((-1,0),(0,1),(1,0),(0,-1)) # 嚇一跳參數
    st= []
    if pos==end:
        return pos
    else:
        mark(maze,pos)
        st.append(pos)
        while st: # 總體就是 先畫出操作圖,在根據圖來把控程序
            pos=st.pop()
            pos1=pos[:]  # 這個細節要注意
            for i in range(4):
                pos=pos1[:] # 要注意
                pos[0],pos[1]=pos[0]+dir1[i][0],pos[1]+dir1[i][1]
                #print("四個方向",pos)
                if 0<=pos[0]<=len(maze)-1 and 0<=pos[1]<=len(maze[0])-1:
                    if maze[pos[0]][pos[1]]==0:
                        if pos==end:
                            return end
                        else:
                            mark(maze,pos)
                            print("1,4",pos)
                            st.append(pos)
    print("沒有找到")          
                        
findit(maze,[1,4],[1,3])              
            

4. 基於隊列的廣度優先算法實現

# 基於隊列的廣度優先
from queue import Queue  # 注意命名模塊時不要用預留字

maze=[[0,0,1,1,1],[1,0,1,0,0],[0,0,1,0,0],[1,0,0,1,0],[0,0,0,0,0],[0,1,1,0,1]]
def mark(maze,pos):
    maze[pos[0]][pos[1]]=2

def findit(maze,pos,end):
    que=Queue()
    dir1=((-1,0),(0,1),(1,0),(0,-1)) # 嚇一跳參數
    if pos==end:
        return pos
    else:
        que.put(pos)
        while not que.empty():
            pos1=que.get()
            #print(pos1)
            mark(maze,pos1)
            for i in range(4):
                pos=pos1[:]
                pos[0],pos[1]=pos[0]+dir1[i][0],pos[1]+dir1[i][1]
                if 0<=pos[0]<=len(maze)-1 and 0<=pos[1]<=len(maze[0])-1:
                    if maze[pos[0]][pos[1]]==0:
                        if pos==end:
                            return pos
                        else:
                            que.put(pos)
    print("沒有找到")
ans=findit(maze,[1,3],[0,1])
print(ans)
            

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章