我对直接无环图 (DAG) 很感兴趣,在阅读了 Wikipedia 上的拓扑排序后,我没有发现任何特别提到涉及层编号的方法(尽管在绘图中广泛提到了层)。使用这种方法,图形在技术上不是拓扑排序的,但是知道每个节点都包含正确的层(级别)编号,我们总是可以判断一个特定节点是否比另一个节点“更大”。另一方面,只要我们没有有序列表,我们就无法在拓扑上枚举节点(尽管这可以通过比较节点级别的最终常规排序来完成)。
这种方法允许实现任意连接,同时保持关卡信息的正确性。步骤可以是:
- 对于任何新添加的节点(没有任何连接),应用的级别为 1。
- 如果请求两个节点之间的连接(从 m 到 n)并且 n.level > m.level 那么它们只是简单地连接,不需要对其他节点进行级别修复。
- 如果对于请求的连接(从 m 到 n)n.level<=m.level,那么我们将 n.level 更改为 (m.level + 1) 并递归检查 n 的任何依赖关系是否有类似的级别增加(或者如果级别不增加,则不增加在递归步骤上是兼容的)。
- 如果我们保留递归输入节点的列表,那么我们可以检测到尝试循环并执行某种撤消操作(将所有受影响节点的级别返回到以前的值)
对于任何一组已知节点和它们之间的连接,我们只需将所有应用 level=1 的节点添加到它们,并尝试应用它们之间的所有已知连接(忽略和撤消 cicles)。
最终级别信息不仅允许在拓扑上比较节点,而且还包含其他有用的信息。例如:
- 每个 level = 1 的节点都没有传入连接(每条路径都从其中一个开始)。所以任何 DAG 枚举都可以从它们开始。
- 最长路径(边数)不能长于(最大层级+1)
我想对于一些人工数据(n 个节点,每个节点(n)连接到节点(n + 1)),这个算法可能非常慢。但是对于我尝试使用的真实数据(维基百科类别 - 800,000 个节点 - 2,000,000 个连接),时间很合适(5-10 分钟),关卡和循环尝试的数量很低(369 个关卡,1000 次循环尝试)
那么这种方法是新的还是众所周知的,但只是没有在维基百科和其他资源中广泛呈现?既然它不是一个排序(技术上),它应该被称为数据重组吗?