El siguiente algoritmo determinista (sin el comparador) funciona para una tupla de entrada :(a1,…,an)
- Foro de la Fisher-Yates barajar la utilización de su comparador con algún par estático (digamos ) (muestreo de aceptación-rechazo haciendo) como una moneda al aire. Si el comparador genera 1 por primera vez, úselo invertido para evitar un bucle de rechazo sin fin en el caso determinista.a1<a21
- (aceleración opcional: pruebe un solo par veces, donde n es la longitud o su entrada. Si cualquiera de las dos salidas difiere, devuelva la permutación obtenida en (1))nn
- Ordene su matriz usando merge sort.
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<2lognO(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<a10
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 :
a=(a1,…,an)bk=(bk,1,…,bk,k)k
- Conjunto b1,1=a1
- a2<a1b2=(a2,a1)(c,d):=(2,1)b2=(a1,a2)(c,d):=(1,2)ad<ac0
- bkk≥3bk−1
- l=⌈log2k⌉k′=2lk′2k
- i0=0j∈{1,…,l}
ij=⎧⎩⎨⎪⎪⎪⎪⎪⎪⎪⎪ij−1+2l−jij−1ij−1+2l−jij−1ij−1+2l−j>k−1∧ad<acij−1+2l−j>k−1∧¬(ad<ac)ij−1+2l−j≤k−1∧bk−1,ij−1+2l−j<akij−1+2l−j≤k−1∧¬(bk−1,ij−1+2l−j<ak)
- il>kbk=(bk−1,1,…,bk−1,il−1,ak,bk−1,il,…,bk−1,k−1)
- bn
k−1k
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.