计算最少的运算以使两个树结构相同


81

这更多是一个CS问题,但有趣的是:

假设我们有2个树结构,它们或多或少地重组了相同的节点。你怎么会找到

  1. 任何
  2. 在某种意义上说极小

操作顺序

  • MOVE(A, B) -将节点A移动到节点B下(带有整个子树)
  • INSERT(N, B)-在节点B下插入节点N
  • DELETE (A) -删除节点A(带有整个子树)

将一棵树转化为另一棵树。

显然,在某些情况下,这种转换是不可能的,琐碎的是将根A与子B转换为根B与子A等)。在这种情况下,该算法将简单地提供“不可能”的结果。

对于网络而言,更通用的版本是通用的,即当我们假设一个节点可以在树中出现多次(有效地具有多个“父级”)时,则禁止循环。

免责声明:这不是家庭作业,实际上是来自一个实际的业务问题,我想知道是否有人知道解决方案非常有趣。


MOVE(A,B)似乎是一样的INSERT(A,B),如果A没有任何孩子。A如果一个人的孩子INSERT(A,B)怎么办?(将其附加到其A父母
身上

区别在于INSERT表示实际上是一个新节点,以前不在树中(因此没有任何子节点,至少没有处于甚至不存在的原始状态)。另一方面,MOVE实际上是一个移动,即节点及其子节点的移动
Tomas Vana

11
听起来您需要检测图同构。关于变换的部分让我想起了Levenshtein距离,可以使用动态规划在O(n * m)中巧妙地解决它。也许这些指针对您有所帮助。
比约恩博动

您是否曾经提出过解决方案?查看维基百科的文章和链接的参考文献,我在任何地方都看不到算法。我想在javascript中做到这一点,在该处我已经知道使两棵树不同的原始操作,但是想产生一个可选的diff:例如,如果修剪了一部分树,然后将其重新移植到同一位置它将优化为不变。
2013年

@Michael,您发现有用的东西了吗?我正在寻找减少树木变化的相同算法。
帕维尔

Answers:


25

不仅有Wikipedia关于图同构的文章(如Space_C0wb0y所指出),而且还有关于图同构问题的专门文章。它有一个Solved special cases已知多项式时间解的部分。树是其中之一,它引用了以下两个引用:


16

您不清楚要比较源代码的抽象语法树,解释为树的XML文档还是其他类型的树。

有许多论文讨论比较语法树和通过各种方式计算最小距离。这些想法应该是相关的。

很好的论文是Change Distilling,它试图比较两个抽象语法树的源代码并报告最小的差异。本文讨论了一种特定的方法,还简要提及(并提供了参考)各种类似的技术。

在用于比较计算机程序源文本的可用工具中,实际上很少能实现这些算法。我们的智能差异器就是其中之一。它由许多语言的显式语言语法驱动。


2
实际上,在我们的例子中,它不是源代码,实际上是树。这些树中有一些语义,但是总的来说并不重要-它们直接由用户作为树进行操作
Tomas Vana

链接断开:我只花了20分钟时间来寻找“变更蒸馏”文件。这是更新的链接:merlin.uzh.ch/publication/show/2531 该软件项目本身已移至bitbucket.org/sealuzh/tools-changedistiller/wiki/Home(这是我获得PDF正确链接的方式)
Shalom Craimer

13

尽管这个问题很旧,但我将在下面添加更多参考资料和算法:

  1. X-Diff:一种有效的XML文档变更检测算法,王远,David J. DeWitt,蔡金一
  2. KF-Diff +:高效的XML文档变更检测算法
  3. diffX:一种用于检测多版本XML文档中的更改的算法
  4. XML树中的变更检测:调查,Luuk Peters
  5. 树数据结构的相似性

此外,GitHub上有一些库和框架(使用javascript),它们实现了树状结构的区分,例如处理JSON数据或XML树的应用程序(例如,针对客户端MVC / MVVM):

  1. React.js
  2. JSON补丁
  3. jsondiffpatch
  4. objectDiff

强烈建议阅读该Change Detection in XML Trees: a Survey论文-它列出了数十种XML差异(仅是树差异)算法。
Timmmm

8

如果人们发现此问题并需要为Node.js或浏览器实现某些功能,我将为我编写的实现提供一个链接和代码示例,您可以在github上找到:(https://github.com /hoonto/jqgram.git)基于现有的PyGram Python代码(https://github.com/Sycondaman/PyGram)。

这是一个树形编辑距离近似算法,但是它比试图找到真实的编辑距离快得多。逼近在O(n log n)时间和O(n)空间中执行,而使用已知的真实编辑距离算法,真实编辑距离通常为O(n ^ 3)或O(n ^ 2)。请参阅PQ-Gram算法来自的学术论文:(http://www.vldb2005.org/program/paper/wed/p301-augsten.pdf

因此,使用jqgram:

例:

var jq = require("jqgram").jqgram;
var root1 = {
    "thelabel": "a",
    "thekids": [
        { "thelabel": "b",
        "thekids": [
            { "thelabel": "c" },
            { "thelabel": "d" }
        ]},
        { "thelabel": "e" },
        { "thelabel": "f" }
    ]
}

var root2 = {
    "name": "a",
    "kiddos": [
        { "name": "b",
        "kiddos": [
            { "name": "c" },
            { "name": "d" },
            { "name": "y" }
        ]},
        { "name": "e" },
        { "name": "x" }
    ]
}

jq.distance({
    root: root1,
    lfn: function(node){ return node.thelabel; },
    cfn: function(node){ return node.thekids; }
},{
    root: root2,
    lfn: function(node){ return node.name; },
    cfn: function(node){ return node.kiddos; }
},{ p:2, q:3 },
function(result) {
    console.log(result.distance);
});

这样一来,您可以得到一个介于0和1之间的数字。该数字越接近零,则它们与jqgram的关系就越紧密。一种方法可能是使用jqgram从给定速度的众多树中缩小几个紧密相关的树,然后对剩余的几棵树使用真正的编辑距离,您需要仔细检查这些树,为此您可以找到python例如,Zhang&Shasha算法的参考或端口实现。

请注意,lfn和cfn参数指定每个树如何独立确定每个树根的节点标签名称和子数组,以便您可以做一些时髦的事情,例如将对象与浏览器DOM进行比较。您需要做的就是提供这些函数以及每个根,而jqgram将完成其余的工作,调用lfn和cfn提供的函数来构建树。因此从某种意义上说(无论如何,我认为它)比PyGram更容易使用。另外,它的Javascript,因此请在客户端或服务器端使用它!

另外,要回答关于周期检测的问题,请检查jqgram内部的clone方法,那里有周期检测,但是值得感谢的是node-clone的作者,对该节点进行了稍微修改并包含了它。


这允许多个lfn吗?我想比标签匹配更多,即。也是储值。node.value。
约翰·克特吉克

0

这称为树到树校正问题树到树编辑问题。出于某些原因,处理此问题的大多数文献都明确地涉及到比较XML树,因此搜索“ XML差异算法”会产生很多结果。除了Nikos的链接列表,我还发现了以下这些:

我也强烈建议阅读“ XML树中的更改检测:调查”,但它来自2005年,因此它所提到的任何工具都几乎不再存在。将XML文档作为具有参考感知能力的标记有序树进行比较,可以很好地直观描述到目前为止我发现的某些算法(从2.1.2节开始)。

不幸的是,似乎没有太多开源代码可以做到这一点,而且它不是很古老。只是很多过于复杂的论文。:-/


我看不到本文,pdf链接是否损坏? Change Detection in XML Trees: a Survey
芒果

为我工作。您是否单击了Download full-test PDF按钮?如果由于某种原因被阻止,请尝试使用Sci-hub。
Timmmm
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.