【问题标题】:Checking validity of topological sort检查拓扑排序的有效性
【发布时间】:2019-01-13 23:18:50
【问题描述】:

给定以下有向图:

我确定拓扑排序为0, 1, 2, 3, 7, 6, 5, 4,每个节点的值为:

d[0] = 1
f[0] = 16

d[1] = 2
f[1] = 15

d[2] = 3
f[2] = 14

d[3] = 4
f[3] = 13

d[4] = 7
f[4] = 8

d[5] = 6
f[5] = 9

d[6] = 5
f[6] = 10

d[7] = 11
f[7] = 12

d 是发现时间,f 是完成时间。

如何检查拓扑排序是否有效?

【问题讨论】:

    标签: graph topological-sort


    【解决方案1】:

    使用pythonnetworkx,可以如下检查:

    import networkx as nx
    
    G = nx.DiGraph()
    G.add_edges_from([(0, 2), (1, 2), (2, 3)])
    all_topological_sorts = list(nx.algorithms.dag.all_topological_sorts(G))
    print([0, 1, 2, 3] in all_topological_sorts) # True
    print([2, 3, 1, 0] in all_topological_sorts) # False
    

    但是,请注意,为了具有拓扑排序,图必须是有向无环图 (DAG)。如果 G 不是定向的,则会引发 NetworkXNotImplemented。如果 G 不是非循环的(如您的情况) NetworkXUnfeasible 将被提出。

    请参阅文档here

    【讨论】:

      【解决方案2】:

      如果您希望对这个问题使用更少的编码方法(因为看起来您的原始拓扑排序是在没有代码的情况下生成的),您可以回到拓扑排序的定义。转述自Emory University

      节点的拓扑排序 = 节点/顶点的排序(标签),使得对于 G 中的每条边 (u,v),u 在排序中出现早于 v。

      有两种方法可以解决这个问题:从顶点角度的边缘角度。我在下面描述了一个简单的(意味着有一些额外的空间复杂性和聪明,你可以改进它们)实现。

      边缘方法

      遍历 G 中的边。对于每条边,按顺序检索其每个顶点的索引。比较指标。如果源顶点不早于目标顶点,则返回 false。如果您遍历所有边而不返回 false,则返回 true。

      复杂度:O(E*V)

      顶点法

      遍历排序中的顶点。对于每个顶点,检索其输出边列表。如果这些边中的任何一条以排序中当前顶点之前的顶点结束,则返回 false。如果您遍历所有顶点而不返回 false,则返回 true。

      复杂度:O(V^2*E)

      【讨论】:

        【解决方案3】:

        首先,做一个图遍历,得到每个顶点的入度。然后从列表中的第一个顶点开始。每次看一个顶点时,我们要检查两件事 1)这个顶点的入度是 0 吗? 2)这个顶点是前一个顶点的邻居吗?我们还想减少其所有邻居的传入度,就好像我们切割所有边一样。如果我们在某个时候从前面的问题中得到否定,我们知道这不是一个有效的拓扑顺序。否则,它是。这需要 O(V + E) 时间。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2021-07-28
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多