【问题标题】:Converting a DAG to Binary Tree将 DAG 转换为二叉树
【发布时间】:2021-06-07 14:02:59
【问题描述】:

我正在尝试将 DAG 转换为二叉树。考虑下图

我希望上面的树有以下输出。

由于 A,B,C,E 形成菱形,要将其转换为树,我需要将 B 和 C 移动成一条线。

我尝试了以下方法:

  1. 拓扑排序:输出为 A -> D -> B -> C -> E -> F。
  2. 按顺序进行拓扑排序:A -> [B,C,D] -> E -> F

拓扑路径为我们提供了一条笔直的路径。但是,如果可能的话,我想保留序列,即 A -> D。但是,如果有一个菱形,我希望一个节点只有一个父节点并且也对这些父节点进行排序。

对于上述情况,有没有办法从 DAG 生成树?

【问题讨论】:

    标签: algorithm graph networkx gremlin graph-algorithm


    【解决方案1】:

    伪代码算法

     Run a topological sort on the graph
    
     For every node B, in reverse order of the topological sort:
        If B has more than one parent:
            Order its parents A1, A2, ..., An in the order of the topological sort
            For every i in 1..n-1:
                Add an arc from Ai to A(i+1)
                Remove the arc from Ai to B
    

    正确性证明

    • 算法总是终止,因为它是一个固定长度的循环;它的时间复杂度是O(N^2),其中N是节点数
    • 在给定节点 B 上的步骤之后,B 的父节点不超过一个
    • 如果给定节点 C 上的步骤已经执行,则在拓扑顺序中位于 C 之前的节点 B 上执行步骤只会将弧添加到拓扑顺序中位于 C 之前的节点;因此,一旦节点的步骤被执行,它们就永远不会获得新的父节点。

    这证明算法终止,并且每个节点在执行算法后最多有一个父节点。由于我们只从具有多个父节点的节点中删除父节点,我认为它也满足了您的问题。

    【讨论】:

    • 我会尝试使用这个算法并告诉你。
    • 这按预期工作。有没有办法降低O(n^2) 的复杂性。我认为最好的情况是O(n)
    • 复杂度实际上是 O(N+M),其中 N 是顶点数,M 是边数。我在解释中简化为 O(N^2);注意 M = O(N^2),如果图是连通的,那么 N = O(M)。
    猜你喜欢
    • 1970-01-01
    • 2012-02-28
    • 2020-08-24
    • 2015-09-24
    • 1970-01-01
    • 1970-01-01
    • 2011-07-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多