6 votos

Minimizando la distancia entre puntos en dos sets.

Dados dos conjuntos a $A, B\subset \mathbb{N}^2$, cada una con cardinalidad finita, ¿qué es lo más eficiente algoritmo para calcular $\min_{u\in A, v\in B}d(u, v)$ donde $d(u,v)$ el (Euclidiana) de la distancia entre el $u$ $v$ (puede ser considerado como puntos o vectores). También lo es el más eficiente algoritmo para determinar el $u$ $v$ (no necesariamente único) tal que $d(u,v)$ se reduce al mínimo?


Para minimizar $d(u,v)$ es prácticamente el mismo que minimizar $[d(u,v)]^2$, que puede ser escrito utilizando la fórmula de la distancia. Pero no podía pensar en nada mejor que un ataque de fuerza bruta $O(|A||B|)$ solución (donde $|A|$ denota la cardinalidad de a $A$) que intenta todo lo posible $u\in A,v\in B$.

1voto

Irvan Puntos 1394

He aquí un $O(n \log n)$ algoritmo que funciona para todos los posibles conjuntos de $A$$B$.

Deje $n = |A| + |B|$.

Esta pregunta se ha hecho en otras plataformas (aquí o aquí), pero ninguno de ellos dar respuestas satisfactorias (...al menos para mí. No puedo comprobar que funcionan en la reclamación del tiempo para todas las posibles entradas. Por ejemplo, el uso de KD árbol no garantiza $O(n \log n)$ menos que los puntos son lo suficientemente aleatorio. La respuesta a la segunda vínculo es aún más malo).

Así que, aquí está una puramente $O(n \log n)$ algoritmo para resolver esto! Buena cosa que haya hecho esta pregunta en matemáticas foro, porque a pesar de ser teóricamente interesante, yo no quiero implementarlo...

En primer lugar, construir el diagrama de voronoi $V_A$ de todos los puntos en $A$. Para cada punto de $b_j \in B$, hallar la celda de voronoi $v_i \in V_A$ que contiene el punto-por la propiedad de un diagrama de voronoi, sabemos que $a_i$ es el vecino más cercano de $b_j$. Por lo tanto, al hacer esto para todos los puntos en $B$ y tomando el mínimo, se obtiene la par con un mínimo de distancia.

Claro, eso suponiendo que somos capaces de encontrar la celda $v_i$ por cada punto de $b_i$ rápidamente. Para hacerlo de forma rápida, podemos utilizar el barrido de la línea de algoritmo: barrido de todos los puntos en el diagrama de voronoi $V_A$ y los puntos de $B$. Podemos almacenar la actual partición del espacio mediante un árbol binario de modo que cada vez que el barrido de la línea se encuentra un punto de $b_i \in B$, somos capaces de encontrar el diagrama de voronoi que contengan $b_i$$O(\log n)$. Siempre que encontremos un punto de $a_i \in A$, podemos actualizar el árbol de la estructura del diagrama de voronoi. Este barrido de la línea es bastante análoga a la de la línea de barrido se realiza para "buscar líneas de intersección" algoritmo.

Desde la construcción de un diagrama de voronoi tarda $O(n \log n)$ a tiempo, todo el procedimiento se $O(n \log n)$.

i-Ciencias.com

I-Ciencias es una comunidad de estudiantes y amantes de la ciencia en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X