如何从Python中带有门和钥匙的迷宫算法中获取路径?

时间:2018-06-21 23:50:44

标签: python algorithm depth-first-search

我正在尝试先使用DFS的地方学习DFS / BFS。我认为我的代码现在可以解决问题,但是我想获得从头到尾的路径。

问题: 这是迷宫问题,我需要从头到尾地坐标,只能在陆地'.'上旅行。这是网格的表示

'#' = Water
'.' = Land
'a' = Key of type 'a'
'A' = Door that opens with key 'a'
'@' = starting point
'+' = finish point. 

这是网格的示例

['.', '.', '.', 'B']
['.', 'b', '#', '.']
['@', '#', '+', '.']

到目前为止,这是我的代码

def find_shortest_path(grid):
    board = []
    for row in grid:
        column = []
        row = row.replace('\r', '')
        for c in row:
            column.append(c)
        board.append(column)

    ROW = len(board)
    COL = len(board[0])

    start = ()
    stop = ()
    key_set = {}

    # I can collapse this with the first loop
    for row in range(ROW):
        for col in range(COL):
            if board[row][col] == '@':
                start = (row, col)
            if board[row][col] == '+':
                stop = (row, col)
            if board[row][col].isalpha() and board[row][col].islower():
                key = board[row][col]
                key_set[key] = key_set.get(key, 0) + 1

    visited = [[False for _ in range(COL)] for _ in range(ROW)]

    def dfs(i, j):
        if i < 0 or i >= ROW \
                or j < 0 or j >= COL \
                or visited[i][j] \
                or board[i][j] == '#':
            return
        if i == stop[0] and j == stop[1]:
            print('end')
            return

        print('{}, {}'.format(i, j))

        if board[i][j].isalpha() and board[i][j].islower():
            key_set[board[i][j]] -= 1
        if board[i][j].isalpha() and board[i][j].isupper() and key_set[board[i][j].lower()] == 0:
            return
        visited[i][j] = True

        dfs(i - 1, j)
        dfs(i + 1, j)
        dfs(i, j - 1)
        dfs(i, j + 1)

        print('backtrack at {}, {}'.format(i, j))

        visited[i][j] = False

    i, j = start
    dfs(i, j)


if __name__ == '__main__':
    grid = ['...B\r', '.b#.\r', '@#+.\r']
    find_shortest_path(grid)

现在我的问题是我需要返回路径。例如,该算法的结果之一将是

[[2,0], [1,0], [1,1], [0, 1], [0, 2], [0, 3], [1, 3], [2, 3], [2, 2]]

1 个答案:

答案 0 :(得分:0)

如果您向dfs添加一个参数,该参数采用当前正在处理的步骤的编号(递归调用dfs时必须加一),并且您设置了visited (子)数组具有此步骤号(例如0或-1表示“未访问”),而不是布尔值,则可以在找到结尾后,按照visited数组中的编号步骤进行操作。

如果您必须两次跨过相同的位置(例如,钥匙处于死胡同中,并且必须走进去拿回门),这将不起作用。但这不会也可以使用您当前的代码。