Puede hacer esto en el tiempo O (n) y en el espacio O (k), donde k es el número de puntos más cercanos que desea, utilizando un truco muy inteligente.
El selection problem es como sigue: Dado un conjunto de elementos y algún índice i, reorganizar los elementos de la matriz de tal manera que el i-ésimo elemento es en el lugar correcto, todos los elementos más pequeños que el i-ésimo elemento están a la izquierda , y todos los elementos mayores que el i-ésimo elemento están a la derecha. Por ejemplo, dada la matriz
40 10 00 30 20
Si tratara de seleccionar basado en el índice 2 (cero-indexada), un resultado podría ser
10 00 20 40 30
Dado que el elemento en el índice 2 (20) está en el lugar correcto, los elementos a la izquierda son más pequeños que 20 y los elementos a la derecha son mayores que 20.
Resulta que, dado que este es un requisito menos estricto que la ordenación de la matriz, es posible hacer esto en el tiempo O (n), donde n es la cantidad de elementos de la matriz. Hacerlo requiere algunos algoritmos complejos como el algoritmo median-of-medians, pero de hecho es O (n) tiempo.
¿Cómo se usa esto aquí? Una opción es cargar todos los n elementos del archivo en una matriz, luego usar el algoritmo de selección para seleccionar la parte superior k en el tiempo O (n) y el espacio O (n) (aquí, k = 100).
¡Pero en realidad puede hacerlo mejor que esto! Para cualquier constante k que desee, mantenga un buffer de 2k elementos. Cargue 2k elementos del archivo en la matriz, luego use el algoritmo de selección para reorganizarlo de manera que los elementos k más pequeños estén en la mitad izquierda de la matriz y los más grandes estén en la derecha, luego descarte los elementos k más grandes (pueden ' t sea uno de los k puntos más cercanos). Ahora, cargue k más elementos del archivo en el búfer y vuelva a hacer esta selección, y repita esto hasta que haya procesado cada línea del archivo. Cada vez que haces una selección, descartas los elementos k más grandes en el búfer y conservas los k puntos más cercanos que has visto hasta ahora. En consecuencia, al final, puede seleccionar los elementos superiores k por última vez y encontrar la parte superior k.
¿Cuál es la complejidad del nuevo enfoque? Bueno, estás usando memoria O (k) para el buffer y el algoritmo de selección. Usted termina llamando a seleccionar en un búfer de tamaño O (k) un total de O (n/k) veces, ya que llama a seleccionar después de leer k elementos nuevos.Como seleccionar en un búfer de tamaño O (k) lleva el tiempo O (k), el tiempo de ejecución total aquí es O (n + k). Si k = O (n) (una suposición razonable), esto toma tiempo O (n), espacio O (k).
Espero que esto ayude!
posible duplicado de [Encuentra los x enteros más pequeños en una lista de longitud n] (http://stackoverflow.com/questions/3764355/find-the-x-smallest-integers-in-a-list-of- longitud-n) – hugomg
Sí, lástima. Es una pregunta interesante, pero ya respondida aquí. –
@missingno: Es similar pero esa pregunta se puede resolver fácilmente con la solución que he proporcionado anteriormente. Aquí, se requieren algunos cálculos adicionales y quería saber si hay alguna manera de minimizarlos. – noMAD