¿Cuál es el algoritmo más eficiente para calcular el modo de una matriz de enteros?

Curiosamente, esto se puede hacer en tiempo sublineal para una matriz ordenada con un modo frecuente: el hecho de que la matriz esté ordenada nos permite saltarnos un montón de elementos.

Supongamos que tenemos una matriz ordenada de enteros [math] n [/ math] con frecuencia de modo (desconocido) [math] m [/ math]. Deje que [math] 2 ^ k [/ math] sea la mayor potencia de [math] 2 [/ math] menor que [math] n [/ math]. Comience muestreando cada [matemático] 2 ^ k [/ matemático] th entero en la matriz, luego cada [matemático] 2 ^ {k-1} [/ matemático], cada [matemático] 2 ^ {k-2} [ / math] th, etc. hasta que encontremos dos enteros a distancia [math] 2 ^ i [/ math] que sean iguales. Como la distancia más grande entre dos enteros iguales es [matemática] m – 1 [/ matemática], debemos tener [matemática] 2 ^ i <m <2 ^ {i + 2} [/ matemática].

En este punto, el modo debe ser uno de los enteros [math] \ bigl \ lceil \ tfrac {n} {2 ^ i} \ bigr \ rceil [/ math] que hemos muestreado. Use búsquedas binarias para encontrar los puntos finales izquierdo y derecho de los intervalos iguales a cada uno de los enteros muestreados. El intervalo más largo será el modo.

El tiempo de ejecución total es [matemáticas] O \ bigl (\ tfrac {n} {2 ^ i} + \ tfrac {n} {2 ^ i} \ cdot i \ bigr) = O \ bigl (\ tfrac {n (1 + \ log m)} {m} \ bigr) [/ math].

Si el conjunto no está ordenado, es claro que tiene que leer la entrada al menos una vez. Por lo tanto, una tabla hash simple con un contador máximo adicional puede encontrar el modo en tiempo y espacio lineales.

Uno puede usar la técnica de aproximación para reducir el espacio a O (1) en algunos casos, pero no en el peor de los casos.
encontrar el modo en 2 pasadas: boceto Count-min
dureza – Página en tau.ac.il

Nuestro objetivo es minimizar el número de comparaciones.

Una posible forma de encontrar el modo es usar la clasificación. Una vez que los elementos están ordenados, podemos escanear la secuencia ordenada y contar las multiplicidades (elementos iguales serán consecutivos en la secuencia ordenada). Pero la clasificación no siempre es necesaria. La razón para pensar que la clasificación puede no ser necesaria es que la búsqueda de la mayoría (aquí significa mayoría, el elemento aparecerá más de n / 2 veces en la secuencia) se puede hacer en tiempo lineal, mientras que la clasificación requiere un tiempo O (n log n) . Esto nos lleva a sospechar que, si la multiplicidad (la cantidad de veces que ocurre un elemento se llama multiplicidad) del modo es alta, entonces puede haber una forma rápida de encontrarlo sin ordenarlo.

Utilizamos el enfoque de divide y vencerás para mejorar el rendimiento del algoritmo. Dividimos el conjunto en dos partes de aproximadamente el mismo tamaño. Las dos partes deben ser disjuntas, de modo que conduzcan a subproblemas independientes. Dividimos el conjunto en dos partes disjuntas aproximadamente iguales usando el algoritmo de búsqueda medio. Primero encontramos la mediana del conjunto y luego la dividimos en tres partes: menor, igual y mayor que la mediana. Aquí encontramos la mediana en tiempo lineal en el peor de los casos. Entonces, primero encontramos la mediana y realizamos la división, luego resolvemos dos subproblemas de tamaño no mayor que n / 2. El modo del conjunto original se puede determinar fácilmente a partir de los modos de los dos conjuntos más pequeños, ya que los conjuntos más pequeños son disjuntos. Dado que la búsqueda de la mediana y la división se pueden hacer en tiempo lineal. Paramos el procedimiento una vez que encontramos los valores máximos iguales de tamaño M (multiplicidad de modos).

Entonces, la complejidad del tiempo total es la siguiente:

  • mediana de búsqueda: O (n)
  • División: O (n)
  • La recursividad aumentará a niveles de registro (n / M) de profundidad. La complejidad del tiempo total es O (n log (n / M))

Donde M es la multiplicidad del modo del conjunto. Por lo tanto, este algoritmo es superior a la clasificación solo si M es bastante alto y si el costo de las comparaciones también es alto (hay una sobrecarga significativa para recordar subproblemas)

CountingSort (). HashTables son útiles para matrices enteras y no enteras, aunque más complejas. Ambos tienen O (n) complejidad. Es decir, el tiempo de ejecución aumenta en relación directa con el número de elementos. 4 veces más elementos resultan en un aumento de 4 veces en el tiempo de ejecución. CountingSort () requiere min (matriz) a max (matriz) y a veces no es eficiente en memoria. Las HashTables requieren una cantidad fija de espacio, una función de generación de índice y un procedimiento de sondeo. Para matrices grandes sin clasificar, estos 2 métodos están bien. Para ordenar, contar las ocurrencias en una fila y hacer un seguimiento del conteo máximo y el valor del elemento es suficiente.

Siento que las respuestas dadas suponen una matriz ordenada o una secuencia y encuentran aproximadamente las frecuencias, ambas complicando el problema que se pide que se resuelva. La pregunta era encontrar el modo en una variedad de enteros de manera eficiente. Como no se dijo lo que define la eficiencia, asumiré que es el momento. Entonces, la solución sería construir un histograma y, después de cada actualización, verificar si el nuevo contenedor de histograma es más grande que el máximo y, de ser así, actualizar el modo.

  1. H diccionario vacío, maxH = 0, modo = nulo
  2. Si x en H: H (x) = H (x) +1 más H (x) = 1
  3. si H (x)> maxH maxH = H (x) y mode = x

More Interesting

¿Es posible crear una matriz paralela bidimensional?

¿Cuál es la técnica para crear una solución DP iterativa a partir de su solución recursiva?

Cómo eliminar un elemento específico y reducir el tamaño de una matriz en Java

Cómo construir robots enjambre

¿Cuáles son las aplicaciones del mundo real de algunas estructuras de datos avanzadas, y cuándo elegiría una estructura de datos sobre otra, en el caso de estructuras de datos similares?

¿Cuál es un buen algoritmo para priorizar mensajes DENTRO de su bandeja de entrada?

Cómo explorar los datos para elegir un algoritmo de aprendizaje automático

¿Cuál es el mejor sitio en línea para aprender estructuras de datos y algoritmos?

¿Por qué Java utiliza diferentes algoritmos de clasificación para diferentes tipos de datos?

¿Por qué mi código solo pasa números pequeños y no los grandes (con respecto a subconjuntos no divisibles)?

¿Algún algoritmo de aprendizaje profundo quedará obsoleto algún día con los algoritmos tradicionales? ¿O los algoritmos de aprendizaje profundo solo son adecuados para problemas específicos?

¿Qué es un algoritmo eficiente para encontrar un número mágico?

¿Dónde puedo encontrar un algoritmo de ordenación que maneje los números dentro de las cadenas correctamente?

¿Alguien puede ayudarme a dibujar un árbol de recursión para la ecuación [matemáticas] T (n) = T (n-2) + n [/ matemáticas]?

¿Qué algoritmos y estructuras de datos se pueden usar para encontrar anagramas?