Está en la página 1de 15

Banner logo

Concurso global �Mujeres con Calle�


Traduce y crea art�culos sobre las mujeres que dan nombre a las calles de nuestros
pueblos, ciudades o provincias y que a�n no est�n en Wikipedia
Puedes participar desde el 1 de marzo hasta el 4 de abril

Contraer
Algoritmo de Fisher-Yates
(Redirigido desde �Algoritmo Fisher-Yates�)
Ir a la navegaci�nIr a la b�squeda
El algoritmo de Fisher-Yates (o alguna variante del mismo), es el que se usa
t�picamente para barajar en los juegos de azar.

Tambi�n es el algoritmo que permite recorrer toda una selecci�n (por ejemplo una
lista musical), de forma aleatoria una sola vez (una reproducci�n por cada elemento
en la lista). Ver m�s detalles en la secci�n m�s abajo.

El algoritmo Fisher-Yates, es un algoritmo de permutaciones que t�cnicamente encaja


en la categor�a de los algoritmos de ordenamiento, aunque en este caso, el fin
perseguido es el opuesto, desordenar los �tems que contiene. Y por tanto deber�a
constar en las bibliotecas de ordenamiento como Random Sort al menos.

�ndice
1 Historia
2 Transcripci�n a la programaci�n
2.1 Descripci�n del algoritmo
2.2 Pseudoc�digo del algoritmo
3 Variantes
3.1 Variante Sattolo
3.2 Variaciones parametrizadas
4 Usos
4.1 Reproducci�n aleatoria de los elementos de una lista
5 Ejemplos paso a paso con comentarios
5.1 Tabla paso a paso (implementaci�n Durstenfeld)
5.2 Tabla paso a paso (implementaci�n Fisher-Yates)
5.3 Tabla paso a paso (implementaci�n Fisher-Yates original)
5.4 Tabla paso a paso (implementaci�n Sattolo)
5.4.1 Resultados de una serie de llamadas consecutivas
6 Test de aleatoriedad sobre las implementaciones
7 V�ase tambi�n
8 Referencias
Historia
El algoritmo Fisher-Yates, aparece por primera vez documentado por Ronald A. Fisher
y Frank Yates, en el libro titulado Statistical tables for biological, agricultural
and medical research.1? si bien su descripci�n era realizada con l�piz y papel.

Posteriormente otros autores (probablemente sin conocimiento previo de dicha


publicaci�n) elaboraron el mismo algoritmo. Lincoln E. Moses y Robert V. Oakford en
Tables of Random Permutations2? y Durstenfeld en CACM-73?(1964), a quienes Knuth
cita en su libro The Art of Computer Programming4? y que describe como "Algoritmo
P" (pags. 139-140 del Vol.2).

En la 'sabidur�a popular' este algoritmo, se conoce como el 'barajado del


sombrero', ya que la descripci�n que Fisher y Yates hicieron de �l, es la que
com�nmente se lleva a cabo cuando se hace una rifa, por ejemplo (ver los detalles
m�s abajo, en la descripci�n del mismo).
Transcripci�n a la programaci�n
Fue Durstenfeld, quien primero hizo una transcripci�n en la forma de algoritmo para
usarse en un ordenador. La descripci�n de Fisher y Yates, exige el uso de 2
matrices (en los trabajos de campo, es simplemente anotar en dos partes de un
papel, aunque bien podr�a reutilizarse borrando y rescribiendo en el mismo sitio),
Durstenfeld usa la propia matriz, para llevar a cabo todo el algoritmo, necesitando
solo como memoria extra una variable temporal.

Descripci�n del algoritmo


La forma m�s simple de entenderlo es partir de la forma popular:

Se escribe cada n�mero en un papelito doblado (construir el array), se introducen


todos los n�meros en un sombrero, se agita el contenido dentro del sombrero (se
barajan), luego se van sacando papelitos que son dispuestos en el mismo orden en
que se sacan, hasta que no quede ninguno. El resultado es la lista barajada.
La descripci�n (grosso modo) que dan Fisher y Yates es la siguiente: Se escribe en
una l�nea los n�meros del orden de la serie de 0 (� 1) hasta el final de la serie
(se supone una serie corta, manejable mediante l�piz y papel) y se dispone debajo
otra l�nea vac�a. Y se hace lo siguiente:
Se elige uno al azar.
Se escribe en otra l�nea (a la derecha de los que ya haya escritos).
Se tacha de la l�nea anterior (el n�mero salido al azar).
Se repiten estos 3 pasos, hasta que solo quede 1, en la l�nea de arriba sin tachar,
entonces se toma directamente y se pasa a la de abajo.

La descripci�n de Durstenfeld, var�a de la de Fisher y Yates, en que al llevarla a


cabo en un programa se trata de ahorrar memoria y por tanto trata de usar el mismo
array, para ello, va intercambiando el valor de la posici�n al azar, y lo remplaza
por el �ltimo del array no remplazado ya. Es decir al iniciar el algoritmo, el
primero elegido se remplaza por el �ltimo, en el siguiente ciclo se elige al azar
entre todos menos el �ltimo, que ahora se remplaza por el pen�ltimo, y de nuevo se
elige otro al azar entre todos menos los dos �ltimos, etc... B�sicamente,
Durstenfeld, escribe el resultado a la izquierda del previo, en tanto que Fisher-
Yates, lo hac�a a la derecha.
Es un error com�n pensar que la aleatoriedad de la lista es dependiente del
algoritmo de barajado (siempre que sea correcto, que para cada posici�n sea elegida
una posici�n al azar), cuando en realidad es dependiente del algoritmo de
aleatoriedad/pseudoaleatoriedad. La lista simplemente es reordenada de otra manera,
siempre contiene los mismos valores, solo cambian sus posiciones, que son
dependientes del algoritmo de aleatoriedad (que no se est� implementando, en ning�n
caso). En cualquier caso, una vez construido el algoritmo, puede o debe probarse su
imparcialidad demostrando las desviaciones de probabilidad.

Pseudoc�digo del algoritmo


�sta es la descripci�n del algoritmo de Durstenfeld. Debe notarse que el elemento
que queda al final del recorrido (�tem-0) como entrada, es el primero en la salida,
raz�n por la que no necesita ser intercambiado de posici�n (es la misma).

Algoritmo BarajadoAleatorio:
Entrada:
Un Array(0,1,2,3,4... Cantidad-1) de valores.
Salida:
El mismo array con sus valores en posiciones aleatorias.
Definici�n de variables:
Cantidad: Un entero que se�ala la cantidad total de �tems que tiene el array.
k: Un entero, que rige la cuenta del bucle.
az: Un entero, elegido por una funci�n Random en el rango 0-k (n�tese que k
se va reduciendo).
tmp: Un entero, que ha de contener un valor para intercambiar valores entre 2
posiciones.
Funciones auxiliares:
Tama�o: Una funci�n que devuelve la cantidad de elementos que contiene el
array.
Random: Una funci�n que devuelve un n�mero aleatorio de un rango de valores.

Cantidad = Tama�o(Array)
Recorrer con k desde Cantidad-1 hasta 1 Regresivamente
az = Random(entre 0 y k)

tmp = Array(az)
Array(az) = Array(k)
Array(k) = tmp
Siguiente
Aunque el coste (en tiempo y memoria) sea mayor, el mismo algoritmo tendr�a el
siguiente pseudoc�digo resuelto con una estructura que permita inserciones y
eliminaciones en posiciones arbitrarias:

Algoritmo BarajadoAleatorio:
Las variables son las mismas del caso anterior, excepto, que en la entrada en
vez de un array,
se recibe una estructura (por ejemplo una colecci�n, una lista enlazada, un
�rbol, etc...)
Recorrer con k desde Cantidad-1 hasta 1 Regresivamente
az = Random(entre 0 y k)

Estruc.A�adirItem(Estruc.Item(az), Al Final)
Estruc.BorrarItem(az)
Siguiente
Es interesante observar en este caso, que los �tems al a�adirlos al final, lo hacen
a la derecha del a�adido anterior, es decir tal como Fisher y Yates describieron.
Si se prefiere, conservar un a�adido a la izquierda del previo a�adido (tal como en
el caso mostrado del array), debe cambiarse la l�nea de a�adido, por la siguiente:

Estruc.A�adirItem(Estruc.Item(az), En Posici�n k)
Puesto que el bucle hace un recorrido regresivo, k vale justo 1 m�s de la posici�n
l�mite pedida a la funci�n Random, y se a�ade justo antes de que sea eliminado el
elemento elegido, por tanto k ir� siendo siempre un valor menor en cada ciclo, por
lo que en efecto se ir�a colocando a la izquierda del previo. Esto se puede ver m�s
claro, en los ejemplos paso a paso, en la secci�n correspondiente (m�s abajo).

Variantes
1 El algoritmo, presenta algunas variantes. De hecho es bastante f�cil que al
tratar de implementar dicho algoritmo se acabe haciendo este otro. Cuya
particularidad m�s destacable, es que siempre que se baraja se elige de nuevo entre
todos los existentes (es como si el sombrero tuviera posiciones donde se coloca
cada uno cuando se meten, y tras barajar el elemento sacado del sombrero se
volviera a introducir de nuevo y se sacaran tantos como elementos hay en el
sombrero y finalmente se expusiera el orden en que los elementos aparecen en el
sombrero):
Recorrer con k desde 0 hasta Cantidad - 1
az = Random(entre 0 y Cantidad-1)

tmp = Array(az)
Array(az) = Array(k)
Array(k) = tmp
Siguiente
2 Tambi�n es posible modificar el algoritmo para solucionar una lista cuya cantidad
de elementos se desconoce (no tiene una cantidad fija, caso t�pico de una
estructura que permite a�adir y eliminar elementos).
3 Tambi�n es posible modificar el algoritmo, de Durnstenfeld, para que opere en el
orden que describe Fisher-Yates (siguiente a la derecha del previo). Es decir, los
valores obtenidos se van colocando en la posici�n m�s baja y creciendo. N�tese que
no hay p�rdida de eficiencia, y n�tese que el recorrido le basta llegar hasta el
pen�ltimo.
Recorrer con k desde 0 hasta Cantidad - 2
az = Random(entre k y Cantidad-1)

tmp = Array(az)
Array(az) = Array(k)
Array(k) = tmp
Siguiente
4 Una variante interesante para determinados juegos, es aquella capaz aun de
generar todas las combinaciones posibles, pero que genere algunas con m�s
frecuencia que otras, pero todav�a de forma aleatoria, es decir que a pesar de ello
no sea predecible. Motivado para permitir un juego que provea jugadas m�s
interesantes y entretenidas con un reparto (de cartas, fichas, etc...) no tan
imparcial (en cuanto a lo que sale, no en cuanto a quien sale). (para acentuar esta
caracter�stica ver la 2� parte de la secci�n variaciones par�metrizadas). El
siguiente pseudoc�digo, obtiene 2 n�meros al azar y ambos se�alan posiciones, que
son las que se intercambian entre s�. Si sucede que la posici�n de origen y destino
es la misma, el intercambio no produce un cambio real. Tambi�n puede suceder que
una o ambas posiciones, hayan salido antes ya. Ambas cosas permiten que la serie no
sea tan diferente entre la entrada y la salida, comparada con las otras
implementaciones. Es f�cil percibir que al no usarse como �ndice el contador del
bucle, sino 2 �ndices elegidos al azar, pueda haber posiciones que en un barajado
no salga y por tanto aumenta la probabilidad de que m�s de 1 elemento mantenga a la
salida, la misma posici�n que ten�a a la entrada. Puede aumentarse notablemente la
eficacia de lo que trata de hacer el algoritmo si el bucle solo recorre la mitad de
los elementos (mitad de posibilidades de que salga cada posici�n). He aqu� el
pseudoc�digo de esta variante:
Fin = (Tama�o(Array) \ 2) - 1
Recorrer con k desde 0 hasta Fin <--- Solo recorre la mitad.
az1 = Random(entre 0 y Cantidad-1)
az2 = Random(entre 0 y Cantidad-1)

tmp = Array(az1) <---- 'k' no se refiere nunca a la posici�n de un


elemento en el
Array(az1) = Array(az2) <--- array de esta variante, como sucede en el resto
de variantes.
Array(az2) = tmp
Siguiente
5 Hay aun una forma diferente de concebir el algoritmo de barajado, que ya no se
ajusta al art�culo, pero que aun resulta de inter�s presentar aqu�. Sea una
estructura en la que las permutaciones est�n ya precalculadas y almacenadas y se
usa una funci�n random para elegir (el �ndice) cual de las permutaciones en la
estructura es la que se entrega. Esta variante, sin embargo queda en la pr�ctica
limitada a series cuya cantidad de elementos sean relativamente peque�o, dado el
espacio de memoria que consume almacenar todas la serie de permutaciones posibles.
Aunque cuando la velocidad es fundamental esta soluci�n resulta la m�s apta. Es
ideal que una vez halladas las permutaciones diferentes estas sean barajadas (para
que no consten el orden creciente en que posiblemente las devuelva la funci�n) y
que se haga lo mismo cada cierto n�mero de entregas.
Variables nuevas:
Series: Es una estructura acorde para contener arrays donde cada array mantiene
una
permutaci�n distinta de la serie (un �rbol de arrays, otro array de
arrays, etc...).
Veces: Es un contador, para barajar el orden de los arrays en la estructura
series,
cada vez que alcanza cierto valor, para favorecer la aleatoriedad.
X: Un valor l�mite que controla el l�mite de veces. Este valor es dependiente
de la cantidad de permutaciones
Funciones accesorias
Permutaciones: Ser�a una funci�n de combinatoria, que devuelve una estructura de
arrays,
con todas las series posibles, donde cada array contiene una serie
distinta.
Barajar: Es un algoritmo de barajado aleatorio (como los descritos), con la
particularidad
de que cambiar�a los punteros de los �ndices del array, en vez del
contenido.
--- Series Es precalculada, (y de nuevo cada vez que cambiare la cantidad de
elementos).
Series = Permutaciones(Cantidad)
Funci�n: BarajarAleatorio
veces = veces + 1
si veces = x entonces <--- 'x' es un valor que se estalece en funci�n
de la cantidad de elementos del array.
Barajar(Series)
veces = 0
Fin si
az = Random(entre 0 y Cantidad-1)
Array = Series(az)
Devolver Array
Fin funci�n
6 Otra interesante variaci�n es el algoritmo de Sattolo. Merece ser descrito m�s
ampliamente, en la siguiente secci�n.
Variante Sattolo
Fue publicado en 1986 en IPL-22,5? por Sattolo en Information Processing Letters6?
y tiene algunas particularidades que se describen:

Hace el barajado, con la garant�a de que cada elemento no ocupe la posici�n (a la


salida) que ocupaba inicialmente (a la entrada). Para ello se recurre a condicionar
la b�squeda aleatoria del elemento al rango de un elemento por debajo de la
posici�n actual, del que se va a remplazar. Esta es la particularidad interesante
de este algoritmo, pero no la �nica.
Las permutaciones que realiza una y otra vez, acaban siendo c�clicas (se repiten),
aunque no sigan un orden espec�fico, si pueden presentarse secuencias ya
aparecidas.
Hay permutaciones que jam�s pueden ocurrir, en series impares (en dichas series
solo alcanza a la mitad de las permutaciones, si la serie entra ordenada y se
ejecutan el n�mero suficiente de veces). Por ello no es un algoritmo imparcial y
debe evitarse su uso en juegos de apuestas (habr�a la mitad de combinaciones sin
ninguna posibilidad real y la otra mitad de combinaciones con el doble de
posibilidades), salvo que se tomen las debidas precauciones y sea estrictamente
necesario que ning�n elemento repita su posici�n a la salida respecto de la
entrada, y siempre que se tenga un conocimiento expreso y exahustivo de los
resultados que puede ofrecer. El modo de prevenir dicho problema es garantizar que
siempre se usan listas de cantidad pares, a�adiendo cuando sean impares un �ltimo
elemento (que se deseche en uso).
�ste, es otro caso de algoritmo, que por error se puede llegar a implementar al
tratar de implementar el de Durstenfeld, ya que la diferencia entra ambas
implementaciones es m�nima.
Recorrer con k desde Cantidad-1 hasta 1 Regresivamente
az = Random(entre 0 y k-1) <--- EL CAMBIO: k-1, en vez de k (es la diferencia
con Durstenfeld)

tmp = Array(az)
Array(az) = Array(k)
Array(k) = tmp
Siguiente
Ya que el algoritmo para conjuntos cuya cantidad de elementos es impar evita la
mitad de combinaciones, puede interesar reproducir en alg�n momento otras
permutaciones. El modo de lograr otras combinaciones (entre el resto de
combinaciones), consiste en solicitar, un nuevo barajado para todo el conjunto
menos 1 (� varios) elemento (por ejemplo el �ltimo o el primero), el cual mantiene
su posici�n. Es decir, hay que generar una combinaci�n nueva que mantenega al menos
1 elemento en la misma posici�n que antes. Para ello habr�a que generar el c�digo
dedicado al algoritmo (haci�ndole creer que tiene un elemento menos, tal como se
expresaba en una de las variantes previas). Se consigue as� generar diversas series
c�clicas (pero no se garantiza que sean todo el resto), dependiendo de cual o
cuales sean los valores que se omitan en el barajado, el ciclo de la serie ser� m�s
largo o m�s corto. El siguiente pseudocodigo se encarga precisamente de eso.
Cantidad = Tama�o(Array)
Si se pide OmitirUno entonces
Cantidad = Cantidad - 1
Fin si
Recorrer con k desde Cantidad-1 hasta 1 Regresivamente
az = Random(entre 0 y k-1)
tmp = Array(az)
Array(az) = Array(k)
Array(k) = tmp
Siguiente

Que se invocar�a con la siguiente llamada:


Llamada a la funci�n BarajarAleatorio(Array, Sattolo, OmitirUno)
Variaciones parametrizadas
Hay algunas variaciones que pueden ser aplicadas a todas las implementaciones
comentadas hasta el momento, bien que pueda variar el c�digo exacto que deba
a�adirse o modificarse en cada una. Implementar estas variaciones, implica a�adir
par�metros en las funciones para que al invocarlas puede elegirse el valor
necesario para que cumpla la misi�n encomendada.

Una variaci�n aplicable a todas las implementaciones, consiste en hacer un barajado


dejando 1 elemento de ellos (o varios, seguidos) sin barajar, es decir quedando en
la misma posici�n. El modo m�s sencillo de llevarlo a efecto es mentir al algoritmo
en cuesti�n haci�ndole creer que tiene un elemento menos, as� baraja todos (los que
el algoritmo en cuesti�n baraje) menos uno (o esos varios). Tal circunstancia puede
reclamarse en un par�metro opcional en la llamada a la funci�n. He aqu� el
pseudoc�digo que se podr�a a�adir a cualquiera de ellos, detr�s se pone la
implementaci�n de Durstenfeld, para apreciar lo que implica (m�s arriba en Sattolo,
se detalla un caso, que hace uso de esta variaci�n, para generar series c�clicas
pero diferente a la previa).
Cantidad = Tama�o(Array)
Si se pide OmitirUno entonces <--- OmitirUno ser�a aqu� un par�metro opcional de
tipo buleano
Cantidad = Cantidad - 1
Fin si
Recorrer con k desde Cantidad-1 hasta 1 Regresivamente
az = Random(entre 0 y k)
tmp = Array(az)
Array(az) = Array(k)
Array(k) = tmp
Siguiente
La invocaci�n a una funci�n que implementa esta variaci�n en el algoritmo ser�a:
Llamada a la funci�n BarajarAleatorio(Array, Durstenfeld, OmitirUno)
Tal y como se comentaba en la variante numerada como 4 (m�s arriba), a menudo hay
juegos donde es regla del mismo (establecida as� en las reglas o acordado entre los
propios jugadores) que el barajado no sea excesivo (suelen ser juegos de
entretenimiento y no tanto de apuestas por el posible riesgo que entra�a), para
permitir un juego m�s interesante y entretenido (por ejemplo un juego como el tute
'cabr�n' acepta muy bien esta situaci�n). Puede entenderse como al tiempo que los
jugadores con peores cartas o fichas, finalizan antes su juego, sus cartas quedan
acumuladas juntas, al tiempo quedan en la partida los jugadores con m�s triunfos,
que al final de la partida quedan tambi�n amontonadas sus cartas, con lo que en la
baraja, quedan reunidos los triunfos por un lado y las cartas sin valor por otro,
de modo que al barajar escasamente los triunfos puedan a�n estar algo acumulados y
que el reparto de cartas en una nueva partida, provea cartas significativas a un
jugador u otro. A veces para garantizar que esto mismo no se enturbia, se procede a
repartir varias cartas seguidas a cada jugador, en vez de repartir a cada jugador
una carta cada vez. Ambas cosas favorecen que una partida produzca jugadas m�s
interesantes (el algoritmo de dicha variante se halla m�s arriba como variante 4).
Podemos pedir a un algoritmo que cada x elementos del recorrido, omita y barajados
(es el pseudoc�digo que se presenta a continuaci�n). En este sentido, puede
proveerse una variaci�n a los algoritmos proporcionados para favorecer ese escaso
barajado, en esta ocasi�n, tomamos la variante que mejor conjunta con esta causa:
Entrada:
Un Array(0,1,2,3,4... Cantidad-1) de valores.
Grupo: un entero que se�ala cada cuantos se evita un barajado.
Salto: un entero que indica cuantos seguidos quedan sin barajar.

Cantidad = Tama�o(Array)
Fin = (Cantidad \ 2) - 1
Recorrer con k desde 0 hasta Fin <--- Solo recorre la mitad.
Si k es congruente con Grupo entonces ---> congruente con, refiere a la
operaci�n m�dulo
(que se traduce como: si ((k mod grupo) = 0) luego
k = k + salto
En otro caso
az1 = Random(entre 0 y Cantidad-1)
az2 = Random(entre 0 y Cantidad-1)
tmp = Array(az1)
Array(az1) = Array(az2) <---- 'k' no se refiere nunca a la posici�n de un
elemento en el array de esta variante.
Array(az2) = tmp
Fin si
Siguiente
La invocaci�n a una funci�n que implementa esta variaci�n en el algoritmo ser�a:
Llamada a la funci�n BarajarAleatorio(Array, Semibarajado, Grupo=13, Salto=3)

Supongamos una baraja de 52 cartas y supongamos que queremos que cada 13 cartas que
baraje, se salte 3. Siendo el array de 0 a 51 elementos, en las posiciones k m�dulo
13 (que son 0, 13, 26 y 39) al llegar a dichas posiciones aumentar� k en 3
unidades, que en efecto tiene como consecuencia no barajar 3 elementos seguidos,
como son 4 veces (4 grupos de 13) hay 12 barajados menos. Tambi�n pueden
especificarse los par�metros como los que se omiten y los que se barajan (en el
ejemplo, ser�an Barajan=10 y se Omiten=3) y la suma de ambos ser�a el equivalente
al grupo, as� se evita la necesidad de comprobar que salto sea menor que grupo.

Debe notarse que esta variaci�n no evita que los valores en esas posiciones se
mantenga en su mismo sitio (pueden salir elegidas por la funci�n Random en
cualquier otro instante del recorrido del bucle), pero si tiene por efecto, que 12
elementos de los 52 no sean barajados, lo que por supuesto tendr� incidencia, en
una cierta similitud entre la serie a la salida y la serie de entrada.

Todas las implementaciones, puede ser tambi�n f�cilmente modificadas para hacer el
barajado, solo con un subconjunto del rango del array (no a todos), se�alando un
par�metro de inicio del elemento que se empieza a barajar y otro de la cantidad de
elementos afectados. Esto (tambi�n) puede aplicarse a listas extremadamente largas
donde la ocupaci�n de la memoria pueda ser cr�tica, o el tiempo necesario para
disponer, de todo el array barajado, no es aceptable. Dicha modificaci�n puede
solucionar el problema. Es imaginable un array de mil millones de elementos, donde
solo se modifica 1 mill�n de elementos consecutivos cada vez, e incluso una
modificaci�n donde se modifica 1 mill�n de elementos a una distancia de 1000
elementos entre uno y otro(el 1, el 1001, 2001, 3001, 4001.... 1001001), cada
vez...
Todav�a todas las implementaciones, admiten a�n otra parametrizaci�n para hacer un
barajado por bloques (lo que com�nmente en los juegos de cartas se llama cortar),
que intercambia bloques de cartas y donde los elementos individuales en cada bloque
mantiene su posici�n. En las cartas, al ser barajadas a mano, cada bloque tiene un
tama�o indeterminado e independiente del otro. Hay dos formas t�picas de cortar:
Cortar en 2 montones (de diferente tama�o) con las manos, uno se pone encima del
que antes estaba arriba y se repite el proceso varias veces. Otras veces, sobre el
tapete se reparten peque�os montones (de cantidades desiguales por lo general, ya
que se hace a mano) y se recogen de la mesa en orden diferente al que se ha
repartido. B�sicamente este es el pseudoc�digo que se expone a continuaci�n con la
salvedad de que se especifica un tama�o de bloque que se ajusta para todos excepto
(quiz�s) el �ltimo mont�n. La funci�n recibir�a un par�metro se�alando el tama�o
del bloque a considerar.
Funci�n BarajadoAleatorio M�todo BarajadoEnBloques
Cantidad = Tama�o(Array)
Grupos = Cantidad \ Bloque <--- es una divisi�n entera, desprecia decimales.
Si (Cantidad m�dulo Bloque) es mayor que 0 entonces sumar 1 a Grupos

En la posibilidad de que el �ltimo grupo no est� completo se intercambia aparte.


Es decir intercambiamos primero el �ltimo bloque por el que bloque elegido al
azar.
Az = Random(entre 0 y Grupos-1)
Si Az es distinto de' Grupos-1 entonces <--- si el grupo al azar es el �ltimo,
no hace falta
intercambiarlo.
p = Az * Bloque
Recorrer con k desde (Grupos-1)*bloque hasta Cantidad-1
tmp = Array(p)
Array(p) = Array(k)
Array(k) = tmp
p = p + 1
Siguiente
Fin si

----> aqu� va el inserto que se se�ala unos p�rrafos m�s abajo <---

Grupos = Grupos - 1
Recorrer con J desde (Grupos - 1) hasta 1 Regresivamente
Az = Random(entre 0 y J)
Si Az es distinto de' J entonces <--- si el grupo al azar es el mismo del
bucle, no hace falta
intercambiarlo.
p = Az * Bloque
n = Az * Bloque
Recorrer con k desde n hasta n + Bloque - 1
tmp = Array(p)
Array(p) = Array(k)
Array(k) = tmp
p = p + 1
Siguiente
Fin si
Siguiente
Y la invocaci�n a la funci�n ser�a as�:
Llamada a la funci�n BarajarAleatorio(Array, BarajadoEnBloques, Bloque=4)
Imag�nese un mazo de 28 cartas, y bloques de 4 cartas, lo que nos dar�a 7 montones
y ser�a equivalente a barajar una serie de 7 elementos (7 * 4 = 28), si los
montones fueran de 6 cartas el �ltimo mont�n solo tendr�a 4 cartas, luego cuando
saliera �ste solo se intercambiar�an 4 cartas con el bloque que se intercambia. Se
pone una serie de resultados de 28 elementos, con un bloque de 4, para darse cuenta
como el afecta a un barajado de esta manera. Obs�rveses como las tuplas de 4
elementos (se ha coloreado un par de ellas), no cambian entre s� el orden (de sus
elementos):

00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
27
24 25 26 27 20 21 22 23 00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18
19
16 17 18 19 00 01 02 03 20 21 22 23 24 25 26 27 04 05 06 07 08 09 10 11 12 13 14
15
00 01 02 03 24 25 26 27 12 13 14 15 16 17 18 19 04 05 06 07 08 09 10 11 20 21 22
23
04 05 06 07 16 17 18 19 20 21 22 23 24 25 26 27 12 13 14 15 00 01 02 03 08 09 10
11
Si el bloque produce grupos exactos entonces no generar� todas las permutaciones
posibles, de hecho ni aunque haya bloques no exactos, no generar� todas las
permutaciones posibles. Por ejemplo para una serie de 7 elementos (que permite 5040
permutaciones distintas de la serie) con un bloque de 2 genera 144 permutaciones,
con un bloque de 3 genera s�lo 12 permutaciones, con un bloque de 4, 5 y 6 solo hay
2 permutaciones posibles (ya que solo ofrece 2 grupos). Por ello hay que considerar
que el n�mero de permutaciones obedece m�s al n�mero de grupos y los elementos en
el �ltimo grupo, que a la cantidad de elementos. Por �ltimo, se�alar que si el
tama�o de bloque es 1, equivale a barajar todos los �tems, cual si no se usara
dicha funcionalidad. Hay que considerar que la entrada y la salida var�an poco
entre s�, pero dado que tras la salida hay un nuevo juego, la siguiente entrada
tendr� una permutaci�n muy distinta de la salida previa. Si el caso es que se desea
que haya una mayor posibilidad de permutaciones, podr�a barajarse el �ltimo bloque
(que antes estaba en otra posici�n y se intercambi� con el �ltimo), de modo que en
sucesivas veces cuando sea cambiado por el bloque en otra posici�n, ir� generando
una mayor cantidad de permutaciones aunque var�en poco de una a otra en el tiempo.
Esto puede ir especificado con otro par�metro o quedar fijo en la variaci�n del
algoritmo. El pseudoc�digo ser�a el siguiente y se colocar�a justos donde aparece
esta l�nea:

----> aqu� va el inserto que se se�ala unos p�rrafos m�s abajo <---
' Barajar los elementos internos del que ahora es el �ltimo bloque.
Min = ((Grupos - 1) * Bloque)
Recorrer con k desde Cantidad - 1 hasta Min Regresivamente <---- el barajado es
m�todo Durstenfeld,
en este ejemplo, pero
podr�a ser otro
Az = Random(entre Min y k) <---- Min: limita el rango inferior en vez de 0
tmp = Array(k)
Array(k) = Array(Az)
Array(Az) = tmp
Siguiente
F�jese en las siguientes salidas como es barajado siempre el bloque que se
intercambi� a la �ltima posici�n y como desde entonces ese bloque se traslada as�
(con ese nuevo orden entre sus elementos) a la siguiente entrada (sin cambios tras
la salida). Para estudiar el caso, aqu� la salida de una serie es la entrada de la
siguiente, caso que se supone que no ser� cierto una vez se traslade a una
aplicaci�n real (que tras un barajado habr� un juego tal que acaben sus elementos
en otro orden). Se marca en azul el bloque que ser� el �ltimo en la siguiente
etapa, y se observa de rojo ese bloque en la siguiente fase, posicionado el �ltimo
y ya barajado. Ese bloque as� barajado mantiene su nuevo orden (interno) en lo
sucesivo.

00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
27 <---entrada
04 05 06 07 20 21 22 23 08 09 10 11 24 25 26 27 12 13 14 15 00 01 02 03 19 16 17
18
19 16 17 18 04 05 06 07 24 25 26 27 08 09 10 11 20 21 22 23 00 01 02 03 14 15 13
12
04 05 06 07 24 25 26 27 20 21 22 23 19 16 17 18 14 15 13 12 08 09 10 11 02 01 00
03
02 01 00 03 14 15 13 12 08 09 10 11 20 21 22 23 19 17 16 18 07 04 07 05 26 25 24
27
14 15 12 13 02 08 09 10 11 01 00 03 19 17 16 18 07 04 07 05 20 21 22 23 25 27 24
26 <--- el �ltimo
bloque se intercambia consigo
mismo esta vez.
Como se puede apreciar, esta variaci�n tambi�n permite generar permutaciones aptas
para cuando se desea generar jugadas interesantes y entretenidas en juegos que lo
necesitan, y en cambio no es aceptable en juegos con apuestas.

Usos
Como ya se ha dicho en el encabezado del art�culo, es el algoritmo que se usa
t�picamente para barajar en los juegos de azar (o alguna de sus variantes).

Se usa tambi�n en los modelos estad�sticos cuando se requiere simular un origen de


datos aleatorio. Un caso pr�ctico, para probar la eficiencia de los algoritmos de
ordenamiento. hacer simulaciones del clima, etc...

Tambi�n se usa en sistemas y programas donde se desea usar una sola vez cada
elemento de la serie pero de una forma aleatoria, sin recurrir a una estructura
adicional de almacenamiento. Se provee un ejemplo al detalle, sobre las listas de
reproducci�n de canciones.

Reproducci�n aleatoria de los elementos de una lista


El presente algoritmo, resuelve tambi�n este caso, sin la necesidad de recurrir a
una segunda estructura donde mover los elementos retirados de la primera.

Imaginemos el caso m�s corriente, una lista de canciones de la que se desea


reproducir cada canci�n una sola vez, pero que lo hagan en orden aleatorio.
Inicialmente se tendr� una lista con las rutas de las canciones, lista que conviene
dejar intacta (no intercambiar sus elementos). Se usa un array cuyo contenido
(inicialmente) son los �ndices de las canciones en la lista. Si el orden es
aleatorio, se manda barajar el array, si el orden solicitado es el original, se
reasigna a cada �ndice el valor del �ndice de la lista (el orden natural
correlativo). La reproducci�n finalmente usar� como �ndice, el valor de dicho
array. En vez de invocar: Reproducir(Ruta(k)), se invocar�:
Reproducir(Ruta(Array(k))), as� la lista original, no necesita ser tocada ni
duplicada para mantener el orden original (es m�s r�pido en memoria asignar valores
num�ricos, que textos).
Si la lista se desea reproducir en la forma original,
Necesitamos recrear el orden original:
Recorrer con k desde 0 hasta Cantidad-1
Array(k) = k
Siguiente
Llamada a la funci�n ReproducirLista
Si la lista se desea reproducir en forma aleatoria,
Desordenamos el array con el algoritmo:
Llamada a la funci�n BarajarAleatorio(Array)
Llamada a la funci�n ReproducirLista
Y la funci�n ReproducirLista ser�a esta.
Recorrer con k desde 0 hasta Cantidad-1
Reproducir(Ruta(Array(k)))
Siguiente
Ejemplos paso a paso con comentarios
Se ir�n exponiendo ejemplos paso a paso de las implementaciones m�s relevantes,
sobre una serie de 7 elementos, en tablas con columnas, cuyo significado son:

Ciclo: identifica a la variable que controla el bucle, cuando es descendente ir� de


6 a 0 cuando sea creciente ir� de 0 a 6. Su valor se colorea de rojo
Rango: Rango de posiciones elegible en cada instante.
Azar: La posici�n que ha salido al azar. Su valor se colorea de azul
Antes: El orden que mantiene la serie antes de aplicar la operaci�n actual.
Despu�s: El orden que mantiene la serie tras aplicar la operaci�n.
Resultado: Alguna tabla muestra una columna adicional, para m�s claridad. Su valor
se colorea de rojo.
Otros detalles:
En la tabla que corresponda, se separa la serie con :, para mayor claridad.
Aquellos campos que no precisen ser rellenados se se�alan con -.
Las tablas se completan visualmente, hasta su t�rmino (aun cuando no necesite un
ciclo final), para acabar de verlo claro.
Cuando ambas posiciones (columnas ciclo y azar) se refieran a la misma, el valor se
colorea de p�rpura.
El contenido del campo Despu�s de un ciclo, es el campo Antes del siguiente ciclo,
que se repite para mejor seguimiento.
Tabla paso a paso (implementaci�n Durstenfeld)
Para el algoritmo descrito en el pseudoc�digo (Durstenfeld). N�tese las siguientes
cuestiones para este ejemplo:

Los intercambios son entre valores de las posiciones ciclo y azar.


N�tese especialmente como los valores van coloc�ndose a la derecha del separador :
que se ha puesto para mejor visibilidad.
Hay que fijarse tambi�n, que aunque han salido 3 veces al azar la posici�n 0, ello
no tiene influencia significativa en el resultado, ya que se refiere a una posici�n
y cada vez ser� intercambiado por un valor en una posici�n distinta.
El ciclo 2, tanto la posici�n de ciclo, como la de azar refieren a la posici�n 2,
luego el valor se intercambia con s� mismo.
En esta implementaci�n, no es preciso hacer el ciclo 0 (no hay necesidad de barajar
si solo hay 1 elemento entre los que escoger), por tanto se queda el valor que yace
en ese momento en dicha posici�n y se ahorra un ciclo en el bucle.
Ciclo Rango Azar Antes Despu�s
0 1 2 3 4 5 6 : 0 1 2 3 4 5 6 :
6 0-6 4 0 1 2 3 4 5 6 : 0 1 2 3 6 5 :4
5 0-5 0 0 1 2 3 6 5 : 4 5 1 2 3 6 : 0 4
4 0-4 0 5 1 2 3 6 : 0 4 6 1 2 3 : 5 0 4
3 0-3 2 6 1 2 3 : 5 0 4 6 1 3 : 2 5 0 4
2 0-2 2 6 1 3 : 2 5 0 4 6 1 : 3 2 5 0 4
1 0-1 0 6 1 : 3 2 5 0 4 1 : 6 3 2 5 0 4
- 0-0 - 1 : 6 3 2 5 0 4 1 6 3 2 5 0 4 :
Tabla paso a paso (implementaci�n Fisher-Yates)
Para el algoritmo descrito en el pseudoc�digo como variante de la implementaci�n de
Durstenfeld, posicionando los elementos a la derecha del previo, tal como
describieron Fisher-Yates. N�tese las siguientes cuestiones para este ejemplo:

Las posiciones al azar, no pueden ser iguales que en el ejemplo previo, ya que a
medida que aumenten los ciclos, no pueden salir los valores de ciclos ya pasados.
El intercambio siempre se har� entre el valor de la posicio�n elegida al azar y el
primero de la serie que entra en juego. Se ha puesto como separador :, para
apreciar donde empieza los que entran en juego.
El resultado va quedando a la derecha de la serie (ver en el encabezado los : a la
derecha de la serie en juego.
Ciclo Rango Azar Antes Despu�s
: 0 1 2 3 4 5 6 : 0 1 2 3 4 5 6
0 0-6 5 : 0 1 2 3 4 5 6 5 : 1 2 3 4 0 6
1 1-6 3 5 : 1 2 3 4 0 6 5 3 : 2 1 4 0 6
2 2-6 6 5 3 : 2 1 4 0 6 5 3 6 : 1 4 0 2
3 3-6 4 5 3 6 : 1 4 0 2 5 3 6 4 : 1 0 2
4 4-6 5 5 3 6 4 : 1 0 2 5 3 6 4 0 : 1 2
5 5-6 6 5 3 6 4 0 : 1 2 5 3 6 4 0 2 : 1
- 6-6 - 5 3 6 4 0 2 : 1 5 3 6 4 0 2 1 :
Tabla paso a paso (implementaci�n Fisher-Yates original)
Para la descripci�n del algoritmo original, empleando para ello, l�piz y papel, es
decir tachando de la lista en una l�nea y escribiendo los resultados en una nueva
l�nea, que ser� la lista resultante. Esto supone simular 2 estructuras, una que
contiene la lista original de la que se extraen y otra donde se insertan. N�tese
las siguientes cuestiones para este ejemplo:

Se emplean los mismos valores de resultado que para el ejemplo anterior, lo que
fuerza a elegir otros valores de azar, para que coincidan ambos resultados.
Aparte de diferenciarse en la representaci�n respecto del anterior y en los valores
de la columna Azar, tambi�n cambian los valores de la columna rango, pues se sigue
el esquema de sacar del sombrero, por lo que en cada ciclo, contiene uno menos
entre los que elegir.
Fijarse en como el valor en la posici�n libre que se�ala azar, se tacha en la lista
despu�s y pasa al resultado.
Los �tems tachados, no se cuentan ya al indizar la lista (no existen, en la tabla
se dejan, para poder comparar los cambios).
Ciclo Rango Azar Antes Despu�s Resultado
0 1 2 3 4 5 6 0 1 2 3 4 5 6 0 1 2 3 4 5 6
0 0-6 5 0 1 2 3 4 5 6 0 1 2 3 4 5 6 5
1 0-5 3 0 1 2 3 4 5 6 0 1 2 3 4 5 6 5 3
2 0-4 4 0 1 2 3 4 5 6 0 1 2 3 4 5 6 5 3 6
3 0-3 3 0 1 2 3 4 5 6 0 1 2 3 4 5 6 5 3 6 4
4 0-2 0 0 1 2 3 4 5 6 0 1 2 3 4 5 6 5 3 6 4 0
5 0-1 1 0 1 2 3 4 5 6 0 1 2 3 4 5 6 5 3 6 4 0 2
6 0-0 - 0 1 2 3 4 5 6 0 1 2 3 4 5 6 5 3 6 4 0 2 1
Tabla paso a paso (implementaci�n Sattolo)
Para la descripci�n del algoritmo Sattolo, variante de Durstenfeld. N�tese las
siguientes cuestiones para este ejemplo:

No puede emplearse los mismos valores (columna Azar) que en aquella tabla, ya que
el rango de posiciones elegible es en cada ciclo uno menor que all� (ver columna
rango).
N�tese la gran diferencia con durstenfeld, la columna rango se ve reducida a un
�tem menos entre los que elegir al azar, respecto de la columna ciclo.
Dado que lo interesante de esta implementaci�n es la capacidad del algoritmo para
no repetir valores en la posici�n inicial, operar con 7 elementos, no ser�a
suficiente para verlo claramente, por ello se ampl�a la lista a 10 elementos.
N�tese como el valor de la columna Azar, nunca iguala el valor de la columna Ciclo
(ver en pseudoc�digo el condicionante del rango en la funci�n Random: Azar =
Random(entre 0 y k-1))
Ciclo Rango Azar Antes Despu�s
0 1 2 3 4 5 6 7 8 9 : 0 1 2 3 4 5 6 7 8 9 :
9 0-8 6 0 1 2 3 4 5 6 7 8 9 : 0 1 2 3 4 5 9 7 8 : 6
8 0-7 4 0 1 2 3 4 5 9 7 8 : 6 0 1 2 3 8 5 9 7 : 4 6
7 0-6 4 0 1 2 3 8 5 9 7 : 4 6 0 1 2 3 7 5 9 : 8 4 6
6 0-5 1 0 1 2 3 7 5 9 : 8 4 6 0 9 2 3 7 5 : 1 8 4 6
5 0-4 1 0 9 2 3 7 5 : 1 8 4 6 0 5 2 3 7 : 9 1 8 4 6
4 0-3 3 0 5 2 3 7 : 9 1 8 4 6 0 5 2 7 : 3 9 1 8 4 6
3 0-2 0 0 5 2 7 : 3 9 1 8 4 6 7 5 2 : 0 3 9 1 8 4 6
2 0-1 1 7 5 2 : 0 3 9 1 8 4 6 7 2 : 5 0 3 9 1 8 4 6
1 0-0 0 7 2 : 5 0 3 9 1 8 4 6 2 : 7 5 0 3 9 1 8 4 6
- - - 2 : 5 0 3 9 1 8 4 6 : 2 7 5 0 3 9 1 8 4 6
Resultados de una serie de llamadas consecutivas
En la siguiente tabla se muestran los resultados de una serie de llamadas a la
funci�n, para apreciar como en efecto, no se repiten (observar verticalmente la
columna resultados, nunca un elemento en la misma posici�n en la siguiente
llamada).

Para esta tabla se han realizado 12 llamadas y se prescindido de los pasos internos
de la funci�n. Y para la ocasi�n se ponen las columnas siguientes:
Llamada: El �ndice indica la en�sima llamada a la funci�n BarajadoAleatorio para la
implementaci�n de Sattolo.
Azar: Contiene la lista de posiciones aleatorias obtenida (internamente) en esa
llamada (por si desea recrearse manualmente siguiendo el esquema de la tabla
previa).
Entrada y Salida: Son columnas que muestran la lista a la entrada y la salida de la
funci�n. La lista de la columna Salida de una llamada a la funci�n, es la misma
lista que se consigna en la columna Entrada de la siguiente llamada.
N�tese como en la columna Azar, verticalmente siempre los valores que salieron son
menores, que el n�mero que indica el encabezado (se ha coloreado toda la sub-
columna encabezada por el 8 de color rojo, para apreciarse mejor, pero se aplica a
todas ellas). La posici�n horizontal en dicha columna Azar, indica el valor
obtenido por la funci�n Random en cada ciclo interno del bucle, dado el rango en el
que se ve obligado a elegir).
Apr�ciese, como en la columna Salida, ning�n valor se repite en la misma posici�n
que ten�a en la llamada anterior (se ha coloreado de azul verticalmente, la sub-
columna 6�, para dirigir mejor la vista, pero se aplica a todas ellas)). Una tabla
similar con cualquiera de las otra implementaciones arrojar�a muchas coincidencias.
Llamada Azar Entrada Salida
9 8 7 6 5 4 3 2 1 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9
1 6 4 4 1 1 3 0 1 0 0 1 2 3 4 5 6 7 8 9 2 7 5 0 3 9 1 8 4 6
2 0 3 6 4 1 3 2 0 0 2 7 5 0 3 9 1 8 4 6 9 8 6 5 4 7 3 1 0 2
3 4 6 0 3 2 1 1 1 0 9 8 6 5 4 7 3 1 0 2 7 1 0 2 8 6 5 9 3 4
4 7 6 4 5 4 0 2 1 0 7 1 0 2 8 6 5 9 3 4 2 3 1 0 7 4 6 8 5 9
4 0 7 4 0 2 0 0 1 0 2 3 1 0 7 4 6 8 5 9 4 0 3 5 6 1 9 7 8 2
6 2 3 2 5 4 1 0 0 0 4 0 3 5 6 1 9 7 8 2 9 7 8 4 0 6 1 2 5 3
7 3 3 4 1 3 0 0 1 0 9 7 8 4 0 6 1 2 5 3 8 6 1 2 9 5 7 0 3 4
8 8 2 5 2 1 3 1 1 0 8 6 1 2 9 5 7 0 3 4 7 8 9 0 2 6 4 5 1 3
9 5 5 6 5 0 2 2 0 0 7 8 9 0 2 6 4 5 1 3 8 0 5 2 9 7 1 4 3 6
10 4 3 2 2 1 0 0 1 0 8 0 5 2 9 7 1 4 3 6 1 3 7 6 8 0 4 5 2 9
11 3 3 1 2 1 2 1 0 0 1 3 7 6 8 0 4 5 2 9 2 8 1 0 4 5 7 3 9 6
12 4 3 0 4 2 3 1 1 0 2 8 1 0 4 5 7 3 9 6 5 3 7 8 9 1 6 2 0 4
Test de aleatoriedad sobre las implementaciones
V�ase tambi�n
Aleatoriedad
Entrop�a (informaci�n)
N�mero aleatorio
Pruebas de aleatoriedad
Secuencia pseudoaleatoria
Teor�a de probabilidad
Variable aleatoria
Referencias
Fisher, Ronald A.; Yates, Frank (1948) [1938]. Statistical tables for biological,
agricultural and medical research (3rd edici�n). Londres: Oliver & Boyd. pp. 26-27.
OCLC 14222135. Nota: la 6� edici�n, ISBN 0-02-844720-4, es disponible a trav�s de
la red, pero ofrece un algortmo de barajado algo diferente, por [[Calyampudi
Radhakrishna Rao |C. R. Rao]].
Moses, Lincoln E.; Oakford, Robert V. (1963) [1963]. Tables of Random Permutations
(1� edici�n). Stanford (California): Stanford University Press. pp. ???. ISBN 0-
8047-0148-2.
doi 10.1145/364520.364540
Knuth, Donald Erwin (1969 (1981 2�ed.)). Seminumerical algorithms. The Art of
Computer Programming 2. Reading, MA: Addison�Wesley. pp. 124-125 (139-140 en 2�
ed.). ISBN 0-201-03822-6.
doi 10.1016/0020-0190(86)90073-6
Sandra Sattolo (25 de junio de 1985). �An algorithm to generate a random cyclic
permutation� [Un algoritmo para generar una permutaci�n c�clica aleatoria]. En
Elsevier B.V., ed. Istituto di Matematica, Facolta' di Scienze Matematiche e
Fisiche, Universita' degli Studi di Udine, via P. Mantica, 33100 Udine, Italy.
Information Processing Letters (30-mayo-1986) 22 (6): 315-317. [El prop�sito de
este trabajo es presentar un algoritmo para generar una permutaci�n c�clica
aleatoria. Y se dan la prueba de su correcci�n, la complejidad y los resultados de
la prueba de distribuci�n. Resumen divulgativo] |url= incorrecta (ayuda).
Control de autoridades
Proyectos WikimediaWd Datos: Q6522952IdentificadoresMicrosoft Academic: 157998647
Categor�as: Algoritmos de ordenamientoPermutacionesAleatoriedadM�todo de Montecarlo
Men� de navegaci�n
No has accedido
Discusi�n
Contribuciones
Crear una cuenta
Acceder
Art�culoDiscusi�n
LeerEditarVer historialBuscar
Buscar en Wikipedia
Portada
Portal de la comunidad
Actualidad
Cambios recientes
P�ginas nuevas
P�gina aleatoria
Ayuda
Donaciones
Notificar un error
Herramientas
Lo que enlaza aqu�
Cambios en enlazadas
Subir archivo
P�ginas especiales
Enlace permanente
Informaci�n de la p�gina
Citar esta p�gina
Elemento de Wikidata
Imprimir/exportar
Crear un libro
Descargar como PDF
Versi�n para imprimir

En otros idiomas
Deutsch
English
?????
Fran�ais
???
???????
?????? / srpski
???
Editar enlaces
Esta p�gina se edit� por �ltima vez el 8 ago 2020 a las 14:49.
El texto est� disponible bajo la Licencia Creative Commons Atribuci�n Compartir
Igual 3.0; pueden aplicarse cl�usulas adicionales. Al usar este sitio, usted acepta
nuestros t�rminos de uso y nuestra pol�tica de privacidad.
Wikipedia� es una marca registrada de la Fundaci�n Wikimedia, Inc., una
organizaci�n sin �nimo de lucro.
Pol�tica de privacidadAcerca de WikipediaLimitaci�n de responsabilidadVersi�n para
m�vilesDesarrolladoresEstad�sticasDeclaraci�n de cookiesWikimedia FoundationPowered
by MediaWiki

También podría gustarte