두 트리 구조를 동일하게 만들기위한 최소 작업 계산


81

이것은 CS 질문에 더 가깝지만 흥미로운 질문입니다.

동일한 노드가 다소 재구성 된 2 개의 트리 구조가 있다고 가정 해 보겠습니다. 어떻게 찾 겠어요

  1. 어떤
  2. 어떤 의미에서는 최소한

작업 순서

  • MOVE(A, B) -노드 A를 노드 B 아래로 이동 (전체 하위 트리 포함)
  • INSERT(N, B)- 노드 B 아래에 노드 N을 삽입합니다.
  • DELETE (A) -노드 A 삭제 (전체 하위 트리 포함)

하나의 나무를 다른 나무로 변환합니다.

분명히 그러한 변환이 불가능한 경우가있을 수 있습니다. 하위 B가있는 루트 A에서 하위 A가있는 루트 B까지 사소한 경우가 있습니다.) 이러한 경우 알고리즘은 단순히 " 불가능 " 이라는 결과를 제공합니다 .

훨씬 더 멋진 버전은 네트워크에 대한 일반화입니다. 즉, 노드가 트리에서 여러 번 발생할 수 있다고 가정하고 (효과적으로 여러 "부모"가 있음)주기는 금지되어 있습니다.

면책 조항 : 이것은 숙제 가 아니며 실제로 실제 비즈니스 문제에서 비롯된 것이며 누군가가 해결책을 알고 있는지 궁금해하는 것이 매우 흥미 롭다는 것을 알았습니다.


MOVE(A,B)같은 것 같다 INSERT(A,B)경우 A자식이 없습니다. A만약 하나 의 아이들은 어떻게됩니까 INSERT(A,B)? (그들은 A부모 에게 첨부 될까요?)
Andre Holzner

차이점은 INSERT는 이전에 트리에 없었던 새로운 노드를 의미한다는 것입니다 (따라서 최소한 원래 상태도 없었던 원래 상태에는 자식이 없음). 반면에 MOVE는 실제로 이동입니다. 즉, 자식을 포함한 노드의 이동
Tomas Vana

11
이것은 그래프 동형 을 감지해야하는 것처럼 들립니다 . 변환에 대한 부분은 동적 프로그래밍을 사용하여 O (n * m)에서 깔끔하게 풀 수 있는 Levenshtein distance를 생각 나게 합니다. 이 포인터가 도움이 될 수 있습니다.
Björn Pollex 2011

해결책을 생각해 낸 적이 있습니까? 위키피디아 기사와 링크 된 참조를 보면 알고리즘이 어디에도 보이지 않습니다. 두 트리를 다르게 만든 원래 작업을 이미 알고 있지만 선택적 diff를 생성하고 싶은 자바 스크립트에서이 작업을 수행하고 싶습니다. 변화가 없도록 최적화됩니다.
Michael

@Michael, 유용한 것을 찾았습니까? 나는 나무의 변화 감소에 대한 동일한 alhoritm을 지켜보고 있습니다.
Pavel

답변:


25

그래프 동형에 관한 Wikipedia 기사 (Space_C0wb0y가 지적한대로)뿐만 아니라 그래프 동형 문제 에 대한 전용 기사도 있습니다 . Solved special cases다항식 시간 솔루션이 알려진 섹션 이 있습니다. 트리는 그중 하나이며 다음 두 가지 참조를 인용합니다.


16

소스 코드, 트리로 해석되는 XML 문서 또는 다른 유형의 트리에 대해 추상 구문 트리를 비교하고 있는지 확실하지 않았습니다.

구문 트리를 비교하고 다양한 방법으로 최소 거리를 계산하는 것에 대해 논의하는 많은 논문이 있습니다. 아이디어는 관련성이 있어야합니다.

좋은 논문은 Change Distilling으로 , 두 개의 추상 구문 트리에 대한 소스 코드를 비교하고 최소한의 차이를보고하려고합니다. 이 문서는 특정 방법에 대해 이야기하고 다양한 유사한 기술에 대해 간략하게 언급하고 참조를 제공합니다.

이러한 알고리즘 중 컴퓨터 프로그램 소스 텍스트를 비교하는 데 사용할 수있는 도구에서 실제로 실현되는 것은 거의 없습니다. 우리의 Smart Differencer 는 그중 하나입니다. 많은 언어에 대한 명시적인 언어 문법에 의해 구동됩니다.


2
사실, 우리의 경우에는 소스 코드가 아닙니다. 이것은 정말 나무입니다. 이러한 트리에는 의미론이 있지만 그다지 중요하지는 않습니다. 사용자 가 트리로
Tomas Vana

끊어진 링크 : "Change Distilling"문서를 찾는 데 20 분을 보냈습니다. 업데이트 된 링크는 다음과 같습니다. merlin.uzh.ch/publication/show/2531 소프트웨어 프로젝트 자체가 bitbucket.org/sealuzh/tools-changedistiller/wiki/Home 으로 이동했습니다 (이렇게하면 PDF에 대한 올바른 링크를 얻었습니다)
Shalom Craimer

13

이 질문은 오래되었지만 아래에 몇 가지 참조와 알고리즘을 더 추가하겠습니다.

  1. X-Diff : XML 문서를위한 효과적인 변경 감지 알고리즘, Yuan Wang, David J. DeWitt, Jin-Yi Cai
  2. KF-Diff + : XML 문서를위한 매우 효율적인 변경 감지 알고리즘
  3. diffX : 다중 버전 XML 문서의 변경 사항을 감지하는 알고리즘
  4. XML 트리의 변경 감지 : 설문 조사, Luuk Peters
  5. 트리 데이터 구조의 유사성

또한, JSON 데이터 또는 XML 트리 (예 : 클라이언트 측 MVC / MVVM의 경우)를 처리하는 애플리케이션의 경우 트리와 유사한 구조의 차이를 구현하는 GitHub (자바 스크립트)에는 라이브러리와 프레임 워크가 있습니다.

  1. React.js
  2. JSON 패치
  3. jsondiffpatch
  4. objectDiff

Change Detection in XML Trees: a Survey논문을 읽을 것을 적극 권장 합니다-XML diffing (그냥 트리 diffing)에 대한 수십 개의 알고리즘을 나열합니다.
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 사이의 숫자를 제공합니다. 0에 가까울수록 두 나무가 jqgram을 더 가깝게 보입니다. 한 가지 접근 방식은 jqgram을 사용하여 속도가 주어진 여러 트리 중에서 밀접하게 관련된 여러 트리를 좁힌 다음 면밀한 검사가 필요한 나머지 몇 개의 트리에 대한 실제 편집 거리를 활용하여 파이썬을 찾을 수 있습니다. 예를 들어 Zhang & Shasha 알고리즘의 참조 또는 포트에 대한 구현.

lfn 및 cfn 매개 변수는 각 트리가 각 트리 루트에 대한 노드 레이블 이름과 자식 배열을 독립적으로 결정하는 방법을 지정하여 예를 들어 개체를 브라우저 DOM과 비교하는 것과 같은 펑키 한 작업을 수행 할 수 있습니다. 각 루트와 함께 해당 함수를 제공하기 만하면 jqgram이 나머지를 수행하여 lfn 및 cfn 제공 함수를 호출하여 트리를 구축합니다. 따라서 그런 의미에서 PyGram보다 사용하기가 훨씬 쉽습니다. 또한 Javascript이므로 클라이언트 또는 서버 측을 사용하십시오!

또한주기 감지와 관련하여 대답하려면 jqgram 내부의 복제 방법을 확인하십시오. 거기에주기 감지가 있지만 그 부분이 약간 수정되고 포함 된 node-clone의 작성자에게 있습니다.


여러 lfn을 허용합니까? 레이블보다 더 많이 일치시키고 싶습니다. 또한 저장된 값. node.value.
john ktejik

0

이를 트리 대 트리 수정 문제 또는 트리 대 트리 편집 문제라고 합니다. 이 문제를 다루는 대부분의 문헌은 어떤 이유로 XML 트리를 비교하는 것과 관련이 있으므로 "XML diffing algorithm"을 검색하면 많은 결과를 얻을 수 있습니다. Nikos의 링크 목록 외에도 다음을 발견했습니다.

또한 XML 트리의 변경 감지 : 설문 조사를 읽는 것이 좋습니다 . 하지만 2005 년에 작성된 것이기 때문에 언급 한 도구가 더 이상 존재하지 않습니다. XML 문서를 참조 인식 레이블이있는 정렬 된 트리로 비교 지금까지 찾은 알고리즘 중 일부에 대한 가장 직관적 인 설명이 있습니다 (섹션 2.1.2에서 시작).

안타깝게도이를 수행하는 오픈 소스 코드가 많지 않은 것 같고 오래되지 않았습니다. 지나치게 복잡한 논문이 많습니다. :-/


이 문서를 볼 수 없습니다. PDF 링크가 깨 졌나요? Change Detection in XML Trees: a Survey
Mengo

나를 위해 작동합니다. Download full-test PDF버튼 을 클릭 했습니까 ? 어떤 이유로 든 차단 된 경우 Sci-hub를 사용해보십시오.
Timmmm
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.