给出以下有向图:
我确定拓扑排序为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
是完成时间。
如何检查拓扑排序是否有效?
答案 0 :(得分:0)
使用python和networkx,您可以按以下方式进行检查:
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)时间。