我正在使用带路径压缩的Lengauer和Tarjan算法来计算有数百万个节点的图的支配树。算法非常复杂,我不得不承认我没有花时间完全理解它,我只是使用它。现在我需要计算根节点的直接子节点的支配树,并可能将图形向下递减到重复此操作的某个深度。即当我为根节点的子节点计算支配树时,我想假装根节点已从图中删除。
我的问题是,是否有一个有效的解决方案,利用已经在根节点的初始支配树中计算的直接支配者信息?换句话说,我不想从头开始为每个孩子开始,因为整个过程非常耗时。
天真地看起来它一定是可能的,因为图中深处有很多节点,它们只有一点点位于它们之上并且不受图形顶部变化的影响。
顺便说一下:顺便说一句,统治者树的主题是由编译人员“拥有”的,并且在经典图论的书中没有提到它。我正在使用它的应用程序 - 我的FindRoots java堆分析器 - 与编译器理论无关。澄清:我在这里谈论有向图。我所指的“根”实际上是具有最大可达性的节点。我已经更新了上面的文本,用“graph”替换了对“tree”的引用。我倾向于认为它们是树,因为形状主要是树状。该图实际上是java堆中的对象,您可以想象它是合理的层次结构。我发现主导树在进行OOM泄漏分析时很有用,因为你感兴趣的是“是什么让这个物体保持活力?”答案最终是它的统治者。支配树允许你< ahem>看到木头而不是树木。但有时很多垃圾漂浮在树顶,所以你有一个根,上面有成千上万的孩子。对于这种情况,我想尝试计算根植于根的每个直接子节点(在原始图形中)的支配树,然后可以进入下一级别,依此类推。 (我现在不想担心反向链接的可能性:)。
答案 0 :(得分:5)
答案 1 :(得分:2)
由于缺乏评论,我猜Stackoverflow上的人并不多,有相关的经验来帮助你。我是其中一个人,但我不希望这个有趣的问题随着沉闷的砰砰声而下去,所以我会试着伸手。
我的第一个想法是,如果这个图是由其他编译器生成的,那么值得看一下像GCC这样的开源编译器,看看它是如何解决这个问题的?
我的第二个想法是,你问题的主要观点似乎是避免重新计算树根的结果。
我要做的是在每个节点周围创建一个包装器,其中包含节点本身以及与该节点关联的任何预先计算的数据。然后使用这些包装类递归地从旧树重建新树。在构建此树时,您将从根开始,逐步完成叶节点。对于每个节点,您将存储到目前为止所有祖先的计算结果。这样,您只需要查看父节点和您正在处理的当前节点数据,以计算新节点的值。
我希望有所帮助!
答案 2 :(得分:1)
您能否详细说明您从哪种图表开始?我不知道作为树的图和该图的支配树之间有什么区别。每个节点的父节点都应该是它的idom,它当然会被树中的所有节点所支配。
答案 3 :(得分:0)
我不完全理解你的问题,但在我看来你想要一些增量更新功能。我刚才研究过他们的算法是什么,但在我看来,大型图表没有已知的方法可以快速完成这项工作(至少从理论的角度来看)。
您可以只搜索“增量更新支配树”来查找一些参考。
我想你知道the Eclipse Memory Analyzer确实使用了支配树,所以这个主题不再被编译器社区完全“拥有”了:)