Inspirado por esta pregunta en la que el autor de la pregunta quiere saber si el tiempo de ejecución cambia cuando el comparador utilizado en un algoritmo de búsqueda estándar se reemplaza por un lanzamiento de moneda justo, y también por la falla prominente de Microsoft al escribir un generador de permutación uniforme, mi pregunta es así :
¿Existe un algoritmo de clasificación basado en la comparación que, según nuestra implementación del comparador:
- devolver los elementos en orden ordenado cuando se utiliza un comparador verdadero (es decir, la comparación hace lo que esperamos en un algoritmo de clasificación estándar)
- devuelve una permutación uniformemente aleatoria de los elementos cuando el comparador se reemplaza por un lanzamiento de moneda justo (es decir, devuelve
x < y = true
con probabilidad 1/2, independientemente del valor de x e y)
El código para el algoritmo de clasificación debe ser el mismo. Es solo el código dentro de la "caja negra" de comparación que está permitido cambiar.
Respuestas:
El siguiente algoritmo determinista (sin el comparador) funciona para una tupla de entrada :(a1,…,an)
Dada una relación de orden determinista como comparador, este algoritmo clasifica una matriz en el tiempo ya que la mezcla aleatoria de Fisher-Yates se ejecuta en O ( n ) utilizando la máxima O ( log n ) "bits aleatorios" no aleatorios (por ejemplo, llamadas a su comparador ) en cada paso y el orden de fusión tiene la misma complejidad asintótica. El resultado de (1) es totalmente inútil en este caso, pero dado que es seguido por un tipo real, esto no hace daño.O(nlogn) O(n) O(logn)
Dado un lanzamiento de moneda real, el comparador (1) permuta la matriz con la misma probabilidad para cada permutación y si realmente tiene que hacer (3) (omitió (2) o (2) no pudo determinar la aleatoriedad), esto no es daño porque la distribución de su resultado solo depende del orden de su entrada que se distribuye uniformemente entre todas las permutaciones debido a (1), por lo que el resultado de todo el algoritmo también se distribuye uniformemente. El número de veces que se debe repetir cada muestreo de aceptación-rechazo se distribuye geométricamente (rechazar con probabilidad ) y por lo tanto tiene un valor esperado<2. Cada repetición usa como máximolognbits, por lo que el análisis de tiempo de ejecución es casi el mismo que en el caso determinista, pero solo obtenemos untiempodeejecución esperadodeO(nlogn), con la posibilidad de no terminación (terminacasi con seguridad).<12 <2 logn O(nlogn)
Como señaló Joe: si no le gusta la prueba para el primer bit en (1), haga (3) luego (1) y use que siempre es 0 , ya que la matriz ya está ordenada en caso determinista Además, debe restar su número aleatorio del límite superior en el rango en el bucle, porque el límite superior para el número aleatorio produce la permutación idéntica. Pero tenga en cuenta que (2) está prohibido entonces, porque siempre tiene que barajar en el caso de rescate.an<a1 0
Incluso puede usar las mismas llamadas a su comparador para (1) y (3), pero luego demostrar que el resultado se distribuye uniformemente es al menos mucho más difícil, si es posible.
El siguiente algoritmo no tiene fases distintas para barajar y ordenar, pero es asintóticamente más lento. Es esencialmente una ordenación por inserción con búsqueda binaria . Usaré para denotar la entrada y b k = ( b k , 1 , ... , b k , k ) para denotar el resultado después de la ronda k :
Tenga en cuenta que este algoritmo es ineficiente en ambos modos en comparación con la ordenación aleatoria y de fusión de Fisher-Yates, ya que insertar un elemento en una posición arbitraria es costoso si se usa una matriz y la búsqueda binaria necesita tiempo lineal si se usa una lista. Pero quizás una modificación de la ordenación del montón o la ordenación del árbol de manera similar podría conducir a un algoritmo más rápido.
fuente
fuente