Árbol kdEn ciencias de la computación, un Árbol kd (abreviatura de árbol k-dimensional) es una estructura de datos de particionado del espacio que organiza los puntos en un Espacio euclídeo de k dimensiones. Los árboles kd son un caso especial de los árboles BSP. Un árbol kd emplea sólo planos perpendiculares a uno de los ejes del sistema de coordenadas. Esto difiere de los árboles BSP, donde los planos pueden ser arbitrarios. Además, todos los nodos de un árbol kd, desde el nodo raíz hasta los nodos hoja, almacenan un punto. Mientras tanto, en los árboles BSP son las hojas los únicos nodos que contienen puntos (u otras primitivas geométricas). Como consecuencia, cada plano debe pasar a través de uno de los puntos del árbol kd. Técnicamente, la letra k se refiere al número de dimensiones. Un árbol kd tridimensional podría ser llamado un árbol 3d. Sin embargo se suele emplear la expresión "árbol kd tridimensional". (También es más descriptivo, ya que un árbol tridimensional puede ser varias cosas, pero el término árbol kd se refiere a un tipo en concreto de árbol de particionado.) Las letras k y d se escriben en minúsculas, incluso al principio de una oración. La k se escribe en cursiva, aunque son también comunes las formas "árbol KD" y "árbol Kd". Operaciones en árboles kConstruir un árbol kDado que hay muchas maneras posibles de elegir planos alineados a los ejes, hay muchas maneras de generar árboles kd. El sistema habitual es:
Este método lleva a un árbol kd balanceado, donde cada nodo hoja está a la misma distancia de la raíz. De todas formas, los árboles balanceados no son necesariamente óptimos para todas las aplicaciones. Dada una lista de n puntos, el siguiente algoritmo genera un árbol kd balanceado que contiene dichos puntos.
Este algoritmo implementado en Python sería: class Node:pass
def kdtree(pointList, depth=0):
if not pointList:
return
# Select axis based on depth so that axis cycles through all valid values
k = len(pointList[0]) # assumes all points have the same dimension
axis = depth % k
# Sort point list and choose median as pivot element
pointList.sort(key=lambda x:x[axis])
median = len(pointList)/2 # choose median
# Create node and construct subtrees
node = Node()
node.location = pointList[median]
node.leftChild = kdtree(pointList[0:median], depth+1)
node.rightChild = kdtree(pointList[median+1:], depth+1)
return node
Un ejemplo de uso: pointList = [(2,3),(5,4),(9,1),(4,7),(8,1)]
tree = kdtree(pointList)
Este algoritmo crea el invariante para cualquier nodo. Todos los nodos en el subárbol de la izquierda están en un lado del plano de corte, y todos los nodos del subárbol de la derecha están en el otro lado. El plano de corte de un nodo pasa a través del punto asociado con ese nodo (referenciado en el código por node.location) Añadir elementos a un árbol kdLos nodos se añaden a un árbol kd de la misma forma que se añaden a cualquier otro árbol. Primero, se recorre el árbol empezando por la raíz y siguiendo por el nodo de la izquierda o de la derecha dependiendo de si el punto que se quiere insertar está en la derecha o en la izquierda del plano de corte. Una vez que se llega a un nodo hoja, se añade el nuevo punto a la izquierda o a la derecha del nodo hoja, de nuevo dependiendo de en que lado del plano se encuentra el nuevo punto. Eliminar elementos de un árbol kdPara eliminar un elemento de un árbol kd, lo primero que se debe de hacer es como en cualquier estructura es verificar la existencia del en este caso, punto a eliminar, suponiendo la localización de este fue exitoso como nodo hoja de nuestra estructura, se elimina este nodo y procedemos al rebalanceo. El rebalanceo consiste en revisar desde el nodo padre del nodo eliminado si tiene asociado uno o dos hijos (que son la posibilidades reales que tiene), si tiene solamente 1 hijo, se trepa al nodo hijo a la posición del padre y se elimina ese corte, pasando a revisar al nodo padre, si tiene 2 hijos, podemos concluir la revisión. De igual manera que la inserción, el algoritmo se ejecuta en tiempo logaritmico. Equilibrar un árbol kdHay que ser cuidadoso al equilibrar un árbol kd. Como estos árboles están ordenados en múltiples dimensiones, no se puede emplear la técnica de rotación de árboles para equilibrarlos — esto rompería el invariante. Cuando se eliminan varios nodos (alrededor de la mitad), o cuando se añaden muchos nodos (cuando se acerca a duplicar la cantidad de nodos hoja), podemos decir que la mejor opción para no romper el equilibrio de esta estructura de datos, es optar por volver a construir la estructura, ya que en cuestión de tiempo nos va a tomar la misma complejidad el hacer todos los cambios de golpe que el construir una nueva estructura según los cambios propuestos, pero nos da más segfuridad de mantener la invariante. Usos de un árbol kd
Búsqueda ortogonal en un árbol kdUsar un árbol kd para encontrar todos los puntos que se encuentran en un rectángulo determinado (o análogo de más dimensiones). Esta operación también se denomina rango de búsqueda ortogonal. Determinar dónde evaluar una superficieEn las regresiones locales es común evaluar la superficie contenida directamente solo por los vértices del árbol kd e interpolar en algún punto. Este uso, reflejado en la imagen de arriba, busca asegurar que sólo se realizarán las evaluaciones directas necesarias. Como los árboles kd se "adaptan" al espacio, este método puede suministrar una excelente aproximación a las verdaderas superficies de regresión local. Si la aproximación es pobre, puede mejorarse con más subdivisiones. Complejidad
Enlaces externos (inglés)
|