Falls Leute diese Frage finden und etwas für Node.js oder den Browser implementieren müssen, stelle ich einen Link und ein Codebeispiel für eine Implementierung bereit, die ich geschrieben habe und die Sie auf github hier finden: ( https://github.com /hoonto/jqgram.git ) basierend auf dem vorhandenen PyGram Python-Code ( https://github.com/Sycondaman/PyGram ).
Dies ist ein Algorithmus zur Approximation der Baumbearbeitungsentfernung, der jedoch viel, viel schneller ist als der Versuch, die wahre Bearbeitungsentfernung zu ermitteln. Die Approximation erfolgt in O (n log n) Zeit und O (n) Raum, während die wahre Bearbeitungsentfernung häufig O (n ^ 3) oder O (n ^ 2) ist, wobei bekannte Algorithmen für die wahre Bearbeitungsentfernung verwendet werden. Siehe die wissenschaftliche Arbeit, aus der der PQ-Gram-Algorithmus stammt: ( http://www.vldb2005.org/program/paper/wed/p301-augsten.pdf )
Also mit jqgram:
Beispiel:
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);
});
Und das gibt Ihnen eine Zahl zwischen 0 und 1. Je näher an Null, desto enger sind die beiden Bäume mit jqgram verwandt. Ein Ansatz könnte darin bestehen, jqgram zu verwenden, um mehrere eng verwandte Bäume unter vielen Bäumen aufgrund seiner Geschwindigkeit einzugrenzen, und dann den tatsächlichen Bearbeitungsabstand für die wenigen verbleibenden Bäume zu verwenden, die Sie genauer untersuchen müssen, und dafür finden Sie Python Implementierungen als Referenz oder Port des Zhang & Shasha-Algorithmus zum Beispiel.
Beachten Sie, dass die Parameter lfn und cfn angeben, wie jeder Baum die Knotenbezeichnungsnamen und das untergeordnete Array für jeden Baumwurzel unabhängig bestimmen soll, damit Sie funky Dinge wie den Vergleich eines Objekts mit einem Browser-DOM ausführen können. Alles, was Sie tun müssen, ist, diese Funktionen zusammen mit jeder Wurzel bereitzustellen, und jqgram erledigt den Rest und ruft Ihre von lfn und cfn bereitgestellten Funktionen auf, um die Bäume aufzubauen. In diesem Sinne ist es (meiner Meinung nach jedenfalls) viel einfacher zu bedienen als PyGram. Plus, sein Javascript, also benutze es client- oder serverseitig!
Um auch in Bezug auf die Zykluserkennung zu antworten, überprüfen Sie die Klonmethode innerhalb von jqgram. Dort gibt es eine Zykluserkennung. Dies geht jedoch an den Autor des Knotenklons, von dem das Teil leicht modifiziert und eingeschlossen wurde.
MOVE(A,B)
scheinen die gleichen zu sein, alsINSERT(A,B)
hätteA
sie keine Kinder. Was passiert mit den Kindern,A
wenn man es tutINSERT(A,B)
? (Werden sie anA
's Eltern gebunden sein ?)