10 votos

Una prueba de la corrección del algoritmo de permutación aleatoria de Durstenfeld

Pregunta : ¿Alguien tiene una prueba matemática precisa de El algoritmo de Durstenfeld ?

La primera $O(n)$ shuffle o generador de permutación aleatoria fue publicado por Richard Durstenfeld en 1964. Este algoritmo llegó a la atención de los programadores porque fue incluido en Knuth 1969, página 125, 2 como Algoritmo P . Una declaración sucinta del algoritmo es: \begin {ecuación} \text para \leftarrow N, N-1, \ldots ,2\ \text y que no se puede hacer \begin {Casos} \text {Elija al azar un número} {\a6} {\a6} \in [1,k] \\ \text {Intercambio } \pi [r] \text y \pi [k],\ \end {Casos} \end {ecuación} donde $ \pi [1 \ldots n]$ es la matriz que debe ser barajada o cambiada aleatoriamente.

Este es un algoritmo realmente elegante, computacional y matemáticamente. Computacionalmente maneja operaciones de conjunto dividiendo la matriz $ \pi $ en un un set sin estrujar $ \pi [1, \ldots , k]$ y un conjunto barajado $ \pi [k+1, \ldots , n]$ . En cada iteración $k$ elige un elemento aleatorio $ \pi [r]$ del set sin batidores $ \pi [1, \ldots , k]$ y la intercambia con $ \pi [k]$ . Esto se mueve $ \pi [r]$ en el nuevo conjunto barajado $ \pi [k, \ldots , n]$ donde permanece, sin moverse, para todas las iteraciones subsiguientes. Esto se hace en $O(1)$ el tiempo y el espacio. Así, la complejidad temporal y espacial del algoritmo de Durstenfeld es $O(n)$ que es óptimo.

Matemáticamente, el algoritmo es elegante porque utiliza implícitamente el conocido lema que cada permutación $ \pi $ es un producto de transposiciones. En cada iteración $k$ el algoritmo elige un número aleatorio $r_k \in [1, \ldots ,k]$ y realiza una transposición $( \pi [k], \pi [r_k])$ . Por lo tanto, la permutación aleatoria producida puede escribirse como

$$ \pi = ( \pi [n], \pi [r_n])( \pi [n-1], \pi [r_{n-1}]) \cdots ( \pi [k], \pi [r_k]) \cdots ( \pi [2], \pi [r_2]), $$

donde $( \pi [k], \pi [r_k])$ es la transposición o el intercambio de $ \pi [k]$ y $ \pi [r_k]$ .

Implementación en Matlab del Algoritmo de Durstenfeld

function p = GRPdurG(p)
% -------------------------------------------------------------
% Randomly permute the elements of p(1:n) using Durstenfeld's 
% Random Permutation Algorithm, CACM, Vol 7, No. 7, 1964. 
% See Knuth, Section 3.4.2, TAOCP, Vol 2, 3rd Ed.
% Derek O'Connor, 8 Dec 2010.  derekroconnor@eircom.net
%
% USE: n=10^7; p = 1:n; p = GRPdur(p);
% -------------------------------------------------------------
n = length(p);
for k = n:-1:2    
    r = 1+floor(rand*k);    % random integer between 1 and k
    t    = p(k);
    p(k) = p(r);            % Swap(p(r),p(k)).
    p(r) = t;                  
end
%  GRPdurG

Un enigma combinatorio

Una permutación aleatoria de los números enteros $\{1,2, \ldots ,10^7\}$ puede ser generado en unos pocos segundos usando el algoritmo Durstenfeld Shuffle en un PC estándar. El espacio combinatorio $ \mathcal {C}$ en este caso es un conjunto de todas las permutaciones de tamaño $10^7$ . El tamaño de este espacio de muestra es \begin {ecuación*} | \mathcal {C}| = n! = (10^7)! \approx 10^{65,657,059} \end {ecuación*} Este es un número gigantesco y está muy por encima de los límites de cualquier generador de números aleatorios conocido. Es decir, $| \mathcal {C}| \ggg | \mathcal {G}|$ el espacio de estado del generador de números aleatorios. Por ejemplo, el período (tamaño del espacio de estado) del conocido Mersenne Twister RNG (MT) se trata de $10^{6000}$ . Por lo tanto, los generadores de permutaciones aleatorias que usan MT deben perder casi todas las permutaciones en este espacio.

No menos, la función de Matlab de arriba produce permutaciones aleatorias de la longitud $10^7$ en las proporciones estadísticas correctas, por ejemplo, $1/e$ son desquiciados, $1/n$ son ciclos, etc., pero debe perder la mayoría de las permutaciones posibles. De ahí el enigma. La pregunta más importante para mí es:

¿Los generadores de permutaciones aleatorias toman muestras uniformes del espacio de las permutaciones ?

asumiendo que usan el mejor generador de números aleatorios disponible. Sospecho que es un problema matemático difícil.

Mira esta discusión de Matlab: ¿Qué echa de menos RANDPERM?

Nota histórica

Creo que el algoritmo de Durstenfeld fue atribuido incorrectamente a Fisher y Yates por Knuth, en (2) abajo. Vea aquí Nota de O'Connor sobre Fisher-Yates . El algoritmo original de Durstenfeld está aquí: Algoritmo del MCCA

Referencias

  1. Durstenfeld, R. 1964: Algoritmo ACM 235: Permutación aleatoria, Comunicaciones de la ACM Vol 7, No 7.
  2. Knuth, D. 1969, 1998: Algoritmos seminuméricos 1ª y 3ª Edición. El arte de la computación Serie de programación Volumen 2.

4voto

GmonC Puntos 114

Creo que el Artículo de Wikipedia contiene la prueba, pero en cualquier caso es fácil. La prueba de la corrección del algoritmo de Durstenfeld es la misma que para el procedimiento original de Fisher y Yates, por inducción en el número $n$ de elementos a permuta (los casos $n=0$ es trivial). Uno comienza con los artículos en cualquier orden; ya que van a ser permutables al azar, este orden no tiene importancia. Para obtener una permutación aleatoria de $n$ elementos distintos, el primer elemento debe ser elegido uniformemente al azar. Una vez elegido este elemento, los elementos restantes, que podemos ordenar en cualquier orden (y la única diferencia entre Fisher-Yates y Durstenfeld es el orden con el que empezamos para el resto) deben ser permutables uniformemente al azar, lo que se hace aplicando el algoritmo de forma recursiva a la lista de esos elementos restantes.

Alternativamente, se puede mostrar (también por inducción), que llamando al generador de números aleatorios $n$ veces para generar un elemento del producto cartesiano $[n] \times [n-1] \times\cdots\times [1]$ hay una bijección entre las secuencias producidas por el generador y las permutaciones resultantes de la secuencia, así que suponiendo que el producto cartesiano se muestre uniformemente al azar, también se produce la permutación.

La dificultad no es el argumento probabilístico, sino los requisitos impuestos al generador aleatorio. Cuando se produce una permutación aleatoria de un gran número de elementos (digamos $n=10000$ ), es muy probable que el producto cartesiano que se muestre sea simplemente mayor que el espacio de estado del generador aleatorio, lo que significa que un generador dado no puede generar todos $n!$ permutaciones, y mucho menos generarlas uniformemente. Esto no tiene nada que ver con el algoritmo utilizado para producir la permutación. Que esto sea un problema depende de para qué se va a utilizar la permutación. Si es sólo para asegurar alguna mezcla en un procedimiento estadístico creo que no importa si hay ciertas permutaciones que nunca aparecerán; el punto importante aquí es sólo que el subconjunto de permutaciones que puede ser realmente producido pasa cualquier prueba estadística fácilmente ejecutada (como el conteo del número de puntos fijos) de la misma manera que lo haría el conjunto de todas las permutaciones. Sin embargo, si el procedimiento se utiliza para producir un sorteo de una lotería en la que se involucran grandes cantidades de dinero, sería bastante embarazoso si un jugador pudiera probar (tal vez mediante una búsqueda exhaustiva del espacio de estado) que el generador utilizado para dibujar no puede producir la combinación que tiene, ya que para él ya no es un juego de azar, sino un fraude. La pregunta que surge es qué se entiende realmente por "permutación aleatoria".

Así que para responder a la pregunta añadida, es claramente así que:

Cualquier algoritmo de generación de permutaciones basado en un generador de números seudoaleatorios no podrá tomar muestras uniformes del espacio de todas las permutaciones de un tamaño fijo suficientemente grande; por ejemplo, cualquier tamaño tal que el número de permutaciones exceda el del espacio de estado del generador de números seudoaleatorios.

i-Ciencias.com

I-Ciencias es una comunidad de estudiantes y amantes de la ciencia en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X