Algorithm 递归计算支配树的有效方法?

Algorithm 递归计算支配树的有效方法?,algorithm,graph-theory,compiler-theory,Algorithm,Graph Theory,Compiler Theory,我正在使用Lengauer和Tarjan算法以及路径压缩来计算一个有数百万个节点的图的支配树。算法相当复杂,我不得不承认我没有花时间完全理解它,我只是在使用它。现在我需要计算根节点的直接子节点的支配树,并可能在重复此操作的情况下,将图形向下递归到某个深度。也就是说,当我为根节点的子节点计算支配树时,我想假装根节点已从图中移除 我的问题是,是否有一种有效的解决方案,可以利用根节点的初始支配器树中已经计算出的直接支配器信息?换句话说,我不想为每个孩子从头开始,因为整个过程相当耗时 天真地说,这似乎是

我正在使用Lengauer和Tarjan算法以及路径压缩来计算一个有数百万个节点的图的支配树。算法相当复杂,我不得不承认我没有花时间完全理解它,我只是在使用它。现在我需要计算根节点的直接子节点的支配树,并可能在重复此操作的情况下,将图形向下递归到某个深度。也就是说,当我为根节点的子节点计算支配树时,我想假装根节点已从图中移除

我的问题是,是否有一种有效的解决方案,可以利用根节点的初始支配器树中已经计算出的直接支配器信息?换句话说,我不想为每个孩子从头开始,因为整个过程相当耗时

天真地说,这似乎是可能的,因为在图的深处将有大量的节点,这些节点的IDOM就在它们上面一点点,并且不受图顶部的更改的影响

顺便说一句:奇怪的是,支配树的主题是由编译人员“拥有”的,而在经典图论的书籍中却没有提及。我使用它的应用程序——我的FindRoots java堆分析器——与编译器理论无关


澄清:我在这里谈论的是有向图。我提到的“根”实际上是具有最大可达性的节点。我已经更新了上面的文本,将对“树”的引用替换为“图”。我倾向于认为它们是树,因为形状主要是树一样的。该图实际上是java堆中对象的一部分,正如您所想象的,它具有合理的层次结构。我发现支配树在进行OOM泄漏分析时非常有用,因为您感兴趣的是“是什么让这个对象保持活力?”最终答案是它的支配树。主控树让你看到的是树林而不是树木。但有时会有很多垃圾漂浮在树顶上,这样你就有了一个根,它的正下方有数千个孩子。对于这种情况,我想尝试计算根的每个直接子级(在原始图中)的支配树,然后可能进入下一级,以此类推。(我暂时不担心反向链接的可能性:)

从评论的缺乏来看,我想Stackoverflow上没有多少人有相关的经验来帮助你。我是这些人中的一员,但我不想让这样一个有趣的问题伴随着一声沉闷的重击,所以我会试着伸出援手

我的第一个想法是,如果这个图是由其他编译器生成的,那么有必要看看开源编译器,比如GCC,看看它是如何解决这个问题的吗

我的第二个想法是,您的问题的要点似乎是避免重新计算树的根的结果

我要做的是在每个节点周围创建一个包装器,其中包含节点本身以及与该节点关联的任何预计算数据。然后,将使用这些包装器类从旧树递归地重构新树。在构建这棵树的过程中,您将从根开始,然后逐步扩展到叶节点。对于每个节点,您将存储到目前为止所有节点的计算结果。这样,您只需查看父节点和正在处理的当前节点数据即可计算新节点的值


我希望这有帮助

你能详细说明一下你从什么样的图表开始吗?我看不出一个作为树的图和该图的支配树之间有什么区别。每个节点的父节点都应该是它的idom,它当然会被树中它上面的所有内容所支配。

可能会有所帮助。

我不完全理解您的问题,但在我看来,您需要一些增量更新功能。我不久前研究了什么是它们的算法,但在我看来,没有已知的方法可以让大型图快速完成这项工作(至少从理论角度来看)

您可以搜索“增量更新支配树”来查找一些引用


我想您应该知道它确实使用支配树,所以这个主题不再完全属于编译器社区:)

谢谢Simon。不幸的是,该算法极其复杂(至少在我看来),而且没有做任何简单的事情,比如递归地从树上往下走。它遵循祖先的锁链。看一下这个,只是想了解一下:。是的,那可能会有帮助,谢谢。我担心算法的另一部分,虽然它通常需要与dfs相同的时间顺序,但有时更糟(这就是为什么您肯定需要路径压缩)。