从混合图中提取链组件

时间:2013-01-25 08:18:17

标签: algorithm graph

鉴于混合非循环图由有向和无向边组成,我想将此图分解为链组件的有向图(链组件中的每个节点将仅与无向边连接)及其排序。

我很困惑我是否应该首先拓扑排序所有有向边,然后将无向边作为链组件捕获,或者首先应该遍历所有无向边并给它们组ID,然后找到一些有向边连接这些组件。

由于图表是非循环的,我认为可以从低编号组件到高编号组件进行排序,但无法得出可靠答案。

3 个答案:

答案 0 :(得分:1)

定义链组件的等价关系如下由Drton 2009: 定义链图 G 中的两个顶点 v_0v_k 等价,如果存在路径 (v_0,..., v_k) 使得 G 中的 v_i − v_{i+1} 对于所有 0 ≤ i ≤ k − 1 .

这个等价关系下的等价类是 G 的链分量。粗略地说,这意味着由链图的无向边构成的图的所有连通分量,加上所有只与有向边相交的节点,加上所有根本没有邻居的节点,相当于 Peter's answer

这是正确分解 Cowell 2005,Probabilistic Networks and ..., p. 中给出的链图 CH-Asia 的函数。 110 图 6.1。 它是我作为业余爱好项目开发的 graphical models library 的一部分。

虽然它使用自定义数据结构,但适应其他涉及图形模型的代码库应该不会太难。

def get_chain_components(self) -> Set[Set[Node]]:
    """!
    """
    # filter out undirected edges
    edges = set()
    for e in self.edges():
        if e.type() == EdgeType.UNDIRECTED:
            edges.add(e)

    # make a graph from undirected edges
    undi = UndiGraph.from_graph(Graph.from_edge_node_set(edges, self.nodes()))
    return undi.get_components_as_node_set()

答案 1 :(得分:0)

我认为你的两种方法都可以正常工作。

在我看来,第二种方法似乎更自然。

如果我在networkx中这样做,我会通过以下方式实现你的第二种方法:

  1. 创建一个仅包含无向边的新图H.

  2. 在H上调用connected_components以提取链组件并为每个组件分配不同的组ID。

  3. 为每个组ID创建一个包含1个节点的新图表F.根据原始图中的有向边,将F中的组与有向边连接。

  4. 在F上调用topological_sort以计算组ID的顺序。

答案 2 :(得分:0)

您描述的混合图也是有向图。只需用指向相反方向的两个定向边缘替换每个无向边缘即可。

此外,您不能拥有具有无向边的非循环图。至少有一个长度为2的循环,所以我不确定你的意思是什么。

您似乎在寻找此图中强关联的组件,因此我建议您使用Tarjan's algorith来查找它们。