En tamaños de ventana más pequeños, la n log n
ordenación podría funcionar. ¿Hay algún algoritmo mejor para lograr esto?
algorithms
median
miku
fuente
fuente
Respuestas:
Es una mala forma ordenar una matriz para calcular una mediana. Las medianas (y otros cuantiles) generalmente se calculan utilizando el algoritmo de selección rápida , con complejidad .O ( n )
También es posible que desee ver mi respuesta a una pregunta relacionada reciente aquí .
fuente
Aquí hay un artículo que describe un algoritmo posible. Código fuente incluido y una aplicación bastante seria (detección de ondas gravitacionales basada en interferometría láser), por lo que puede esperar que se pruebe bien.
fuente
Si está dispuesto a tolerar una aproximación, existen otros métodos. Por ejemplo, una aproximación es un valor cuyo rango está dentro de una distancia (especificada por el usuario) de la mediana real. Por ejemplo, la mediana tiene un rango (normalizado) de 0.5, y si especifica un término de error del 10%, desearía una respuesta que tenga un rango entre 0.45 y 0.55.
Si tal respuesta es apropiada, existen muchas soluciones que pueden funcionar en ventanas deslizantes de datos. La idea básica es mantener una muestra de los datos de cierto tamaño (aproximadamente 1 / término de error) y calcular la mediana en esta muestra. Se puede demostrar que con alta probabilidad, independientemente de la naturaleza de la entrada, la mediana resultante satisface las propiedades que mencioné anteriormente.
Por lo tanto, la pregunta principal es cómo mantener una muestra continua de los datos de cierto tamaño, y hay muchos enfoques para eso, incluida la técnica conocida como muestreo de yacimientos. Por ejemplo, este documento: http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.24.7136
fuente
Si mantiene una ventana de datos de longitud k como una lista doblemente ordenada, entonces, mediante una búsqueda binaria (para insertar cada elemento nuevo a medida que se desplaza en la ventana) y una matriz circular de punteros (para ubicar inmediatamente elementos que debe eliminarse), cada cambio de la ventana requiere un esfuerzo O (log (k)) para insertar un elemento, solo un esfuerzo O (1) para eliminar el elemento desplazado fuera de la ventana, y solo un esfuerzo O (1) para encontrar la mediana (porque cada vez que se inserta o elimina un elemento en la lista, puede actualizar un puntero a la mediana en el tiempo O (1)). Por lo tanto, el esfuerzo total para procesar una matriz de longitud N es O ((nk) log (k)) <= O (n log (k)). Esto es mejor que cualquiera de los otros métodos propuestos hasta ahora y no es una aproximación, es exacto.
fuente
Como mencionó, la clasificación sería
O(n·log n)
por una ventana de longitudn
. Hacer esta mudanza agrega otral=vectorlength
haciendo el costo totalO(l·n·log n)
.La forma más sencilla de impulsar esto es mantener una lista ordenada de los últimos n elementos en la memoria al pasar de una ventana a la siguiente. Como eliminar / insertar un elemento de / en una lista ordenada son ambos,
O(n)
esto generaría costos deO(l·n)
.Pseudocódigo:
fuente
Aquí hay una solución O (1) para encontrar la mediana actual, y O (log n) para agregar un nuevo número http://www.dsalgo.com/RunningMedian.php
fuente
Si puede vivir con una estimación en lugar de la mediana real, el Algoritmo Remedian (PDF) es de una pasada con bajos requisitos de almacenamiento y precisión bien definida.
fuente
Usé esta biblioteca RunningStats C ++ en una aplicación incrustada. Es la biblioteca de estadísticas de ejecución más simple que he encontrado hasta ahora.
Desde el enlace:
fuente