¿Cómo se puede calcular la mediana de una gran variedad de enteros sin mantener todos los valores en la memoria?

Puede hacerlo de manera bastante eficiente con la selección rápida en [math] O (\ log n) [/ math] pasadas de la matriz, para un tiempo de ejecución total de [math] O (n \ log n) [/ math].

(En la implementación estándar de la selección rápida, uno realmente dividiría la matriz en subconjuntos que se ubican a ambos lados del pivote, produciendo un tiempo de ejecución más rápido [matemática] O (n) [/ matemática]. Pero esos subconjuntos podrían no caber en la memoria, entonces Supongo que eso no está permitido aquí. En cambio, solo recordamos los límites en el subconjunto de interés actual y pasamos por todo el conjunto cada vez, ignorando cualquier cosa fuera de los límites).

from itertools import islice from random import randint inf = float("inf") def select(lst, index): lo, hi = -inf, inf count = len(lst) while True: i = randint(0, count - 1) pivot, = islice((x for x in lst if lo <= x < hi), i, i + 1) if count == 1: break lo_count = sum(1 for x in lst if lo <= x < pivot) if index < lo_count: hi = pivot count = lo_count else: lo = pivot count -= lo_count index -= lo_count return pivot 

Al elegir [math] k – 1 [/ math] pivotes aleatorios en lugar de solo uno, donde puede colocar enteros [math] k [/ math] en la memoria, puede reducir el número de pases a [math] O (\ log_k n) [/ matemáticas]. Esta variante todavía se ejecuta en tiempo [matemático] O (n \ log n) [/ matemático] pero exhibe una mejor localidad de referencia.

No sé lo que dice Recetas numéricas, pero un enfoque razonable (dependiendo de sus datos) es a menudo hacer una estimación con un subconjunto y luego usarlo para contar en lugar de almacenar los valores extremos. Incluso con números no enteros, esto puede permitirle pasar una sola vez por la matriz completa y evitar clasificar el 99% de sus datos:

Si la matriz es N elementos, tome un subconjunto aleatorio de tamaño n << N. Si sus datos son aleatorios, puede usar la primera n de la matriz como parte de comenzar un solo paso a través de los datos.

Obtenga un intervalo de confianza del 99.99% para la mediana de n. (Y, obviamente, si su matriz pequeña tiene una distribución divertida, como si fueran todos ceros y unos, entonces se detiene y reconsidera su enfoque. Si solo hay unos pocos valores únicos, puede contar sus instancias).

Continúe su paso por la matriz completa, manteniendo los valores que están dentro del elemento de configuración y el recuento de cuántos elementos están por debajo del límite inferior y cuántos están por encima del límite superior del elemento de configuración.

Si el número de elementos debajo de su límite inferior y superior a su límite superior es individualmente

Este enfoque debería fallar una fracción muy pequeña del tiempo, en cuyo caso simplemente lo vuelve a ejecutar.

Aprendí este truco de Thomas Lumley, uno de los desarrolladores principales de R.

En realidad, Anders Kaseorg cubre el caso en el que se usa O (1) memoria adicional para calcular la mediana. Trataré de explicar la idea general de la solución.

Selección rápida:

1. Seleccione un número ALEATORIO ‘Z’ (ser aleatorio clave aquí). Solo para estar seguro, llame a rand () un par de veces para asegurarse de que sea aleatorio. (No, solo estaba bromeando).

2. Seleccione todos los números menores que Z en una matriz y los números> = Z en otra.

3. Si el conjunto con los números

4. Si el conjunto con los números> = Z tiene cardinalidad

5. 3 y 4 pueden hacerse recursivamente.

Ahora, supongamos que no tenemos memoria adicional para almacenar estos conjuntos, podemos usar http://gregable.com/2007/10/rese … para seleccionar un número aleatorio de una lista. Saltamos elementos que sabemos que no están en el rango requerido. es decir, siempre tenemos un rango (a, b) entre los cuales, si el número cae, consideramos que forma parte de la lista.

Puedo estar equivocado, pero no creo que ningún enfoque estándar para encontrar medianas funcione en este caso. [p.ej. está dividiendo la matriz sobre un pivote aleatorio y luego descarta el enfoque de la mitad (más pequeña) o media de las medianas]

Sugeriría ordenar la matriz y encontrar la mediana.
Para ordenar,
Digamos que puede almacenar 1000 elementos en la memoria y el tamaño de la matriz es de 1 millón, luego ordenar cada uno de los trozos individuales de 1000 y luego fusionarlos [tirar del cabezal de cada una de las 1000 matrices (1), elegir el más pequeño de ellos; use minheap para esto ( 2) y empuje eso de vuelta a la memoria secundaria (3), tire de la cabeza de la matriz cuya cabeza se retiró (4) y luego repita (1)]

More Interesting

¿Cuánto tiempo te lleva programar un algoritmo razonablemente complicado?

¿Cuál es la forma de encontrar tres números cuyo producto y suma sean iguales?

¿Debería alguien que se aplica a un campo de arranque de desarrollo ya saber cómo escribir una función para sumar una matriz multidimensional?

¿Puedo volverme competente en estructuras de datos y algoritmos sin leer el libro CLRS?

¿Cuáles son las ventajas de una matriz?

¿Cuáles son las ventajas de los algoritmos de aprendizaje de refuerzo como LinUCB sobre otros algoritmos de predicción de CTR en línea como la regresión logística en línea?

En la complejidad temporal de un algoritmo, ¿por qué puede considerarse útil que una operación elemental tome "tiempo unitario"?

¿Son los algoritmos de detección de imágenes el futuro de Silicon Valley?

Deje G (V, E) ser un gráfico conectado, no dirigido, dar un algoritmo O (| V | + | E |) para calcular una ruta en G que atraviesa cada borde en E exactamente una vez en cada dirección?

Cuando trato de entender una técnica como la memorización o lo que sea, me enfrento a muchos dolores y no lo entiendo de inmediato. Necesito intentarlo varias veces. ¿Es normal o debo obtener algoritmos y técnicas con al menos uno o 2 aciertos?

¿Qué es la búsqueda de fuerza bruta?

Cómo desarrollar un algoritmo para detectar rangos de negociación horizontales / patrones de consolidación

Cómo ejecutar cruces en algoritmos genéticos con cromosomas codificados por gráficos

¿Cuál es el equivalente binario de -2?

¿Cómo debo hacer uso de sitios como HackerEarth y GeeksforGeeks si tengo habilidades de algoritmos por debajo del promedio?