【问题标题】:Creating a graph from a string从字符串创建图表
【发布时间】:2021-02-04 17:14:05
【问题描述】:

让我们考虑一个由字符串定义的“迷宫”,例如

'''
################
#******#########
#*####*********#
##############*#
#*****#*#***##F#
#*###*###*#****#
#S###*****######
################
''' 

符号“#”表示墙,符号“*”表示可能的路径。而且“S”是起点,“F”是终点。

我想应用路径搜索算法来解决这个迷宫,例如广度优先搜索。我读过该算法使用图表来找到正确的路径。我的问题来了。

我想根据我的路径创建一个图表。我认为它应该看起来像这样:

graph = {
    0: [],
    ...
    17: [18],
    18: [17, 19],
    ...
}

因为第一个节点是一堵墙,所以它没有链接到任何路径,第十七个节点是一条路径,它链接到他的邻居等等。

我的第一个想法是实现几个功能,迷宫的中心和侧面的不同。

例如,我想检查图表内的所有节点i(我指的是不在两侧的节点)我会检查它们是否链接到i-n_1, i-n_2, i-n_3, i-n_4,因为我们只能去楼下,楼上,左右。 n_j 取决于迷宫的大小。

但是我发现这个想法完全无效且丑陋。如果有任何其他想法或提示,我将不胜感激。

【问题讨论】:

    标签: python algorithm


    【解决方案1】:

    将这样的字符串读入图表并不难。

    第一个函数获取所有非壁单元的坐标,第二个函数找出哪些是相邻的。

    import collections
    
    
    def read_maze_string(maze_string):
        start_coord = None
        end_coord = None
        non_walls = set()
    
        for y, row in enumerate(maze_string.strip().splitlines()):
            for x, c in enumerate(row):
                if c == "#":
                    continue
                non_walls.add((x, y))
                if c == "S":
                    start_coord = (x, y)
                if c == "F":
                    end_coord = (x, y)
        return (non_walls, start_coord, end_coord)
    
    
    def get_graph(non_walls):
        neighbors = collections.defaultdict(set)
        neighbor_deltas = [(-1, 0), (+1, 0), (0, -1), (0, +1)]  # You could also add the diagonal deltas
        for c in non_walls:
            x, y = c
            for dx, dy in neighbor_deltas:
                nc = (x + dx, y + dy)  # neighbor coordinate
                if nc in non_walls:
                    neighbors[c].add(nc)
        return dict(neighbors)
    
    
    non_walls, start_coord, end_coord = read_maze_string(
        """
    ################
    #******#########
    #*####*********#
    ##############*#
    #*****#*#***##F#
    #*###*###*#****#
    #S###*****######
    ################
    """
    )
    graph = get_graph(non_walls)
    print(graph)
    

    输出例如

    
    {(3, 4): {(4, 4), (2, 4)}, (14, 4): {(14, 3), (14, 5)}, (3, 1): {(4, 1), (2, 1)}, (5, 4): {(4, 4), (5, 5)}, (5, 1): {(6, 1), (4, 1)}, (9, 2): {(8, 2), (10, 2)}, (9, 5): {(9, 6), (9, 4)}, (11, 2): {(12, 2), (10, 2)}, (11, 5): {(12, 5), (11, 4)}, (8, 6): {(9, 6), (7, 6)}, (13, 2): {(14, 2), (12, 2)}, (1, 6): {(1, 5)}, (13, 5): {(12, 5), (14, 5)}, (6, 2): {(6, 1), (7, 2)}, (14, 3): {(14, 2), (14, 4)}, (5, 6): {(6, 6), (5, 5)}, (8, 2): {(9, 2), (7, 2)}, (11, 4): {(10, 4), (11, 5)}, (10, 2): {(11, 2), (9, 2)}, (9, 4): {(10, 4), (9, 5)}, (2, 4): {(3, 4), (1, 4)}, (1, 2): {(1, 1)}, (2, 1): {(3, 1), (1, 1)}, (1, 5): {(1, 6), (1, 4)}, (6, 1): {(6, 2), (5, 1)}, (7, 6): {(6, 6), (8, 6)}, (12, 2): {(13, 2), (11, 2)}, (12, 5): {(13, 5), (11, 5)}, (14, 2): {(13, 2), (14, 3)}, (4, 1): {(3, 1), (5, 1)}, (14, 5): {(13, 5), (14, 4)}, (4, 4): {(5, 4), (3, 4)}, (5, 5): {(5, 4), (5, 6)}, (10, 4): {(11, 4), (9, 4)}, (1, 1): {(1, 2), (2, 1)}, (9, 6): {(9, 5), (8, 6)}, (1, 4): {(2, 4), (1, 5)}, (7, 2): {(8, 2), (6, 2)}, (6, 6): {(7, 6), (5, 6)}}
    

    【讨论】:

      猜你喜欢
      • 2016-02-13
      • 2011-04-20
      • 1970-01-01
      • 2016-12-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-08-11
      • 1970-01-01
      相关资源
      最近更新 更多