Articulo de referencia

Algoritmo de Steinhaus-Johnson-Trotter

El ciclo hamiltoniano en el grafo de Cayley del grupo simétrico generado por el algoritmo de Steinhaus-Johnson-Trotter Diagrama de rueda de todas las permutaciones de longitud n...

El ciclo hamiltoniano en el grafo de Cayley del grupo simétrico generado por el algoritmo de Steinhaus-Johnson-Trotter
Diagrama de rueda de todas las permutaciones de longitudnorte=4{\displaystyle n=4}generado por el algoritmo de Steinhaus-Johnson-Trotter, donde cada permutación está codificada por colores (1=azul, 2=verde, 3=amarillo, 4=rojo).

El algoritmo Steinhaus-Johnson-Trotter o algoritmo Johnson - Trotter , también llamado cambios simples , es un algoritmo que lleva el nombre de Hugo Steinhaus , Selmer M. Johnson y Hale F. Trotter que genera todas las permutaciones denorte{\displaystyle n}elementos. Cada par de permutaciones adyacentes en la secuencia resultante difieren al intercambiar dos elementos permutados adyacentes. De forma equivalente, este algoritmo encuentra un ciclo hamiltoniano en el permutoedro , un politopo cuyos vértices representan permutaciones y cuyas aristas representan intercambios.

Este método ya era conocido por los campaneros ingleses del siglo XVII , y Robert Sedgewick lo denomina «quizás el algoritmo de enumeración de permutaciones más destacado ». [ 1 ] Una versión del algoritmo puede implementarse de tal manera que el tiempo promedio por permutación sea constante. Además de ser simple y computacionalmente eficiente, este algoritmo tiene la ventaja de que los cálculos subsiguientes sobre las permutaciones generadas pueden acelerarse aprovechando la similitud entre permutaciones consecutivas. [ 1 ]

Algoritmo

La secuencia de permutaciones generada por el algoritmo de Steinhaus-Johnson-Trotter posee una estructura recursiva natural , que puede generarse mediante un algoritmo recursivo. Sin embargo, el algoritmo de Steinhaus-Johnson-Trotter en sí no utiliza recursión, sino que calcula la misma secuencia de permutaciones mediante un método iterativo sencillo. Una mejora posterior permite que se ejecute en un tiempo promedio constante por permutación.

Estructura recursiva

La secuencia de permutaciones para un número dadonorte{\displaystyle n}se puede formar a partir de la secuencia de permutaciones paranorte1{\displaystyle n-1}colocando el númeronorte{\displaystyle n}en cada posición posible en cada una de las permutaciones más cortas. El algoritmo de Steinhaus-Johnson-Trotter sigue esta estructura: la secuencia de permutaciones que genera consiste en(norte1)¡{\displaystyle (n-1)!}bloques de permutaciones, de modo que dentro de cada bloque las permutaciones coincidan en el orden de los números del 1 alnorte1{\displaystyle n-1}y difieren únicamente en la posición denorte{\displaystyle n}. Los bloques mismos se ordenan recursivamente, según el algoritmo de Steinhaus-Johnson-Trotter para un elemento menos. Dentro de cada bloque, las posiciones en las quenorte{\displaystyle n}se colocan en orden descendente o ascendente, y los bloques alternan entre estos dos órdenes: las colocaciones denorte{\displaystyle n}En el primer bloque están en orden descendente, en el segundo bloque están en orden ascendente, en el tercer bloque están en orden descendente, y así sucesivamente. [ 2 ]

Así, a partir de la única permutación en un elemento,

1

uno puede colocar el número 2 en cada posición posible en orden descendente para formar una lista de dos permutaciones en dos elementos,

1 2
2 1

Entonces, se puede colocar el número 3 en cada una de las tres posiciones diferentes para estas dos permutaciones, en orden descendente para la primera permutación 1 2, y luego en orden ascendente para la permutación 2 1:

1 2 3
1 3 2
3 1 2
3 2 1
2 3 1
2 1 3

El mismo patrón de colocación, alternando entre colocaciones descendentes y ascendentes denorte{\displaystyle n}, se aplica a cualquier valor mayor denorte{\displaystyle n}. [ 2 ] En secuencias de permutaciones con esta estructura recursiva, cada permutación difiere de la anterior ya sea por el movimiento de una posición a la vez denorte{\displaystyle n}o mediante un cambio de dos números más pequeños heredados de la secuencia anterior de permutaciones más cortas. En cualquier caso, esta diferencia es simplemente la transposición de dos elementos adyacentes. Cuandonorte>1{\displaystyle n>1}El primer y el último elemento de la secuencia también difieren en solo dos elementos adyacentes (las posiciones de los números).1{\displaystyle 1}y2{\displaystyle 2}), como puede probarse por inducción.

Esta secuencia puede ser generada por un algoritmo recursivo que construye la secuencia de permutaciones más pequeñas y luego realiza todas las inserciones posibles del número más grande en la secuencia generada recursivamente. [ 2 ] El mismo ordenamiento de permutaciones también puede describirse de manera equivalente como el ordenamiento generado por el siguiente algoritmo voraz . [ 3 ] Comience con la permutación identidad12norte{\displaystyle 1\;2\;\ldots \;n}Ahora, transponga repetidamente la entrada más grande posible con la entrada a su izquierda o derecha, de manera que en cada paso se cree una nueva permutación que no se haya encontrado antes en la lista de permutaciones. Por ejemplo, en el casonorte=3{\displaystyle n=3}La secuencia comienza con123{\displaystyle 1\;2\;3}, luego se voltea3{\displaystyle 3}con su vecino izquierdo para obtener132{\displaystyle 1\;3\;2}. Desde este punto, volteando3{\displaystyle 3}con su vecino derecho2{\displaystyle 2}produciría la permutación inicial123{\displaystyle 1\;2\;3}, por lo que la secuencia se invierte3{\displaystyle 3}con su vecino de la izquierda1{\displaystyle 1}y llega a312{\displaystyle 3\;1\;2}etc. La dirección de la transposición (izquierda o derecha) siempre se determina de forma única en este algoritmo. Sin embargo, el algoritmo real de Steinhaus-Johnson-Trotter no utiliza recursión y no necesita llevar un registro de las permutaciones que ya ha encontrado. En cambio, calcula la misma secuencia de permutaciones mediante un método iterativo simple .

Versión original

Como lo describió Johnson, el algoritmo para generar la siguiente permutación a partir de una permutación dadaπ{\displaystyle \pi }realiza los siguientes pasos.

  • Para cadai{\displaystyle i}del 1 alnorte{\displaystyle n}, dejarincógnitai{\displaystyle x_{i}}ser la posición donde el valori{\displaystyle i}se coloca en permutaciónπ{\displaystyle \pi }. Si el orden de los números del 1 ali1{\displaystyle i-1}en permutaciónπ{\displaystyle \pi }define una permutación par , seayi=incógnitai1{\displaystyle y_{i}=x_{i}-1}de lo contrario, dejayi=incógnitai+1{\displaystyle y_{i}=x_{i}+1}.
  • Encuentra el número más grandei{\displaystyle i}para quéyi{\displaystyle y_{i}}define una posición válida en la permutaciónπ{\displaystyle \pi }que contiene un número menor quei{\displaystyle i}. Intercambia los valores en las posicionesincógnitai{\displaystyle x_{i}}yyi{\displaystyle y_{i}}.

Cuando no hay númeroi{\displaystyle i}Se puede encontrar que cumple las condiciones del segundo paso del algoritmo, el algoritmo ha alcanzado la permutación final de la secuencia y termina. Este procedimiento se puede implementar enO(norte){\displaystyle O(n)}tiempo por permutación. [ 4 ]

Trotter ofrece una implementación alternativa de un algoritmo iterativo para la misma secuencia, en notación ALGOL 60 con comentarios breves . [ 5 ]

Debido a que este método genera permutaciones que alternan entre ser pares e impares, puede modificarse fácilmente para generar solo las permutaciones pares o solo las impares: para generar la siguiente permutación de la misma paridad a partir de una permutación dada, basta con aplicar el mismo procedimiento dos veces. [ 6 ]

La aceleración de Even

Una mejora posterior de Shimon Even optimiza el tiempo de ejecución del algoritmo al almacenar información adicional para cada elemento de la permutación: su posición y la dirección (positiva, negativa o cero) en la que se mueve actualmente (básicamente, esta es la misma información calculada utilizando la paridad de la permutación en la versión del algoritmo de Johnson). Inicialmente, la dirección del número 1 es cero, y todos los demás elementos tienen una dirección negativa:

1 2 3

En cada paso, el algoritmo encuentra el elemento más grande con una dirección distinta de cero y lo intercambia en la dirección indicada:

1 3 2

Si esto provoca que el elemento elegido alcance la primera o la última posición dentro de la permutación, o si el siguiente elemento en la misma dirección es mayor que el elemento elegido, la dirección del elemento elegido se establece en cero:

3 1 2

Después de cada paso, a todos los elementos mayores que el elemento elegido (que previamente tenía dirección cero) se les cambia la dirección para indicar movimiento hacia el elemento elegido. Es decir, positiva para todos los elementos entre el inicio de la permutación y el elemento elegido, y negativa para los elementos hacia el final. Así, en este ejemplo, después de que el número 2 se mueve, el número 3 vuelve a tener una dirección asignada:

+3 2 1

Los dos pasos restantes del algoritmo paranorte=3{\displaystyle n=3}son:

2 +3 1
2 1 3

Cuando todos los números quedan sin marcar, el algoritmo finaliza. [ 7 ]

Este algoritmo lleva tiempoO(i){\displaystyle O(i)}por cada paso en el que el mayor número a moverse esnortei+1{\displaystyle n-i+1}. Por lo tanto, los intercambios que involucran el númeronorte{\displaystyle n}toman solo tiempo constante; ya que estos intercambios representan todo menos un1/norte{\displaystyle 1/n}fracción de todos los intercambios realizados por el algoritmo, el tiempo promedio por permutación generada también es constante, aunque un pequeño número de permutaciones tomará una mayor cantidad de tiempo. [ 1 ]

Una versión más compleja y sin bucles del mismo procedimiento, adecuada para la programación funcional, permite que se ejecute en tiempo constante por permutación en todos los casos; sin embargo, las modificaciones necesarias para eliminar los bucles del procedimiento lo hacen más lento en la práctica. [ 8 ]

Permutoedro

El conjunto de todas las permutaciones denorte{\displaystyle n}Los elementos pueden representarse geométricamente mediante un permutoedro , el politopo formado a partir de la envoltura convexa denorte¡{\displaystyle n!}vectores, las permutaciones del vector(1,2,norte){\displaystyle (1,2,\dots n)}. Aunque se define de esta manera ennorte{\displaystyle n}espacio -dimensional, en realidad es un(norte1){\displaystyle (n-1)}politopo de dimensión ; por ejemplo, el permutoedro de cuatro elementos es un poliedro tridimensional, el octaedro truncado . Si cada vértice del permutoedro se etiqueta mediante la permutación inversa a la permutación definida por sus coordenadas de vértice, el etiquetado resultante describe un grafo de Cayley del grupo simétrico de permutaciones ennorte{\displaystyle n}elementos, generados por las permutaciones que intercambian pares adyacentes de elementos. Así, cada dos permutaciones consecutivas en la secuencia generada por el algoritmo de Steinhaus-Johnson-Trotter corresponden de esta manera a dos vértices que forman los extremos de una arista en el permutoedro, y toda la secuencia de permutaciones describe un camino hamiltoniano en el permutoedro, un camino que pasa por cada vértice exactamente una vez. Si la secuencia de permutaciones se completa añadiendo una arista más de la última permutación a la primera de la secuencia, el resultado es un ciclo hamiltoniano. [ 9 ]

Códigos grises

Un código Gray para números en una base dada es una secuencia que contiene cada número hasta un límite dado exactamente una vez, de tal manera que cada par de números consecutivos difiere en uno en un solo dígito.norte¡{\displaystyle n!}permutaciones de lanorte{\displaystyle n}números del 1 alnorte{\displaystyle n}puede ser colocado en correspondencia individual con elnorte¡{\displaystyle n!}números del 0 alnorte¡1{\displaystyle n!-1}emparejando cada permutación con la secuencia de númerosdoi{\displaystyle c_{i}}que cuentan el número de posiciones en la permutación que están a la derecha del valori{\displaystyle i}y que contienen un valor menor quei{\displaystyle i}(es decir, el número de inversiones para las cualesi{\displaystyle i}es el mayor de los dos valores invertidos), y luego interpretando estas secuencias como números en el sistema numérico factorial , es decir, el sistema de base mixta con secuencia de base(1,2,3,4,){\displaystyle (1,2,3,4,\dots )}Por ejemplo, la permutación(3,1,4,5,2){\displaystyle (3,1,4,5,2)}daría los valoresdo1=0{\displaystyle c_{1}=0},do2=0{\displaystyle c_{2}=0},do3=2{\displaystyle c_{3}=2},do4=1{\displaystyle c_{4}=1}, ydo5=1{\displaystyle c_{5}=1}. La secuencia de estos valores,(0,0,2,1,1){\displaystyle (0,0,2,1,1)}, da el número 0×0¡+0×1¡+2×2¡+1×3¡+1×4¡=34.{\displaystyle 0\times 0!+0\times 1!+2\times 2!+1\times 3!+1\times 4!=34.} Las permutaciones consecutivas en la secuencia generada por el algoritmo de Steinhaus-Johnson-Trotter tienen números de inversiones que difieren en uno, formando un código Gray para el sistema numérico factorial. [ 10 ]

En términos más generales, los investigadores de algoritmos combinatorios han definido un código Gray para un conjunto de objetos combinatorios como un ordenamiento de los objetos en el que cada par de objetos consecutivos difiere de la forma mínima posible. En este sentido generalizado, el algoritmo de Steinhaus-Johnson-Trotter genera un código Gray para las permutaciones mismas. [ 11 ]

Historia

El método fue conocido durante gran parte de su historia como un método para el repique de campanas de iglesia: proporciona un procedimiento mediante el cual un conjunto de campanas puede tocarse a través de todas las permutaciones posibles, cambiando el orden de solo dos campanas por cambio. Estos llamados "cambios simples" o "caza simple" eran conocidos hacia 1621 para cuatro campanas, [ 12 ] y el método general se ha rastreado hasta un manuscrito inédito de 1653 de Peter Mundy . [ 6 ] Un libro de 1677 de Fabian Stedman enumera las soluciones para hasta seis campanas. [ 13 ] Más recientemente, los campaneros de cambio han respetado una regla que establece que ninguna campana puede permanecer en la misma posición durante tres permutaciones consecutivas; esta regla se viola con los cambios simples, por lo que se han ideado otras estrategias que intercambian varias campanas por cambio. [ 14 ]

El algoritmo lleva el nombre de Hugo Steinhaus , Selmer M. Johnson y Hale F. Trotter . Johnson y Trotter redescubrieron el algoritmo de forma independiente a principios de la década de 1960. [ 15 ] Un libro de Steinhaus de 1958, traducido al inglés en 1964, describe un rompecabezas relacionado, aparentemente imposible , que consiste en generar todas las permutaciones mediante un sistema de partículas, cada una moviéndose a velocidad constante a lo largo de una línea e intercambiando posiciones cuando una partícula adelanta a otra. [ 16 ] Un artículo de Hu y Bien de 1976 atribuyó a Steinhaus la formulación del problema algorítmico de generar todas las permutaciones, [ 17 ] y en 1989 su libro había sido (erróneamente) reconocido como una de las publicaciones originales del algoritmo. [ 18 ]

Véase también

Notas

Referencias

  • Bird, Richard (2010), «Capítulo 29: El algoritmo de Johnson-Trotter», Perlas del diseño de algoritmos funcionales , Cambridge University Press, pp. 251-257 , doi : 10.1017/cbo9780511763199 , ISBN  9780511763199
  • Dershowitz, Nachum (1975), "Un algoritmo simplificado sin bucles para generar permutaciones", Nordisk Tidskr. Informationsbehandling (BIT) , 15 (2): 158–164 , doi : 10.1007/bf01932689 , MR 0502206 , S2CID 121353303  
  • Dijkstra, Edsger W. (1976), "Sobre un desafío lanzado por David Gries" (PDF) , Acta Informatica , 6 (4): 357–359 , doi : 10.1007/BF00268136 , MR 0426492 , S2CID 7085805  . Aunque Dijkstra no cita ninguna literatura previa, un borrador anterior EWD502 revela que conocía a Trotter (1962) .
  • Ehrlich, Gideon (1973), "Algoritmos sin bucles para generar permutaciones, combinaciones y otras configuraciones combinatorias", Journal of the ACM , 20 (3): 500– 513, doi : 10.1145/321765.321781 , S2CID 21493963 
  • Even, Shimon (1973), Combinatoria algorítmica , Macmillan
  • Hu, TC ; Tien, BN (octubre de 1976), "Generación de permutaciones con elementos no distintos", The American Mathematical Monthly , 83 (8): 629–631 , doi : 10.1080/00029890.1976.11994195 , JSTOR 2319890 
  • Johnson, Selmer M. (1963), "Generación de permutaciones mediante transposición adyacente", Mathematics of Computation , 17 (83): 282–285 , doi : 10.1090/S0025-5718-1963-0159764-2 , JSTOR 2003846 , MR 0159764  
  • Lenstra, JK ; Rinnooy Kan, AHG (septiembre de 1979), "Un enfoque recursivo para la implementación de métodos enumerativos", Actas de la Escuela sobre Análisis y Diseño de Algoritmos en Optimización Combinatoria, Udine, Italia (PDF) , Informe técnico 8003/0, Universidad Erasmus de Róterdam; véase la Sección 2.1, "Un generador de cambio mínimo", págs. 3-8
  • Knuth, Donald (2011), "Sección 7.2.1.2: Generación de todas las permutaciones" , El arte de la programación informática, volumen 4A: Algoritmos combinatorios, Parte 1
  • McGuire, Gary (2003), Campanas, moteles y grupos de permutación , CiteSeerX 10.1.1.6.5544 
  • Ruskey, Frank (1989), "Generación por transposición de permutaciones alternas", Order , 6 (3): 227– 233, doi : 10.1007/BF00563523 , MR 1048093 
  • Savage, Carla (1997), "Un estudio de los códigos Gray combinatorios", SIAM Review , 39 (4): 605– 629, Bibcode : 1997SIAMR..39..605S , CiteSeerX 10.1.1.39.1924 , doi : 10.1137/S0036144595295272 , JSTOR 2132693 , MR 1491049   
  • Sedgewick, Robert (1977), "Métodos de generación de permutaciones", ACM Comput. Surv. , 9 (2): 137– 164, doi : 10.1145/356689.356692 , S2CID 12139332 
  • Stedman, Fabian (1677), Campanalogia, o, El arte de tocar campanas mejorado , Londres: W. Godbid vía Early English Books Online Text Creation Partnership
  • Steinhaus, Hugo (1964), Cien problemas de matemáticas elementales , Nueva York: Basic Books, págs. 49–50 , MR 0157881  
  • Trotter, HF (agosto de 1962), "Algoritmo 115: Perm", Communications of the ACM , 5 (8): 434– 435, doi : 10.1145/368637.368660 , S2CID 1013826 
  • White, Arthur T. (noviembre de 1996), "Fabian Stedman: ¿el primer teórico de grupos?", The American Mathematical Monthly , 103 (9): 771– 778, doi : 10.1080/00029890.1996.12004816 , JSTOR 2974446 
  • Williams, Aaron (2013), "El algoritmo de código gris voraz", en Dehne, Frank; Solis-Oba, Roberto; Sack, Jörg-Rüdiger (eds.), Algoritmos y estructuras de datos - 13.º Simposio Internacional, WADS 2013, London, ON, Canadá, 12-14 de agosto de 2013. Actas , Lecture Notes in Computer Science, vol.  8037, Springer, pp. 525–536 , doi : 10.1007/978-3-642-40104-6_46 , ISBN  978-3-642-40103-9