【问题标题】:finding all paths from one vertex to another查找从一个顶点到另一个顶点的所有路径
【发布时间】:2019-08-09 10:20:06
【问题描述】:

试图找到从起始顶点到结束顶点的所有可能路径。这就是我目前所拥有的。

def all_paths(adj_list, source, destination):
paths = []
for neighbour,_ in adj_list[source]:
    path = [source,neighbour]
    state = ['U'] * len(adj_list)
    state[neighbour] = 'D'
    path = finder(adj_list, neighbour, state, path, destination)
    paths.append(path)
return paths

def finder(adj_list, current, state, path, end):
    for neighbour,_ in adj_list[current]:
        if neighbour == end:
            path.append(neighbour)
            return path
        if state[neighbour] == 'U':
            state[neighbour] = 'D'
            path.append(finder(adj_list, neighbour, state, path, end))
            return path

状态数组是为了确保没有顶点被访问两次(U未被发现,D被发现。) adj_list 是图的邻接列表,因此在列表的 index[i] 处,它具有通过边连接到 i 的所有顶点的列表(无是所述边的权重)

输入是

adj_list = [[(1, None), (2, None)], [(0, None), (2, None)], [(1, None), (0, None)]]


print(sorted(all_paths(adj_list, 0, 2)))

预期的输出是

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

我的输出是

[[0, 1, 2, [...]], [0, 2, 2, [...], [...]]]

不确定我如何在第二条路径中获得这些点和重复的 2?

【问题讨论】:

  • adjacency_list 是做什么的?
  • 这是一个改进,但我仍然不明白adj_list 是如何表示点的邻接关系的——其中的信息是如何布局的/它的结构意味着什么。
  • ... 表示你的数据结构是自引用的:Python 不能全部打印出来,因为它永远不会停止引用自身的其他部分。我没有研究细节,但是很怀疑您将path 作为参数传递给函数,在该函数中对其进行变异,然后将其返回。这似乎是错误的,它可能是你麻烦的根源——或者至少是其中的一部分。

标签: python recursion path


【解决方案1】:

与您的代码非常相似的逻辑,但经过清理,这是因为 Python 可以检查项目是否在列表中,因此不使用单独的“U”或“D”数组。

ajs =  [[(1, None), (2, None)], [(0, None), (2, None)], [(1, None), (0, None)]]

def paths(node, finish):
    routes = []

    def step(node, path):
        for nb,_ in ajs[node]:

            if nb == finish:
                routes.append( path + [node, nb] )

            elif nb not in path:
                step(nb, path + [node])

    step(node, [])
    return routes

print paths(0,2)

【讨论】:

  • 啊,是的,我知道我哪里出错了,非常感谢你让我免于头痛!
【解决方案2】:

这是您的代码的变体,可以得到所需的答案。也就是说,这是解决问题的一种令人困惑的方式。在我看来,该算法正在跨两个函数传播,而它应该可以用一个递归函数来解决。

def main():
    adj_list = [
        [(1, None), (2, None)],
        [(0, None), (2, None)],
        [(1, None), (0, None)],
    ]
    paths = sorted(all_paths(adj_list, 0, 2))
    print(paths)

def all_paths(adj_list, source, destination):
    paths = []
    for neighbour, _ in adj_list[source]:
        pth = [source, neighbour]
        if neighbour == destination:
            paths.append(pth)
        else:
            node = finder(
                adj_list,
                neighbour,
                ['U'] * len(adj_list),
                pth,
                destination,
            )
            paths.append(pth + [node])
    return paths

def finder(adj_list, current, state, pth, end):
    for neighbour, _ in adj_list[current]:
        if neighbour == end:
            state[neighbour] = 'D'
            return neighbour
        elif state[neighbour] == 'U':
            state[neighbour] = 'D'
            return finder(adj_list, neighbour, state, pth, end)

main()

例如,这里有一个替代实现:

def main():
    # An adjacency matrix for this example:
    #
    #    0 - 1
    #     \ /
    #      2
    #
    matrix = [
        [(1, None), (2, None)],
        [(0, None), (2, None)],
        [(1, None), (0, None)],
    ]
    # Print all paths from 0 to 2.
    paths = get_paths(matrix, 0, 2)
    for p in paths:
        print(p)

def get_paths(matrix, src, dst, seen = None):
    # Setup:
    # - Initialize return value: paths.
    # - Get an independent seen set.
    # - Add the source node to the set.
    paths = []
    seen = set(seen or [])
    seen.add(src)
    # Explore all non-seen neighbors.
    for nb, _ in matrix[src]:
        if nb not in seen:
            seen.add(nb)
            # Find the subpaths from NB to DST.
            if nb == dst:
                subpaths = [[nb]]
            else:
                subpaths = get_paths(matrix, nb, dst, seen)
            # Glue [SRC] to the those subpaths and add everything to paths.
            for sp in subpaths:
                paths.append([src] + sp)
    return paths

main()

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-01-11
    • 1970-01-01
    • 1970-01-01
    • 2017-10-26
    • 2019-02-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多