最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Python 實(shí)現(xiàn)遞歸法解決迷宮問(wèn)題的示例代碼

 更新時(shí)間:2020年01月12日 11:20:42   作者:HibiscusToYou  
這篇文章主要介紹了Python 實(shí)現(xiàn)遞歸法解決迷宮問(wèn)題的示例代碼,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧

迷宮問(wèn)題

問(wèn)題描述:

迷宮可用方陣 [m, n] 表示,0 表示可通過(guò),1 表示不能通過(guò)。若要求左上角 (0, 0) 進(jìn)入,設(shè)計(jì)算法尋求一條能從右下角 (m-1, n-1) 出去的路徑。

示例圖:

期望輸出路徑圖

此示例圖基本參數(shù)為:

  • m:對(duì)應(yīng)
  • x 軸n:對(duì)應(yīng) y 軸
  • 綠色線代表期望輸出的路徑

算法思路

  1. 標(biāo)記當(dāng)前所在位置
  2. 如果此時(shí)所在位置為終點(diǎn),說(shuō)明可以到達(dá)終點(diǎn),退出遞歸;

否則,則存在 4 種可能的移動(dòng)方向即上、下、左、右,遍歷這 4 個(gè)方向,如果這 4 個(gè)方向存在相鄰值為 0 的點(diǎn),則將當(dāng)前點(diǎn)坐標(biāo)標(biāo)記為該相鄰值為 0 的點(diǎn)坐標(biāo),進(jìn)入遞歸

直觀理解為:

遞歸理解圖

上圖中紅色圈的相鄰值為 0 的點(diǎn)有 3 個(gè),則會(huì)依次遍歷這 3 個(gè)點(diǎn)尋求某一條件并進(jìn)入遞歸

實(shí)現(xiàn)過(guò)程

標(biāo)記函數(shù)

def mark(maze, pos):
  """
  標(biāo)記函數(shù),用來(lái)標(biāo)記歷史走過(guò)的位置
  :param maze: 一個(gè) m*n 大小的二維矩陣迷宮
  :param pos: 當(dāng)前需要標(biāo)記的位置坐標(biāo) pos = (x, y),x = pos[0], y = pos[1]
  """
  maze[pos[0]][pos[1]] = 2 # 將走過(guò)的位置標(biāo)記為 2

移動(dòng)函數(shù)

def move(maze, pos):
  """
  移動(dòng)函數(shù),用來(lái)測(cè)試當(dāng)前位置是否可繼續(xù)移動(dòng),移動(dòng)條件為當(dāng)前位置為 0
  :param maze: 一個(gè) m*n 大小的二維矩陣迷宮
  :param pos: 當(dāng)前需要標(biāo)記的位置坐標(biāo) pos = (x, y),x = pos[0], y = pos[1]
  :return: bool 類(lèi)型
  """
  return maze[pos[0]][pos[1]] == 0

核心函數(shù) - 路徑查找函數(shù)

def find_path(maze, start, end):
  """
  路徑查找函數(shù)
  :param maze: 一個(gè) m*n 大小的二維矩陣迷宮
  :param start: 起始點(diǎn)位置坐標(biāo),start = (1, 1)
  :param end: 終點(diǎn)坐標(biāo),end = (m, n)
  :return: bool 類(lèi)型
  """
  mark(maze, start) # 將起始位置標(biāo)記
  if start == end: # 路徑查找(遞歸)終止條件為到達(dá)終點(diǎn)
    move_path.append(start)
    return True

  # 未到達(dá)終點(diǎn)時(shí),存在 4 種可能的移動(dòng)方向,即上 (-1, 0),下 (1, 0),左 (0, -1),右 (0, 1)
  move_direction = [
    (-1, 0), (1, 0), (0, -1), (0, 1)
  ]
  direction = ['↑', '↓', '←', '→']
  for i in range(4): # 遍歷 4 種可能的方向
    next_start = (start[0] + move_direction[i][0], start[1] + move_direction[i][1]) # 下一個(gè)可能的起始點(diǎn)坐標(biāo)
    if move(maze, next_start): # 找出存在 0 即可移動(dòng)的下一個(gè)起始點(diǎn)坐標(biāo),進(jìn)入遞歸
      if find_path(maze, next_start, end):
        # 這里之所以仍然添加起始點(diǎn)坐標(biāo)是因?yàn)楫?dāng)查詢(xún)到下一個(gè)位置就是終點(diǎn)或者可到達(dá)終點(diǎn)時(shí)記錄此時(shí)位置
        move_path.append(start)
        path_direction.append(direction[i]) # 記錄路徑方向
        return True
  return False # 遍歷遞歸了 4 種可能方向后仍不能到達(dá)終點(diǎn)則說(shuō)明無(wú)法走出迷宮

算法到這里基本上已經(jīng)算完成,整體上不算太復(fù)雜

美化輸出

生成帶有移動(dòng)路徑數(shù)據(jù)的迷宮矩陣

def path_maze(maze, directions_map):
  """
  生成帶有移動(dòng)路徑的迷宮矩陣
  :param maze: 一個(gè) m*n 大小的二維矩陣迷宮
  :param directions_map: 一個(gè)記錄移動(dòng)方向坐標(biāo)的字典,有 ↑,↓,←,→ 4 個(gè)元素
  :return: path_maze
  """
  n, m = len(maze[0]), len(maze)
  for x in range(1, m-1):
    for y in range(1, n-1):
      maze[x][y] = maze[x][y] if maze[x][y] != 2 else 0 # 將標(biāo)記的 2 還原為 0

  for x in range(m):
    for i in range(1, 2 * n - 1, 2):
      maze[x].insert(i, '  ') # 重初始化 maze,在每?jī)蓚€(gè)元素間插入占位符 '  ' 3 個(gè)空格

  for x in range(1, 2 * m - 1, 2):
    maze.insert(x, [' ', '  '] * (n-1) + ['']) # 插入兩種空格占位符 ' ' 和 '  '

  for direction in directions_map:
    for directions_position in directions_map[direction]:
      i, j = directions_position
      i = 2 * i
      j = 2 * j
      if direction == "↑":
        maze[i - 1][j] = "↑"
      if direction == "↓":
        maze[i + 1][j] = "↓"
      if direction == "←":
        maze[i][j] = " ← "
      if direction == "→":
        maze[i][j + 1] = " → "
  return maze

生成的帶路徑數(shù)據(jù)的迷宮矩陣部分?jǐn)?shù)據(jù)截圖如下:

帶路徑數(shù)據(jù)的矩陣

美化打印迷宮矩陣

def print_maze(maze, text='原始迷宮為:', end1='  ', end2='\n\n', xs=0, xe=0, ys=0, ye=0):
  """
  輸出迷宮矩陣,非必要,可注釋刪除
  :param maze: 一個(gè) m*n 大小的二維矩陣迷宮
  :param text: 輸出提示
  :param end1: 控制每行尾結(jié)束符
  :param end2: 控制每行尾結(jié)束符
  :param xs: 控制是否輸出最上方的 1 環(huán),0 為輸出,1 為不輸出
  :param xe: 控制是否輸出最上方的 1 環(huán),0 為輸出,1 為不輸出
  :param ys: 控制是否輸出最上方的 1 環(huán),0 為輸出,1 為不輸出
  :param ye: 控制是否輸出最上方的 1 環(huán),0 為輸出,1 為不輸出
  """
  print(text)
  n, m = len(maze[0]), len(maze)
  for x in range(xs, m-xe):
    for y in range(ys, n-ye):
      print(maze[x][y], end=end1)
    print(end=end2)

最終輸出結(jié)果:

美化打印

效果尚可

完整代碼

# -*- coding: utf-8 -*-
"""
Created on 2020/1/11 10:51
Author : zxt
File  : maze_recursion.py
Software: PyCharm
"""


from random import randint


def mark(maze, pos):
  """
  標(biāo)記函數(shù),用來(lái)標(biāo)記歷史走過(guò)的位置
  :param maze: 一個(gè) m*n 大小的二維矩陣迷宮
  :param pos: 當(dāng)前需要標(biāo)記的位置坐標(biāo) pos = (x, y),x = pos[0], y = pos[1]
  """
  maze[pos[0]][pos[1]] = 2 # 將走過(guò)的位置標(biāo)記為 2


def move(maze, pos):
  """
  移動(dòng)函數(shù),用來(lái)測(cè)試當(dāng)前位置是否可繼續(xù)移動(dòng),移動(dòng)條件為當(dāng)前位置為 0
  :param maze: 一個(gè) m*n 大小的二維矩陣迷宮
  :param pos: 當(dāng)前需要標(biāo)記的位置坐標(biāo) pos = (x, y),x = pos[0], y = pos[1]
  :return: bool 類(lèi)型
  """
  return maze[pos[0]][pos[1]] == 0


move_path = [] # 記錄能成功到達(dá)出口的移動(dòng)路徑坐標(biāo)
path_direction = [] # 記錄能成功到達(dá)出口的移動(dòng)路徑方向


def find_path(maze, start, end):
  """
  路徑查找函數(shù)
  :param maze: 一個(gè) m*n 大小的二維矩陣迷宮
  :param start: 起始點(diǎn)位置坐標(biāo),start = (1, 1)
  :param end: 終點(diǎn)坐標(biāo),end = (m, n)
  :return: bool 類(lèi)型
  """
  mark(maze, start) # 將起始位置標(biāo)記
  if start == end: # 路徑查找(遞歸)終止條件為到達(dá)終點(diǎn)
    move_path.append(start)
    return True

  # 未到達(dá)終點(diǎn)時(shí),存在 4 種可能的移動(dòng)方向,即上 (-1, 0),下 (1, 0),左 (0, -1),右 (0, 1)
  move_direction = [
    (-1, 0), (1, 0), (0, -1), (0, 1)
  ]
  direction = ['↑', '↓', '←', '→']
  for i in range(4): # 遍歷 4 種可能的方向
    next_start = (start[0] + move_direction[i][0], start[1] + move_direction[i][1]) # 下一個(gè)可能的起始點(diǎn)坐標(biāo)
    if move(maze, next_start): # 找出存在 0 即可移動(dòng)的下一個(gè)起始點(diǎn)坐標(biāo),進(jìn)入遞歸
      if find_path(maze, next_start, end):
        # 這里之所以仍然添加起始點(diǎn)坐標(biāo)是因?yàn)楫?dāng)查詢(xún)到下一個(gè)位置就是終點(diǎn)或者可到達(dá)終點(diǎn)時(shí)記錄此時(shí)位置
        move_path.append(start)
        path_direction.append(direction[i]) # 記錄路徑方向
        return True
  return False # 遍歷遞歸了 4 種可能方向后仍不能到達(dá)終點(diǎn)則說(shuō)明無(wú)法走出迷宮


def gen_maze(m, n):
  """
  生成隨機(jī)迷宮陣列
  :param m: int 類(lèi)型
  :param n: int 類(lèi)型
  :return: maze
  """
  m += 2
  n += 2 # m 和 n 均 +2 是為了構(gòu)造最外層的 1
  maze = [[1 for i in range(n)] for j in range(m)] # 初始化大小為 m * n,值全為 1 的二維矩陣
  for x in range(1, m-1):
    for y in range(1, n-1):
      """
      這里 x, y 取值范圍為 x ∈ [1, m-1),y ∈ [1, n-1) 是因?yàn)槲覀兞畲嗣詫m的最外層(四周)均為 1,如:
      考察 3 * 3 矩陣,一種可能的陣列為:
      [
       _ |←--- n:y ---→|
       ↑ [1, 1, 1, 1, 1],
       | [1, 0, 1, 0, 1],
      m:x [1, 0, 0, 1, 1],
       | [1, 1, 0, 0, 1],
       ↓ [1, 1, 1, 1, 1] 
      ]
      """
      if (x == 1 and y == 1) or (x == m - 2 and y == n - 2):
        maze[x][y] = 0 # 起始點(diǎn)和終點(diǎn)必為 0
      else:
        maze[x][y] = randint(0, 1) # 在最外層均為 1 的情況下內(nèi)部隨機(jī)取 0,1
  return maze


def print_maze(maze, text='原始迷宮為:', end1='  ', end2='\n\n', xs=0, xe=0, ys=0, ye=0):
  """
  輸出迷宮矩陣,非必要,可注釋刪除
  :param maze: 一個(gè) m*n 大小的二維矩陣迷宮
  :param text: 輸出提示
  :param end1: 控制每行尾結(jié)束符
  :param end2: 控制每行尾結(jié)束符
  :param xs: 控制是否輸出最上方的 1 環(huán),0 為輸出,1 為不輸出
  :param xe: 控制是否輸出最上方的 1 環(huán),0 為輸出,1 為不輸出
  :param ys: 控制是否輸出最上方的 1 環(huán),0 為輸出,1 為不輸出
  :param ye: 控制是否輸出最上方的 1 環(huán),0 為輸出,1 為不輸出
  """
  print(text)
  n, m = len(maze[0]), len(maze)
  for x in range(xs, m-xe):
    for y in range(ys, n-ye):
      print(maze[x][y], end=end1)
    print(end=end2)


def path_maze(maze, directions_map):
  """
  生成帶有移動(dòng)路徑的迷宮矩陣
  :param maze: 一個(gè) m*n 大小的二維矩陣迷宮
  :param directions_map: 一個(gè)記錄移動(dòng)方向坐標(biāo)的字典,有 ↑,↓,←,→ 4 個(gè)元素
  :return: path_maze
  """
  n, m = len(maze[0]), len(maze)
  for x in range(1, m-1):
    for y in range(1, n-1):
      maze[x][y] = maze[x][y] if maze[x][y] != 2 else 0 # 將標(biāo)記的 2 還原為 0

  for x in range(m):
    for i in range(1, 2 * n - 1, 2):
      maze[x].insert(i, '  ') # 重初始化 maze,在每?jī)蓚€(gè)元素間插入占位符 '  ' 3 個(gè)空格

  for x in range(1, 2 * m - 1, 2):
    maze.insert(x, [' ', '  '] * (n-1) + ['']) # 插入兩種空格占位符 ' ' 和 '  '

  for direction in directions_map:
    for directions_position in directions_map[direction]:
      i, j = directions_position
      i = 2 * i
      j = 2 * j
      if direction == "↑":
        maze[i - 1][j] = "↑"
      if direction == "↓":
        maze[i + 1][j] = "↓"
      if direction == "←":
        maze[i][j] = " ← "
      if direction == "→":
        maze[i][j + 1] = " → "
  return maze


def main():
  # maze = gen_maze(m=10, n=12)
  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]
    ] # 輸入樣式矩陣,這里最外層用 1 環(huán)包圍住,目的是方便后續(xù)的處理,可以用 gen_maze() 函數(shù)自生成
  print_maze(maze)
  if find_path(maze, start=(1, 1), end=(10, 12)):
    mp = move_path[::-1]
    pd = path_direction[::-1]
    # 這里 pos[0] 和 pos[1] 都要 -1 是因?yàn)樵瓉?lái)的遞歸計(jì)算中存在最外層的 1 環(huán)
    print('坐標(biāo)移動(dòng)順序?yàn)?', [(pos[0]-1, pos[1]-1) for pos in mp])
    path_direction_map = {
      '↑': [],
      '↓': [],
      '←': [],
      '→': []
    } # 路徑方向的映射表
    for i in range(len(pd)):
      path_direction_map[pd[i]].append(mp[i])
    maze = path_maze(maze, path_direction_map)
    print_maze(maze, text='迷宮移動(dòng)路徑為:', end1='', end2='\n', xs=1, xe=1, ys=1, ye=1)
  else:
    print('此迷宮無(wú)解')


if __name__ == '__main__':
  main()

 以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • Python星號(hào)*與**用法分析

    Python星號(hào)*與**用法分析

    這篇文章主要介紹了Python星號(hào)*與**用法,結(jié)合實(shí)例形式較為詳細(xì)的分析了Python中的星號(hào)*與**在函數(shù)參數(shù)及數(shù)值運(yùn)算中的相關(guān)使用技巧,需要的朋友可以參考下
    2018-02-02
  • python實(shí)現(xiàn)linux下使用xcopy的方法

    python實(shí)現(xiàn)linux下使用xcopy的方法

    這篇文章主要介紹了python實(shí)現(xiàn)linux下使用xcopy的方法,可實(shí)現(xiàn)模仿windows下的xcopy命令功能,需要的朋友可以參考下
    2015-06-06
  • python文件和目錄操作方法大全(含實(shí)例)

    python文件和目錄操作方法大全(含實(shí)例)

    這篇文章主要介紹了python文件和目錄的操作方法,簡(jiǎn)明總結(jié)了文件和目錄操作中常用的模塊、方法,并列舉了一個(gè)綜合實(shí)例,需要的朋友可以參考下
    2014-03-03
  • python爬取全國(guó)水雨情信息詳解

    python爬取全國(guó)水雨情信息詳解

    這篇文章主要為大家詳細(xì)介紹了python爬取全國(guó)水雨情信息,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-10-10
  • PyQt5實(shí)現(xiàn)拖放功能

    PyQt5實(shí)現(xiàn)拖放功能

    這篇文章主要為大家詳細(xì)介紹了PyQt5實(shí)現(xiàn)拖放功能,拖放一個(gè)按鈕的實(shí)現(xiàn)方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-04-04
  • 對(duì)PyQt5的輸入對(duì)話框使用(QInputDialog)詳解

    對(duì)PyQt5的輸入對(duì)話框使用(QInputDialog)詳解

    今天小編就為大家分享一篇對(duì)PyQt5的輸入對(duì)話框使用(QInputDialog)詳解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2019-06-06
  • Python實(shí)現(xiàn)數(shù)據(jù)結(jié)構(gòu)線性鏈表(單鏈表)算法示例

    Python實(shí)現(xiàn)數(shù)據(jù)結(jié)構(gòu)線性鏈表(單鏈表)算法示例

    這篇文章主要介紹了Python實(shí)現(xiàn)數(shù)據(jù)結(jié)構(gòu)線性鏈表(單鏈表)算法,結(jié)合實(shí)例形式分析了Python單鏈表的定義、節(jié)點(diǎn)插入、刪除、打印等相關(guān)操作技巧,需要的朋友可以參考下
    2019-05-05
  • Linux安裝Pytorch1.8GPU(CUDA11.1)的實(shí)現(xiàn)

    Linux安裝Pytorch1.8GPU(CUDA11.1)的實(shí)現(xiàn)

    這篇文章主要介紹了Linux安裝Pytorch1.8GPU(CUDA11.1)的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2021-03-03
  • Python實(shí)現(xiàn)登陸文件驗(yàn)證方法

    Python實(shí)現(xiàn)登陸文件驗(yàn)證方法

    本篇文章中我們給大家分享了關(guān)于Python實(shí)現(xiàn)登陸文件驗(yàn)證的方法和技巧,有興趣的朋友們參考學(xué)習(xí)下。
    2018-10-10
  • Python編程之序列操作實(shí)例詳解

    Python編程之序列操作實(shí)例詳解

    這篇文章主要介紹了Python編程之序列操作,結(jié)合實(shí)例形式分析了Python序列的功能、相關(guān)函數(shù)與具體使用技巧,需要的朋友可以參考下
    2017-07-07

最新評(píng)論

桂平市| 依安县| 周口市| 波密县| 德化县| 河池市| 永善县| 分宜县| 博爱县| 平潭县| 色达县| 兴山县| 普定县| 高唐县| 宝鸡市| 修水县| 资源县| 洞口县| 泗水县| 乐昌市| 安福县| 汝城县| 本溪市| 宜阳县| 松滋市| 托克托县| 孝义市| 卓尼县| 惠安县| 读书| 会同县| 张家港市| 丘北县| 威海市| 金塔县| 得荣县| 正阳县| 尉犁县| 西充县| 新兴县| 盐津县|