Python网络:如何检查两个节点之间是否只存在一条简单路径?

时间:2015-05-13 11:38:01

标签: python networkx

我正在使用networkx.all_simple_paths(G,source,dest)找出两个节点之间的所有可能路径。我返回多个列表。

这是我的代码段:

for path in (nx.all_simple_paths(G,source=node1,target=node2):
         print path 

这为我提供了存储路径的多个列表。 我需要找出给定节点对之间是否只有一条路径。

我该怎么做?

感谢。

5 个答案:

答案 0 :(得分:2)

不是绝对最干净的,但这是一个查看迭代器的函数。如果没有第一个元素,则返回False。如果存在第一个元素(即,存在路径),但没有第二个元素,则返回True。如果存在第二个(即,存在多个路径),则返回False。它永远不会检查是否还有。

def simple_path(G,source,target):
    iterator = nx.all_simple_paths(G,source=source,target=target)
    try:
        first_path = next(iterator)
    except StopIteration:
        return False
    try:
        second_path = next(iterator)
    except StopIteration:
        return True
    return False

样品运行:

In [3]: G= nx.Graph()

In [4]: G.add_edges_from([(1,2),(1,3),(2,3),(3,4)])

In [5]: simple_path(G,1,2)
Out[5]: False

In [6]: simple_path(G,1,3)
Out[6]: False

In [7]: simple_path(G,3,4)
Out[7]: True

In [8]: simple_path(G,1,4)
Out[8]: False

答案 1 :(得分:1)

您可以使用zip将前两个潜在路径匹配在一起(列表内容不重要,这就是我放_的原因)。结果对象的长度是找到的路径数:

paths = nx.all_simple_paths(G,source=node1,target=node2))
# True, if there was exactly one path, calculates at most 2 paths
is_unique_path = len(zip([_, _], paths)) == 1

答案 2 :(得分:1)

如果您想知道此图g1的节点0和1之间是否存在单个路径,例如:

enter image description here

len([path for path in nx.all_simple_paths(g1, source=0, target=1)]) == 1  # True

如果存在特定数量的路径,您可以对此进行扩展以检查所有节点,并为该特定节点对返回True / False列表。

import itertools
def number_paths(graph, number):
    # list of all possible pairs. NOTE: there may not be an edge between some pairs
    node_pairs = list(itertools.combinations(graph.nodes(), 2))
    num_path = []
    for pair in node_pairs:
        num_path.append( 
            len([path for path in nx.all_simple_paths(graph, source=pair[0], target=pair[1])]) == number )
    return num_path, node_pairs

因此,对于上图,您可以这样做:

print number_paths(g1, 1)  # prints: ([True], [(0, 1)])

更好的示例是此图g2

enter image description here

节点对之间是否只存在一条路径?

check, nodes = number_paths(g2, 1)
print 'check:', check  # check: [True, False, False, False, False, False]
print 'nodes:', nodes  # nodes: [(0, 1), (0, 2), (0, 3), (1, 2), (1, 3), (2, 3)]

节点对之间是否只存在2条路径?

check, nodes = number_paths(g2, 2)
print 'check:', check  # check: [False, True, True, True, True, True]
print 'nodes:', nodes  # nodes: [(0, 1), (0, 2), (0, 3), (1, 2), (1, 3), (2, 3)]

答案 3 :(得分:1)

受Joel的回答启发,避免生成两个以上的路径并通过异常捕获进行分支:

import itertools

def simple_path(G,source,target):
    iterator = nx.all_simple_paths(G,source=source,target=target)
    return sum(1 for _ in itertools.islice(iterator, 2)) == 1

它尝试从发生器计算最多2个元素。 它应返回False是否有零或两个元素,如果只有一个元素,则返回True

答案 4 :(得分:0)

您可以将nextdefault参数一起使用:

def has_one_path(G, source, target):
    paths = nx.all_simple_paths(G, source, target)
    return next(paths, None) is not None and next(paths, None) is None

我认为它非常具有可读性和效率:如果有下一个路径,图表有一条从源到目标的路径,之后没有下一条路径。