检查拓扑排序的有效性

时间:2019-01-13 23:18:51

标签: graph topological-sort

给出以下有向图:

enter image description here

我确定拓扑排序为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是完成时间。

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

3 个答案:

答案 0 :(得分:0)

使用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

答案 1 :(得分:0)

如果您希望对该问题使用较少的编码方法(因为看起来原始的拓扑顺序是在没有代码的情况下生成的),则可以返回拓扑排序的定义。改写自Emory University

节点的拓扑顺序=节点/顶点的顺序(标签),以使得对于G中的每个边(u,v),u都比v早出现。

有两种方法可以解决此问题:从顶点角度的边缘角度。我在下面描述了两种方法的幼稚(意味着一些额外的空间复杂性和智能性,您可以对其进行改进)。

优势方法

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

复杂度:O(E * V)

顶点方法

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

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

答案 2 :(得分:0)

首先,进行图遍历以获得每个顶点的传入度。然后从列表中的第一个顶点开始。每次查看顶点时,我们要检查两件事:1)该顶点的传入度是否为0? 2)这个顶点是先前顶点的邻居吗?我们还希望降低其所有邻居的传入程度,就像我们削减所有边缘一样。如果在某些时候我们从前面的问题中得到否,那么我们知道这不是有效的拓扑顺序。否则,是的。这需要O(V + E)时间。