从起始节点查找DAG中的所有路径

时间:2019-01-30 13:20:54

标签: python networkx

我正在尝试从所选节点中查找DAG中的所有路径。

所以我正在随机生成看起来像这样的元组列表:

glavnaLista = [(6, 7), (6, 15), (15, 16), (16, 21), (15, 9), (9, 13), (13, 4), (4, 1), (1, 5)]

从此列表中,我们可以看到节点“ 6”是图的起点

现在我正在创建图形:

G = nx.DiGraph() 
    G.add_edges_from(glavnaLista)

So it looks like this picture

现在我正在尝试使用代码从起始节点查找所有路径(已完成):

def find_all_paths(graph, start, path=[]):

    path = path + [start]
    if start not in graph:
        return [path]
    paths = [path]
    for node in graph[start]:
        if node not in path:
            newpaths = find_all_paths(graph, node, path)
            for newpath in newpaths:
                print (newpath)
                paths.append(newpath)        
    return paths

结果是所有路径的列表:

[[6], [6, 7], [6, 15], [6, 15, 16], [6, 15, 16, 21], [6, 15, 9], [6, 15, 9, 13], [6, 15, 9, 13, 4], [6, 15, 9, 13, 4, 1], [6, 15, 9, 13, 4, 1, 5]]

但是我的问题是我不需要不完整的路径(不去终点),我的列表应该只有完整的路径:

[6, 7]
[6, 15, 9, 13, 4, 1, 5]
[6, 15, 16, 21]

我的想法是检查节点是否同时具有两个邻居,是否不添加列表路径,但我不确定如何实现此功能,因为我对python还是很陌生。

2 个答案:

答案 0 :(得分:1)

您要尝试创建的实际上是通过BFSDFS遍历DAG而创建的树。您可以通过稍微更改代码来做到这一点。

首先请注意,您有一些不必要的代码部分:

def find_all_paths(graph, start, path=[]):
    path = path + [start]
    paths = [path]
    for node in graph[start]:
        newpaths = find_all_paths(graph, node, path)
        for newpath in newpaths:
            print (newpath)
            paths.append(newpath)        
    return paths

由于我们假设这是一个DAG,所以我们可以摆脱一些条件...

现在,我们要生成DFS遍历的路径。此处的打印将在每次迭代后打印路径,但是我们想在结束时打印路径。
因此,我们将添加一个简单的if语句来检查这是否是路径的结尾,如果是,我们将打印路径:

def find_all_paths(graph, start, path=[]):
    path = path + [start]
    paths = [path]
    if len(graph[start]) == 0:  # No neighbors
        print(path)
    for node in graph[start]:
        newpaths = find_all_paths(graph, node, path)
        for newpath in newpaths:
            paths.append(newpath)
    return paths

结果:

[6, 7]
[6, 15, 16, 21]
[6, 15, 9, 13, 4, 1, 5]

答案 1 :(得分:0)

您可以编写一个简单的递归函数,该函数利用DFS +回溯来完成工作(如果是DAG):

def find_all_paths(graph, start):
    if not graph[u]:
        return [[u]]
    paths = []
    for v in graph[u]:
        for v_path in find_all_paths(graph, v):
            paths.append([u] + v_path)
    return paths