4

我对直接无环图 (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 次循环尝试)

那么这种方法是新的还是众所周知的,但只是没有在维基百科和其他资源中广泛呈现?既然它不是一个排序(技术上),它应该被称为数据重组吗?

4

3 回答 3

1

考虑一个由两条“平行”有向路径组成的 DAG,n它们共享起始节点和最后一个节点。这里的层编号比拓扑顺序更严格。在拓扑顺序中,您可以将路径 A 的倒数第二个节点放在路径 B 的第二个节点之前,即使其层数更大。

于 2012-04-14T11:50:49.303 回答
1

可能有人之前已经想到了这一点,但由于它的最坏情况是线性的,我很难将你指向一篇描述它的研究文章。该算法解决的问题的名称是“增量拓扑排序”(或动态,也可以删除边)。

于 2012-04-14T11:39:21.810 回答
1

有一些关于增量维护图中节点的拓扑顺序的论文,以及您描述的算法的变体。

如果图形有n节点和m边,则O(m + n)每次插入边时都会花费时间。k论文问插入边缘需要多少时间?琐碎,O(k * (n + m))。但实际上你可以显示更好的上限——比如O(k * sqrt(m + n))for large enough k

下面的一些链接,还有更多:

http://igitur-archive.library.uu.nl/math/2007-0725-201647/2005-011.pdf

http://arxiv.org/abs/0802.1059

http://www.siam.org/proceedings/soda/2009/SODA09_120_benderm.pdf

于 2012-04-14T15:55:40.980 回答