代码之家  ›  专栏  ›  技术社区  ›  Dave Griffiths

递归计算主宰树的有效方法?

  •  16
  • Dave Griffiths  · 技术社区  · 17 年前

    我使用带有路径压缩的lengauer和tarjan算法来计算一个有数百万个节点的图的主宰树。算法相当复杂,我不得不承认我没有花时间完全理解它,我只是在使用它。现在,我需要计算根节点的直接子节点的主宰树,并可能在图中递归到一定深度,重复这个操作。也就是说,当我为根节点的子节点计算主宰树时,我想假设根节点已经从图中删除。

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

    天真地说,这似乎是可能的,因为在图的深处有很多节点的IDOM比它们稍高一点,并且不受图的顶部变化的影响。

    顺便说一句:很奇怪,主宰树的主题是由编译人员“拥有”,经典图论书籍中没有提到它。我正在使用的应用程序——我的FixRooJava Java堆分析器——与编译器理论无关。

    澄清:我在这里谈论的是有向图。我所指的“根”实际上是具有最大可达性的节点。我已经更新了上面的文本,用“graph”替换了对“tree”的引用。我倾向于把它们当作树,因为形状是 主要地 树状的图形实际上是Java堆中的对象,正如你可以想象的那样,它是合理的层次结构。在进行OOM泄漏分析时,我发现主宰树很有用,因为您感兴趣的是“什么使这个对象保持活动状态?”最终答案是它的主宰者。主宰者树允许您查看木材而不是树木。但是有时候很多垃圾会浮到树的顶部,这样你就有了一个根,在它的正下方有成千上万的孩子。对于这种情况,我想尝试计算根的每个直接子代(在原始图中)的主宰树,然后再向下一级,依此类推。(我暂时不担心有可能出现反向链接:)

    4 回复  |  直到 16 年前
        1
  •  5
  •   jfs    17 年前
        2
  •  2
  •   Simon Johnson Andomar    17 年前

    从没有评论来看,我想StackOverflow上没有多少人有相关的经验来帮助你。我是那些人中的一员,但我不想让这样一个有趣的问题沉闷地说下去,所以我会尽力帮忙的。

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

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

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

    希望有帮助!

        3
  •  1
  •   Jay Kominek    17 年前

    你能详细描述一下你从什么样的图表开始吗?我看不出一个树图和那个图的主宰树有什么区别。每个节点的父节点都应该是它的IDOM,当然它将被树中它上面的所有内容所控制。

        4
  •  0
  •   kohlerm    16 年前

    我不完全理解您的问题,但在我看来您想要一些增量更新功能。我之前研究过什么算法是它们的,但在我看来,对于大型图来说,没有已知的快速实现这一点的方法(至少从理论角度来看)。

    您可以搜索“增量更新主宰树”来查找一些引用。

    我想你知道 the Eclipse Memory Analyzer 使用了主宰树,因此这个主题不再完全由编译器社区“拥有”)。