快速获取边缘穿过networkx.Graph中的两组节点的方法

时间:2016-09-13 14:47:43

标签: python graph-theory networkx

networkx在两个不相交的节点集之间获得交叉边缘的禁区方式是什么? 是否有一些现成的功能可供使用?

我现在使用的方式:

import networkx as nx
from itertools import product
A = set(range(50))
B = set(range(50, 100))
g = nx.complete_graph(100)
cross_edges = [(n1, n2)
  for n1, n2 in product(A, B)
  if n1 in g.adj and n2 in g.adj[n1]]

3 个答案:

答案 0 :(得分:1)

您可以在Networkx中使用edge_boundary功能。

  

相对于集合T的集合S的边缘边界是边(u,v)的集合,使得u在S中,v在T中。

这也称为 cut-set ,一组在每个分区子集中具有一个端点的边。

答案 1 :(得分:0)

这取决于对图表的假设。

如果图形密集,则方法最佳,因为结果边缘集与class MyComponent extends React.Component { constructor() { super() this.state = { name: this.props.name || 'Joseph Flowers' }; } } 几乎相同。比通过迭代所有可能的边缘(product(A,B))并检查它是否是边缘而言。

如果图形稀疏,则迭代现有边缘并检查A和B之间的边缘会更快。例如:

product(A,B)

可能的优化是将A设置为两个输入集中较小的一个。

答案 2 :(得分:0)

这是一个老线程,但这是我正在使用的解决方案。

def edges_cross(graph, nodes1, nodes2):
    """
    Finds edges between two sets of disjoint nodes.
    Running time is O(len(nodes1) * len(nodes2))

    Args:
        graph (nx.Graph): an undirected graph
        nodes1 (set): set of nodes disjoint from nodes2
        nodes2 (set): set of nodes disjoint from nodes1.
    """
    return {(u, v) for u in nodes1
            for v in nodes2.intersection(graph.adj[u])}

如果n=len(nodes1)m=len(nodes2),则此算法将在O(nm)中运行,因为外循环有n次迭代。每个内部循环调用nodes2.intersection将在O(m)时间内运行,只要graph.adj[u]是一个集合(它实际上是一个字典,但这将在其键上运行,就像一个集合一样)。有关设置交叉点运行时间的更多详细信息,请参阅python docs

我还有一个函数用于一组节点内的边缘,这些节点在O(n^2)中通过类似的参数运行,但它也包含一些减少常数因子的技巧。

def edges_inside(graph, nodes):
    """
    Finds edges within a set of nodes
    Running time is O(len(nodes) ** 2)

    Args:
        graph (nx.Graph): an undirected graph
        nodes1 (set): a set of nodes
    """
    result = set([])
    upper = nodes.copy()
    graph_adj = graph.adj
    for u in nodes:
        for v in upper.intersection(graph_adj[u]):
            result.add((u, v))
        upper.remove(u)
    return result