Esta es más una pregunta de CS, pero interesante:
Digamos que tenemos 2 estructuras de árbol con más o menos los mismos nodos reorganizados. Como encontraras
- alguna
- en cierto sentido mínimo
secuencia de operaciones
MOVE(A, B)
- mueve el nodo A debajo del nodo B (con todo el subárbol)INSERT(N, B)
- inserta un nuevo nodo N debajo del nodo BDELETE (A)
- elimina el nodo A (con todo el subárbol)
que transforma un árbol en otro.
Obviamente, podría haber casos en los que tal transformación no sea posible, siendo trivial la raíz A con el niño B a la raíz B con el niño A, etc.). En tales casos, el algoritmo simplemente entregaría un resultado " no posible ".
Una versión aún más espectacular es una generalización para redes, es decir, cuando asumimos que un nodo puede ocurrir varias veces en el árbol (efectivamente tiene múltiples "padres"), mientras que los ciclos están prohibidos.
Descargo de responsabilidad: esto no es una tarea, en realidad proviene de un problema comercial real y me pareció bastante interesante preguntarme si alguien podría conocer una solución.
fuente
MOVE(A,B)
parece ser lo mismo queINSERT(A,B)
siA
no tuviera hijos. ¿Qué pasa con los hijos deA
si uno lo haceINSERT(A,B)
? (¿Estarán apegados alA
padre de '?)Respuestas:
No solo hay un artículo de Wikipedia sobre isomorfismo de grafos (como señala Space_C0wb0y), sino también un artículo dedicado al problema del isomorfismo de grafos . Tiene una sección
Solved special cases
para la que se conocen soluciones en tiempo polinómico. Trees es uno de ellos y cita las siguientes dos referencias:fuente
No tenía claro si estaba comparando árboles de sintaxis abstracta para el código fuente, documentos XML interpretados como árboles o algún otro tipo de árbol.
Hay varios artículos que discuten la comparación de árboles de sintaxis y el cálculo de distancias mínimas por varios medios. Las ideas deben ser relevantes.
Un buen artículo es Change Distilling , que intenta comparar el código fuente de dos árboles de sintaxis abstractos e informar una diferencia mínima. El documento habla de un método específico y también menciona brevemente (y proporciona referencias) a una variedad de técnicas similares.
Pocos de estos algoritmos se realizan en las herramientas disponibles para comparar el texto fuente de los programas de computadora. Nuestro Smart Differencer es uno de ellos; está impulsado por una gramática explícita del lenguaje para muchos idiomas.
fuente
Aunque esta pregunta es antigua, agregaré un par de referencias y algoritmos más a continuación:
Además, hay bibliotecas y marcos en GitHub (en javascript) que implementan la diferenciación de estructuras en forma de árbol, por ejemplo, aplicaciones que se ocupan de datos JSON o árboles XML (por ejemplo, para MVC / MVVM del lado del cliente):
fuente
Change Detection in XML Trees: a Survey
documento: enumera docenas de algoritmos para la diferenciación de XML (que es solo diferenciación de árbol).En caso de que la gente encuentre esta pregunta y necesite algo implementado para Node.js o el navegador, proporciono un enlace y un ejemplo de código para una implementación que he escrito que puede encontrar en github aquí: ( https://github.com /hoonto/jqgram.git ) basado en el código PyGram Python existente ( https://github.com/Sycondaman/PyGram ).
Este es un algoritmo de aproximación de distancia de edición de árbol , pero es mucho, mucho más rápido que intentar encontrar la distancia de edición real. La aproximación se realiza en el tiempo O (n log n) y el espacio O (n), mientras que la distancia de edición real suele ser O (n ^ 3) u O (n ^ 2) utilizando algoritmos conocidos para la distancia de edición real. Vea el artículo académico del que proviene el algoritmo PQ-Gram: ( http://www.vldb2005.org/program/paper/wed/p301-augsten.pdf )
Entonces usando jqgram:
Ejemplo:
Y eso le da un número entre 0 y 1. Cuanto más cerca de cero, más estrechamente relacionados se ven los dos árboles con jqgram. Un enfoque podría ser usar jqgram para reducir varios árboles estrechamente relacionados de entre muchos árboles dada su velocidad, luego utilizar la distancia de edición real en los pocos árboles restantes que necesita para inspeccionar más de cerca, y para eso puede encontrar python implementaciones para referencia o puerto del algoritmo Zhang & Shasha, por ejemplo.
Tenga en cuenta que los parámetros lfn y cfn especifican cómo cada árbol debe determinar los nombres de las etiquetas de los nodos y la matriz secundaria para cada raíz del árbol de forma independiente para que pueda hacer cosas divertidas como comparar un objeto con un DOM del navegador, por ejemplo. Todo lo que necesita hacer es proporcionar esas funciones junto con cada raíz y jqgram hará el resto, llamando a sus funciones proporcionadas lfn y cfn para construir los árboles. Entonces, en ese sentido, es (en mi opinión de todos modos) mucho más fácil de usar que PyGram. Además, es Javascript, ¡así que utilícelo del lado del cliente o del servidor!
TAMBIÉN, para responder con respecto a la detección de ciclos, consulte el método de clonación dentro de jqgram, hay detección de ciclos allí, pero el crédito es para el autor del clon de nodo a partir del cual esa pieza fue ligeramente modificada e incluida.
fuente
Esto se denomina problema de corrección de árbol a árbol o problema de edición de árbol a árbol . La mayor parte de la literatura que trata sobre esto se relaciona explícitamente con la comparación de árboles XML por alguna razón, por lo que la búsqueda de "algoritmo de diferenciación de XML" produce muchos resultados. Además de la lista de enlaces de Nikos, encontré estos:
El código para esto: ¡ VTracker todavía existe!Editar: en realidad, el código interesante no está incluido. Esto me señaló ...También recomiendo encarecidamente leer Change Detection in XML Trees: a Survey, pero es de 2005, por lo que casi ninguna de las herramientas que menciona ya existen. La comparación de documentos XML como árboles ordenados etiquetados con reconocimiento de referencias tiene la mejor descripción intuitiva de algunos de los algoritmos que he encontrado hasta ahora (comience en la sección 2.1.2).
Desafortunadamente, no parece haber mucho código fuente abierto disponible que haga esto y no sea antiguo. Solo un montón de artículos demasiado complejos. : - /
fuente
Change Detection in XML Trees: a Survey
Download full-test PDF
botón? Quizás pruebe Sci-hub si está bloqueado por alguna razón.