2010-07-18 11 views
8

Tengo una lista de valores (unidimensionales) y me gustaría conocer la mejor estructura de datos/algoritmo para encontrar el valor de consulta más cercano que tengo. La mayoría de las soluciones (¿todas?) Que encontré aquí son para 2 o más dimensiones. ¿Alguien puede sugerirme el enfoque para mi caso?Mejor estructura de datos para el vecino más cercano en 1 dimensión

Mi instinto me dice que ordene los datos y utilice la búsqueda binaria de alguna manera. Por cierto, no hay límite en la construcción o el tiempo de inserción de ningún árbol, por lo que probablemente alguien pueda sugerir un árbol mejor que simplemente una lista ordenada.

+2

un BST en combinación con la búsqueda binaria suena perfectamente bien para mí. –

Respuesta

9

Si necesita algo más rápido que O (log (n)), que puede obtener fácilmente con una matriz ordenada o una búsqueda binaria árbol, puede usar un van Emde Boas Tree. Los árboles vEB te dan O (log (log (n))) para buscar el elemento más cercano a cada lado.

+7

En comparación con una matriz ordenada, un árbol vEB es un cerdo espacial complicado. A menos que los puntos sean muy densos, es probable que los efectos de la jerarquía de la memoria anulen la diferencia teórica entre O (log n) y O (log log n) y algo más. – user382751

+0

Eso es impresionante. Estoy aceptando esta respuesta como la mejor teoría hasta ahora para datos lineales enormes. Aunque de manera realista, voy a usar la lista ordenada/búsqueda binaria que debería ser suficiente para mis propósitos. –

1

Ordene la lista y utilice la búsqueda binaria para encontrar el elemento que está buscando, luego compare sus vecinos izquierdo y derecho. Puede usar una matriz que es O (1) acceso.

Algo así como:

int nearest(int[] list, int element) { 

    sort(list); 
    int idx = binarySearch(element, list); 

    // make sure you are accessing elements that exist 
    min = (element - list[idx-1] <= list[idx+1] - element) ? idx-1 : idx+1; 

    return list[min]; 
} 

Esta es O (n log n), el cual será amortizado si se va a realizar muchas subidas mirada.

EDIT: Para que usted tendría que mover la clasificación de este método

+0

Primero, todavía no veo cómo la función min devuelve el elemento correcto. Ni siquiera se compara con el punto de consulta. En segundo lugar, el costo amortizado no parece mejorar nada ... no debe ordenar la lista al realizar consultas. Debería hacerlo solo cuando modifique la colección de puntos. –

+0

@ Eyal-Schneider Gracias – quantumSoup

+0

En realidad, si mueve la clasificación, la búsqueda binaria debe ser O (log n) –

1

Como ya se ha mencionado, la forma más fácil y rápida debe clasificar los datos y luego en busca de la izquierda y derecha de un vecino punto de datos.

2

Si el tiempo de inserción es irrelevante, la búsqueda binaria en una matriz ordenada es la forma más sencilla de lograr el tiempo de consulta O (log N). Cada vez que se agrega un elemento, ordena todo. Para cada consulta, realice una búsqueda binaria. Si se encuentra una coincidencia, devuélvala. De lo contrario, la búsqueda binaria debería devolver el índice del artículo, donde debería haberse insertado. Use este índice para verificar los dos elementos vecinos y determinar cuál de ellos está más cerca del punto de consulta.

Supongo que hay soluciones con O (1) tiempo. Trataré de pensar en uno que no involucre demasiado uso de memoria ...

+0

Eso debería ser interesante. No veo cómo puede encontrar el vecino más cercano en el tiempo que sea independiente del tamaño del conjunto de datos. Entonces, si tienes alguna solución como esa, por favor agrégala aquí, aunque es más curiosidad académica en esta etapa. –

+1

@Muhammad: esta es una compensación entre la complejidad del tiempo y la complejidad del espacio. Suponiendo que no tiene problemas de espacio (o que el rango de valores no es tan grande), puede simplemente crear una gran matriz que contenga en la posición k el punto más cercano al valor de consulta k.Esto tiene complejidad de tiempo de consulta O (1) y complejidad de espacio O (max-min). No estoy seguro de cómo se puede mejorar la complejidad del espacio, sin embargo ... –

+0

Gran idea. Así que esto parece una implementación de la tabla de búsqueda de la función encontrar más cercana. El problema es cualquier hash que se me ocurra para este caso lo transformará por algo O (log n). –

Cuestiones relacionadas