Python breadth-first search matrix print path

前端 未结 3 1860
深忆病人
深忆病人 2021-01-23 23:16

I have this line of code that tests wether or not there is a path to be found in a labyrinth represented by a matrix. How do I print the path at the end after I\'ve determined w

3条回答
  •  佛祖请我去吃肉
    2021-01-23 23:56

    As a variant to @程名锐's post, this implementation of a DFS will also return the first path it has found. And as a general advice, if you don't care about the path being optimal, a DFS will usually serve you better than a BFS.

    Note that we also have to make sure not to run in circles, since this graph is not a tree.

    # for convenience
    matrix = [
        ["0", "0", "0", "0", "1", "0", "0", "0"],
        ["0", "1", "1", "0", "1", "0", "1", "0"],
        ["0", "1", "0", "0", "1", "0", "1", "0"],
        ["0", "0", "0", "1", "0", "0", "1", "0"],
        ["0", "1", "0", "1", "0", "1", "1", "0"],
        ["0", "0", "1", "1", "0", "1", "0", "0"],
        ["1", "0", "0", "0", "0", "1", "1", "0"],
        ["0", "0", "1", "1", "1", "1", "0", "0"]
    ]
    num_rows = len(matrix)
    num_cols = len(matrix[0])
    
    # just to be a bit more flexible, could also be passed as a function argument
    goal_state = (num_rows - 1, num_cols - 1)
    
    
    def dfs(current_path):
        # anchor
        row, col = current_path[-1]
        if (row, col) == goal_state:
            return True
    
        # try all directions one after the other
        for direction in [(row, col + 1), (row, col - 1), (row + 1, col), (row - 1, col)]:
            new_row, new_col = direction
            if (0 <= new_row < num_rows and 0 <= new_col < num_cols and  # stay in matrix borders
                    matrix[new_row][new_col] == "0" and                  # don't run in walls
                    (new_row, new_col) not in current_path):             # don't run in circles
                # try new direction
                current_path.append((new_row, new_col))
                if dfs(current_path):  # recursive call
                    return True
                else:
                    current_path.pop()  # backtrack
    
    
    # result a list of coordinates which should be taken in order to reach the goal
    result = [(0, 0)]
    if dfs(result):
        print("Success!")
        print(result)
    else:
        print("Failure!")
    

    Prints:

    [(0, 0), (0, 1), (0, 2), (0, 3), (1, 3), (2, 3), (2, 2), (3, 2), (3, 1), (3, 0), (4, 0), (5, 0), (5, 1), (6, 1), (6, 2), (6, 3), (6, 4), (5, 4), (4, 4), (3, 4), (3, 5), (2, 5), (1, 5), (0, 5), (0, 6), (0, 7), (1, 7), (2, 7), (3, 7), (4, 7), (5, 7), (6, 7), (7, 7)]
    

    The first (but for sure not shortest) correct path a DFS with the pathing preferences right -> left -> down -> up encounters.

提交回复
热议问题