Steinhaus–Johnson–Trotter-algoritm

Hamiltoncykeln i Cayley-grafen för den symmetriska gruppen som genereras av Steinhaus-Johnson-Trotter- algoritmen






Permutationerna av fyra element, deras elementbaserade inversionsmängder (uppsättningar av elementpar utanför deras naturliga ordning), inversionsvektorer och inversionstal. Inversionsmängderna bildar en grå kod, alltså även inversionsvektorerna (summor av trianglarnas stigande diagonaler) och inversionstal. Siffrorna till vänster är permutationernas omvända kolexikografiska index (jämför lista i naturlig ordning ) och bildar rad 4 i triangeln OEIS : A280319 Inversionsuppsättningarna av permutationer 12 platser från varandra är komplement .
Hjuldiagram över alla permutationer med längden genererat av Steinhaus-Johnson-Trotter-algoritmen, där varje permutation är färgkodad (1=blå, 2=grön, 3=gul, 4=röd ).

Steinhaus –Johnson–Trotter-algoritmen eller Johnson–Trotter-algoritmen , även kallad plain changes , är en algoritm uppkallad efter Hugo Steinhaus , Selmer M. Johnson och Hale F. Trotter som genererar alla permutationer av -element. Varje permutation i sekvensen som den genererar skiljer sig från den tidigare permutationen genom att byta två intilliggande element i sekvensen. På motsvarande sätt hittar denna algoritm en Hamiltonsk cykel i permutoedern .

Denna metod var känd redan för 1600-talets engelska växlingsringare , och Sedgewick (1977) kallar den "kanske den mest framträdande permutationsuppräkningsalgoritmen". En version av algoritmen kan implementeras på ett sådant sätt att den genomsnittliga tiden per permutation är konstant. Förutom att den är enkel och beräkningseffektiv har denna algoritm fördelen att efterföljande beräkningar av de permutationer som den genererar kan påskyndas på grund av likheten mellan konsekutiva permutationer som den genererar.

Algoritm

Sekvensen av permutationer som genereras av Steinhaus-Johnson-Trotter-algoritmen har en naturlig rekursiv struktur, som kan genereras av en rekursiv algoritm. Men den faktiska Steinhaus-Johnson-Trotter-algoritmen använder inte rekursion, utan beräknar istället samma sekvens av permutationer med en enkel iterativ metod. En senare förbättring gör att den kan köras med konstant genomsnittlig tid per permutation.

Rekursiv struktur

Sekvensen av permutationer för ett givet tal kan bildas från sekvensen av permutationer för genom att placera talet i varje möjlig position i var och en av de kortare permutationerna. Steinhaus–Johnson–Trotter-algoritmen följer denna struktur: sekvensen av permutationer som den genererar består av block av permutationer, så att permutationerna inom varje block överensstämmer med ordningen på talen från 1 till och skiljer sig endast i positionen för . Själva blocken är ordnade rekursivt, enligt Steinhaus–Johnson–Trotter-algoritmen för ett element mindre. Inom varje block förekommer positionerna där placeras antingen i fallande eller stigande ordning, och blocken växlar mellan dessa två ordningsföljder: placeringarna av i det första blocket är i fallande ordning , i det andra blocket är de i stigande ordning, i det tredje blocket är de i fallande ordning, och så vidare.

Alltså, från den enda permutationen på ett element,

1

man kan placera siffran 2 i varje möjlig position i fallande ordning för att bilda en lista med två permutationer på två element,

1 2
2 1

Sedan kan man placera siffran 3 i var och en av tre olika positioner för dessa två permutationer, i fallande ordning för den första permutationen 1 2 och sedan i stigande ordning för permutationen 2 1:

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

Samma placeringsmönster, alternerande mellan fallande och stigande placeringar av , gäller för alla större värden på . I sekvenser av permutationer med denna rekursiva struktur skiljer sig varje permutation från den föregående antingen genom rörelsen med en enda position i taget av eller genom en förändring av två mindre tal som ärvts från den föregående sekvensen av kortare permutationer. I båda fallen är denna skillnad bara transponeringen av två intilliggande element. När skiljer sig de första och sista elementen i sekvensen också i endast två intilliggande element (positionerna för talen och , som kan bevisas genom induktion.

Denna sekvens kan genereras av en rekursiv algoritm som konstruerar sekvensen av mindre permutationer och sedan utför alla möjliga infogningar av det största antalet i den rekursivt genererade sekvensen. Samma ordning av permutationer kan också beskrivas på samma sätt som den ordning som genereras av följande giriga algoritm. Börja med identitetspermutationen . Transponera nu den största möjliga posten upprepade gånger med posten till vänster eller höger, så att i varje steg skapas en ny permutation som inte har påträffats i listan över permutationer tidigare. Till exempel, i fallet börjar sekvensen med och vänder sedan med sin vänstra granne för att få . Från denna punkt skulle vändning av med dess högra granne ge den initiala permutationen , så sekvensen vänder istället med sin vänstra granne och kommer fram till etc. Transpositionens riktning (vänster eller höger) bestäms alltid unikt i denna algoritm. Den faktiska Steinhaus–Johnson–Trotter-algoritmen använder dock inte rekursion och behöver inte hålla reda på de permutationer som den redan har stött på. Istället beräknar den samma sekvens av permutationer med en enkel iterativ metod .

Original version

Som beskrivs av Johnson (1963) , utför algoritmen för att generera nästa permutation från en given permutation följande steg.

  • För varje från 1 till , låt vara den position där värdet placeras i permutation . Om ordningen på talen från 1 till i permutation definierar en jämn permutation , låt annars, låt .
  • Hitta det största talet för vilket definierar en giltig position i permutationen som innehåller ett tal mindre än . Byt värdena i positionerna och .

När inget nummer kan hittas som uppfyller villkoren för det andra steget i algoritmen, har algoritmen nått den slutliga permutationen av sekvensen och avslutas. Denna procedur kan implementeras i tid per permutation.

Trotter (1962) ger en alternativ implementering av en iterativ algoritm för samma sekvens, i lätt kommenterad ALGOL 60- notation.

Eftersom denna metod genererar permutationer som växlar mellan att vara jämna och udda, kan den lätt modifieras för att generera endast de jämna permutationerna eller endast de udda permutationerna: för att generera nästa permutation av samma paritet från en given permutation, använd helt enkelt samma procedur två gånger .

Evens snabbare

En efterföljande förbättring av Shimon Even ger en förbättring av körtiden för algoritmen genom att lagra ytterligare information för varje element i permutationen: dess position och en riktning (positiv, negativ eller noll) i vilken den för närvarande rör sig (i huvudsak, detta är samma information som beräknas med hjälp av pariteten för permutationen i Johnsons version av algoritmen). Inledningsvis är riktningen för talet 1 noll, och alla andra element har en negativ riktning:

1 −2 −3

Vid varje steg hittar algoritmen det största elementet med en riktning som inte är noll och byter det i den angivna riktningen:

1 −3 −2

Om detta gör att det valda elementet når den första eller sista positionen inom permutationen, eller om nästa element i samma riktning är större än det valda elementet, sätts riktningen för det valda elementet till noll:

3 1 −2

Efter varje steg har alla element större än det valda elementet (som tidigare hade riktning noll) sina riktningar inställda för att indikera rörelse mot det valda elementet. Det vill säga positivt för alla element mellan början av permutationen och det valda elementet, och negativt för element mot slutet. I det här exemplet, efter att siffran 2 har flyttats, markeras siffran 3 med en riktning igen:

+3 2 1

De återstående två stegen i algoritmen för är:

2 +3 1
2 1 3

När alla siffror blir omarkerade avslutas algoritmen.

Denna algoritm tar tid för varje steg där det största antalet att flytta är . Således tar byten som involverar talet endast konstant tid; eftersom dessa swappar står för alla utom en bråkdel av alla swappar som utförs av algoritmen, är den genomsnittliga tiden per genererad permutation också konstant, även om ett litet antal permutationer tar ett större tid.

En mer komplex slinglös version av samma procedur gör att den kan utföras i konstant tid per permutation i varje fall; Men modifieringarna som behövs för att eliminera slingor från proceduren gör det långsammare i praktiken.

Relaterade strukturer

Permutoeder

Uppsättningen av alla permutationer av { objekt kan representeras geometriskt av en permutohedron , polytopen bildad av det konvexa skrovet av vektorer, permutationerna av vektorn . Även om det definieras på detta sätt i -dimensionellt utrymme, är det faktiskt en -dimensionell polytop; till exempel är permutoedern på fyra objekt en tredimensionell polyeder, den trunkerade oktaedern . Om varje vertex i permutoedern är märkt av den inversa permutationen till permutationen som definieras av dess vertexkoordinater, beskriver den resulterande märkningen en Cayley-graf av den symmetriska gruppen av permutationer på objekt, som genereras av permutationerna som växlar intilliggande par av föremål. Således motsvarar varje två på varandra följande permutationer i sekvensen som genereras av Steinhaus-Johnson-Trotter-algoritmen på detta sätt två hörn som bildar ändpunkterna för en kant i permutoedern, och hela sekvensen av permutationer beskriver en Hamiltonsk väg i permutoederen , en bana som passerar genom varje vertex exakt en gång. Om sekvensen av permutationer fullbordas genom att lägga till ytterligare en kant från den sista permutationen till den första i sekvensen, blir resultatet istället en Hamiltonsk cykel.

Grå koder

En grå kod för tal i en given radix är en sekvens som innehåller varje nummer upp till en given gräns exakt en gång, på ett sådant sätt att varje par av på varandra följande tal skiljer sig med ett i en enda siffra. Den permutationer av de talen från 1 till kan placeras i en-till-en-korrespondens med nummer från 0 till genom att para ihop varje permutation med nummersekvensen som räknar antalet positioner i permutationen som är till höger om värdet och som innehåller ett värde mindre än (det vill säga antalet inversioner för vilka är det största av de två inverterade värdena), och sedan tolka dessa sekvenser som tal i faktorialen talsystem , det vill säga det blandade radixsystemet med radixsekvens Till exempel permutationen skulle ge värdena , , , och . Sekvensen av dessa värden, , ger talet

Konsekutiva permutationer i sekvensen som genereras av Steinhaus–Johnson–Trotter-algoritmen har antal inversioner som skiljer sig åt med en, och bildar en grå kod för det faktoriella talsystemet.

Mer generellt har forskare av kombinatoriska algoritmer definierat en grå kod för en uppsättning kombinatoriska objekt för att vara en ordning för de objekt där varje två på varandra följande objekt skiljer sig åt på ett minimalt sätt. I denna generaliserade mening genererar Steinhaus–Johnson–Trotter-algoritmen en Gray-kod för själva permutationerna.

Historia

Metoden var känd under en stor del av historien som en metod för att ändra ringning av kyrkklockor: den ger en procedur genom vilken en uppsättning klockor kan ringas genom alla möjliga permutationer, vilket ändrar ordningen på endast två klockor per byte. Dessa så kallade "släta förändringar" registrerades så tidigt som 1621 för fyra klockor, och en bok från 1677 av Fabian Stedman listar lösningarna för upp till sex klockor. På senare tid har byte av ringsignaler följt en regel att ingen klocka får stanna i samma position under tre på varandra följande permutationer; denna regel bryts av de vanliga ändringarna, så andra strategier som byter flera klockor per förändring har utarbetats.

Algoritmen är uppkallad efter Hugo Steinhaus , Selmer M. Johnson och Hale F. Trotter . Johnson och Trotter återupptäckte algoritmen oberoende av varandra i början av 1960-talet. En bok av Steinhaus, ursprungligen publicerad 1958 och översatt till engelska 1963, beskriver ett relaterat pussel med att generera alla permutationer av ett system av partiklar, som var och en rör sig med konstant hastighet längs en linje och byter positioner när en partikel kör om en annan. Ingen lösning är möjlig för eftersom antalet byten är mycket färre än antalet permutationer, men Steinhaus–Johnson–Trotter-algoritmen beskriver rörelsen hos partiklar med icke-konstanta hastigheter som genererar alla permutationer.

Se även

Anteckningar