Share to: share facebook share twitter share wa share telegram print page

Heap's algorithm

A map of the 24 permutations and the 23 swaps used in Heap's algorithm permuting the four letters A (amber), B (blue), C (cyan) and D (dark red)
Wheel diagram of all permutations of length generated by Heap's algorithm, where each permutation is color-coded (1=blue, 2=green, 3=yellow, 4=red).

Heap's algorithm generates all possible permutations of n objects. It was first proposed by B. R. Heap in 1963.[1] The algorithm minimizes movement: it generates each permutation from the previous one by interchanging a single pair of elements; the other n−2 elements are not disturbed. In a 1977 review of permutation-generating algorithms, Robert Sedgewick concluded that it was at that time the most effective algorithm for generating permutations by computer.[2]

The sequence of permutations of n objects generated by Heap's algorithm is the beginning of the sequence of permutations of n+1 objects. So there is one infinite sequence of permutations generated by Heap's algorithm (sequence A280318 in the OEIS).

Details of the algorithm

For a collection containing n different elements, Heap found a systematic method for choosing at each step a pair of elements to switch in order to produce every possible permutation of these elements exactly once.

Described recursively as a decrease and conquer method, Heap's algorithm operates at each step on the initial elements of the collection. Initially and thereafter . Each step generates the permutations that end with the same final elements. It does this by calling itself once with the element unaltered and then times with the () element exchanged for each of the initial elements. The recursive calls modify the initial elements and a rule is needed at each iteration to select which will be exchanged with the last. Heap's method says that this choice can be made by the parity of the number of elements operated on at this step. If is even, then the final element is iteratively exchanged with each element index. If is odd, the final element is always exchanged with the first.

procedure generate(k : integer, A : array of any):
    if k = 1 then
        output(A)
    else
        // Generate permutations with k-th unaltered
        // Initially k = length(A)
        generate(k - 1, A)

        // Generate permutations for k-th swapped with each k-1 initial
        for i := 0; i < k-1; i += 1 do
            // Swap choice dependent on parity of k (even or odd)
            if k is even then
                swap(A[i], A[k-1]) // zero-indexed, the k-th is at k-1
            else
                swap(A[0], A[k-1])
            end if
            generate(k - 1, A)
        end for
    end if

One can also write the algorithm in a non-recursive format.[3]

procedure generate(n : integer, A : array of any):
    // c is an encoding of the stack state. c[k] encodes the for-loop counter for when generate(k - 1, A) is called
    c : array of int

    for i := 0; i < n; i += 1 do
        c[i] := 0
    end for

    output(A)
    
    // i acts similarly to a stack pointer
    i := 1;
    while i < n do
        if  c[i] < i then
            if i is even then
                swap(A[0], A[i])
            else
                swap(A[c[i]], A[i])
            end if
            output(A)
            // Swap has occurred ending the while-loop. Simulate the increment of the while-loop counter
            c[i] += 1
            // Simulate recursive call reaching the base case by bringing the pointer to the base case analog in the array
            i := 1
        else
            // Calling generate(i+1, A) has ended as the while-loop terminated. Reset the state and simulate popping the stack by incrementing the pointer.
            c[i] := 0
            i += 1
        end if
    end while

Proof

In this proof, we'll use the implementation below as Heap's Algorithm. While it is not optimal (it does not minimize moves, which is described in the section below), the implementation is nevertheless still correct and will produce all permutations. The reason for using the below implementation is that the analysis is easier, and certain patterns can be easily illustrated.

procedure generate(k : integer, A : array of any):
    if k = 1 then
        output(A)
    else
        for i := 0; i < k; i += 1 do
            generate(k - 1, A)
            if k is even then
                swap(A[i], A[k-1])
            else
                swap(A[0], A[k-1])
            end if

        end for
    end if

Claim: If array A has length n, then performing Heap's algorithm will either result in A being "rotated" to the right by 1 (i.e. each element is shifted to the right with the last element occupying the first position) or result in A being unaltered, depending if n is even or odd, respectively.

Basis: The claim above trivially holds true for as Heap's algorithm will simply return A unaltered in order.

Induction: Assume the claim holds true for some . We will then need to handle two cases for : is even or odd.

If, for A, is even, then the subset of the first i elements will remain unaltered after performing Heap's Algorithm on the subarray, as assumed by the induction hypothesis. By performing Heap's Algorithm on the subarray and then performing the swapping operation, in the kth iteration of the for-loop, where , the kth element in A will be swapped into the last position of A which can be thought as a kind of "buffer". By swapping the 1st and last element, then swapping 2nd and last, all the way until the nth and last elements are swapped, the array will at last experience a rotation. To illustrate the above, look below for the case

1,2,3,4 ... Original Array
1,2,3,4 ... 1st iteration (Permute subset)
4,2,3,1 ... 1st iteration (Swap 1st element into "buffer")
4,2,3,1 ... 2nd iteration (Permute subset)
4,1,3,2 ... 2nd iteration (Swap 2nd element into "buffer")
4,1,3,2 ... 3rd iteration (Permute subset)
4,1,2,3 ... 3rd iteration (Swap 3rd element into "buffer")
4,1,2,3 ... 4th iteration (Permute subset)
4,1,2,3 ... 4th iteration (Swap 4th element into "buffer") ... The altered array is a rotated version of the original

If, for A, is odd, then the subset of the first i elements will be rotated after performing Heap's Algorithm on the first i elements. Notice that, after 1 iteration of the for-loop, when performing Heap's Algorithm on A, A is rotated to the right by 1. By the induction hypothesis, it is assumed that the first i elements will rotate. After this rotation, the first element of A will be swapped into the buffer which, when combined with the previous rotation operation, will in essence perform a rotation on the array. Perform this rotation operation n times, and the array will revert to its original state. This is illustrated below for the case .

1,2,3,4,5 ... Original Array
4,1,2,3,5 ... 1st iteration (Permute subset/Rotate subset)
5,1,2,3,4 ... 1st iteration (Swap)
3,5,1,2,4 ... 2nd iteration (Permute subset/Rotate subset)
4,5,1,2,3 ... 2nd iteration (Swap)
2,4,5,1,3 ... 3rd iteration (Permute subset/Rotate subset)
3,4,5,1,2 ... 3rd iteration (Swap)
1,3,4,5,2 ... 4th iteration (Permute subset/Rotate subset)
2,3,4,5,1 ... 4th iteration (Swap)
5,2,3,4,1 ... 5th iteration (Permute subset/Rotate subset)
1,2,3,4,5 ... 5th iteration (Swap) ... The final state of the array is in the same order as the original

The induction proof for the claim is now complete, which will now lead to why Heap's Algorithm creates all permutations of array A. Once again we will prove by induction the correctness of Heap's Algorithm.

Basis: Heap's Algorithm trivially permutes an array A of size 1 as outputting A is the one and only permutation of A.

Induction: Assume Heap's Algorithm permutes an array of size i. Using the results from the previous proof, every element of A will be in the "buffer" once when the first i elements are permuted. Because permutations of an array can be made by altering some array A through the removal of an element x from A then tacking on x to each permutation of the altered array, it follows that Heap's Algorithm permutes an array of size , for the "buffer" in essence holds the removed element, being tacked onto the permutations of the subarray of size i. Because each iteration of Heap's Algorithm has a different element of A occupying the buffer when the subarray is permuted, every permutation is generated as each element of A has a chance to be tacked onto the permutations of the array A without the buffer element.

Frequent mis-implementations

It is tempting to simplify the recursive version given above by reducing the instances of recursive calls. For example, as:

procedure generate(k : integer, A : array of any):
    if k = 1 then
        output(A)
    else

        // Recursively call once for each k
        for i := 0; i < k; i += 1 do
            generate(k - 1, A)
            // swap choice dependent on parity of k (even or odd)
            if k is even then
                // no-op when i == k-1
                swap(A[i], A[k-1])
            else
                // XXX incorrect additional swap when i==k-1
                swap(A[0], A[k-1]) 
            end if

        end for
    end if

This implementation will succeed in producing all permutations but does not minimize movement. As the recursive call-stacks unwind, it results in additional swaps at each level. Half of these will be no-ops of and where but when is odd, it results in additional swaps of the with the element.

swaps additional = swaps
1 0 0 0
2 1 1 0
3 5 6 1
4 23 27 4
5 119 140 21
6 719 845 126
7 5039 5922 883
8 40319 47383 7064
9 362879 426456 63577

These additional swaps significantly alter the order of the prefix elements.

The additional swaps can be avoided by either adding an additional recursive call before the loop and looping times (as above) or looping times and checking that is less than as in:

procedure generate(k : integer, A : array of any):
    if k = 1 then
        output(A)
    else

        // Recursively call once for each k
        for i := 0; i < k; i += 1 do
            generate(k - 1, A)
            // avoid swap when i==k-1
            if (i < k - 1)
                // swap choice dependent on parity of k
                if k is even then
                    swap(A[i], A[k-1])
                else
                    swap(A[0], A[k-1])
                end if
            end if
        end for
    end if

The choice is primarily aesthetic but the latter results in checking the value of twice as often.

See also

References

  1. ^ Heap, B. R. (1963). "Permutations by Interchanges". The Computer Journal. 6 (3): 293–4. doi:10.1093/comjnl/6.3.293.
  2. ^ Sedgewick, R. (1977). "Permutation Generation Methods". ACM Computing Surveys. 9 (2): 137–164. doi:10.1145/356689.356692. S2CID 12139332.
  3. ^ Sedgewick, Robert (4 June 2020). "a talk on Permutation Generation Algorithms" (PDF).

Read other articles:

Combate de Martín García Guerra de Independencia de la ArgentinaParte de Expediciones Libertadoras de la Banda Oriental Combate de Martín GarcíaFecha 10 al 15 de marzo de 1814Lugar Isla Martín García, Río de la Plata34°09′29″S 58°15′10″O / -34.15806, -58.25278Coordenadas 34°11′22″S 58°16′20″O / -34.18941944, -58.27230278Resultado Victoria Decisiva Argentina.[1]​Beligerantes Provincias Unidas del Río de la Plata Monarquía espa�...

 

 

1958 studio album by Sonny StittSonny StittStudio album by Sonny StittReleased1958Recorded1958 Chicago, IllinoisGenreJazzLabelArgoLP 629Sonny Stitt chronology The Saxophones of Sonny Stitt(1958) Sonny Stitt(1958) Burnin'(1958) Professional ratingsReview scoresSourceRatingAllmusic[1] Sonny Stitt is an album by saxophonist Sonny Stitt recorded in Chicago in 1958 and originally released on the Argo label.[2] Reception The Allmusic review stated Stitt, doubling on alto and...

 

 

Oliver Plunkettarcivescovo della Chiesa cattolicaRitratto di mons. Plunkett  Incarichi ricoperti Arcivescovo metropolita di Armagh (1669-1681) Primate di tutta l'Irlanda (1669-1681)  Nato1º novembre 1629 a Loughcrew Ordinato presbitero1º gennaio 1654 dal vescovo Anthony MacGeoghegan, O.F.M. Nominato arcivescovo3 agosto 1669 da papa Clemente IX Consacrato arcivescovo1º dicembre 1669 dal vescovo Eugenius Albertus d'Allamont Deceduto1º luglio 1681 (51 anni) a Tyburn   Man...

Лекса ДойгLexa Doig Ім'я при народженні Олександра Л. «Лекса» ДойгAlexandra L. «Lexa» DoigІнші імена LexaНародилася 8 червня 1973(1973-06-08) (50 років)Торонто, Онтаріо[2]Громадянство  КанадаДіяльність акторка, кіноакторка, телеакторкаРоки діяльності 1999-дотеперЧоловік Майкл Шенкс (2003...

 

 

Naval conflict from 1665 to 1667 Second Anglo-Dutch WarPart of the Anglo-Dutch WarsThe Four Days' Battle, 1–4 June 1666, by Abraham StorckDate4 March 1665 – 31 July 1667 (1665-03-04 – 1667-07-31)LocationNorth Sea, English Channel, North America, West Africa, East Indies and the CaribbeanResult Treaty of BredaBelligerents  Dutch Republic  Denmark–Norway  France  England  Scotland  Münster Commanders and leaders Johan de ...

 

 

Artikel ini sebatang kara, artinya tidak ada artikel lain yang memiliki pranala balik ke halaman ini.Bantulah menambah pranala ke artikel ini dari artikel yang berhubungan atau coba peralatan pencari pranala.Tag ini diberikan pada Mei 2016. Devia SherlyLahirDevia Sherly23 Juli 1967 (umur 56)Surabaya, IndonesiaPekerjaanPenyanyi, PengusahaKarier musikTahun aktif2014-sekarangLabelNagaswaraSitus webwww.deviasherly.com DEVIA SHERLY (lahir di Surabaya, 23 Juli 1967) adalah wanita yang berprofe...

Tjerita Si Tjonat Sampul, edisi pertamaPengarangF.D.J. PangemanannNegaraHindia BelandaBahasaMelayu RendahGenreBanditPenerbitTjoe Toei YangHalaman126OCLC35197577 Tjerita Si Tjonat, Sato Kepala Penjamoen di Djaman Dahoeloe Kala[a] (juga dikenal sebagai Tjerita Si Tjonat; EYD Cerita Si Conat) adalah novel tahun 1900 yang ditulis oleh jurnalis F.D.J. Pangemanann. Salah satu cerita bandit dari Hindia Belanda kontemporer ini mengisahkan kebangkitan dan kejatuhan Tjonat, sejak pembunuhan per...

 

 

Na de verkiezingen voor het Belgisch Parlement op 27 november 1932 ging de formatie van een nieuwe Belgische regering van start. De formatie, die negen dagen duurde, leidde tot de vorming van de regering-De Broqueville IV. Verloop van de formatie Tijdslijn Aanloop naar de formatie Op 27 november 1932 vonden in volle economische crisis vervroegde verkiezingen plaats. De Katholieke Unie bleef de grootste partij en ging er een paar procenten op vooruit: haar resultaat steeg van 35 procent bij de...

 

 

Arrondissement Brussel Het arrondissement Brussel was een arrondissement in België dat in 1963, in het kader van de vastlegging van de taalgrens, werd omgevormd tot: drie bestuurlijke arrondissementen: Brussel-Hoofdstad Halle-Vilvoorde Brussel-Rand (werd in 1971 bij Halle-Vilvoorde gevoegd) de kieskring Brussel-Halle-Vilvoorde (in 2012 opgeheven ten voordele van de kieskring Brussel-Hoofdstad en de kieskring Vlaams-Brabant) het gerechtelijk arrondissement Brussel (hiervan werd in 2012 het pa...

Main international airport of Israel Tel Aviv Airport redirects here. For the closed airport that also served Tel Aviv, see Sde Dov Airport. Lod airport redirects here. For the airport in Vanuatu with IATA code LOD, see Longana Airport. Ben Gurion International Airportנמל התעופה בן-גוריון‎مطار بن غوريون الدولي‎IATA: TLVICAO: LLBGSummaryAirport typePublicOwnerMinistry of Transport and Road SafetyOperatorIsrael Airports AuthorityServesGush Dan and ...

 

 

Lament, 2009, video stills, by Richard Ashrowan Richard Ashrowan, (English, born 1966) is a moving image/video artist working in Scotland. He specializes in multi-screen moving image installations, relating to themes connected with natural landscapes. Biography Ashrowan was born in 1966, in Essex, England. After training in Chinese Medicine he was a founder member of the charity Open Road, he played with an experimental ambient/techno band Shen in the early 1990s. From 2002 to 2007 he worked ...

 

 

American sitcom This article is about the American sitcom. For the song by Raffi, see Evergreen Everblue. Where I LiveGenreSitcomCreated byMichael JacobsEhrich Van LoweWritten byAlan DanielsGary HardwickMichael JacobsApril KellyLore KimbroughPaula Mitchell ManningEhrich Van LoweStan SeidelDirected byArlene SanfordRob SchillerDavid TrainerTom TrbovichMichael ZinbergStarringDoug E. DougFlex AlexanderShaun BakerLorraine ToussaintYunoka DoyleJason Bose SmithSullivan WalkerTheme music composerRay ...

Protected area in South AustraliaKelly Hill Conservation ParkSouth AustraliaIUCN category III (natural monument or feature)[1] Stalactite in Kelly Hill cavesKelly Hill Conservation ParkNearest town or cityKingscoteCoordinates35°59′4″S 136°55′6″E / 35.98444°S 136.91833°E / -35.98444; 136.91833Established21 January 1971[2]Area2,176 ha (5,380 acres)[3]Managing authoritiesDepartment for Environment and WaterWebsiteKelly Hill Conserv...

 

 

Journalist and TV presenter Isha SesayIsha Sesay (right) and Nima Elbagir (left) at the 2015 Peabody AwardsBornIsha Isatu Sesay (1976-01-06) 6 January 1976 (age 47)London, EnglandEducationEnglishAlma materTrinity College, Cambridge OccupationNews presenter journalistYears active1998–presentNotable creditHLN CNN CNN International Sky Sports News ITN BBC W.E. Can LeadRelativesKadi Sesay (mother)WebsiteIsha Sesay on Twitter Isha Isatu Sesay (/ˈaɪʃə səˈseɪ/ ⓘ EYE-sh�...

 

 

1956 film directed by Hans Deppe My Brother JoshuaDirected byHans DeppeWritten byWerner EpliniusJanne FurchProduced byJohannes J. FrankWilhelm GernhardtStarringWilly A. KleinauIngrid AndreeKenneth SpencerCinematographyWerner M. LenzEdited byHanna MeiselMusic byWilly MattesProductioncompanyHans Deppe FilmDistributed byEuropa-FilmverleihRelease date19 September 1956Running time92 minutesCountryWest GermanyLanguageGerman My Brother Joshua (German: Mein Bruder Josua) is a 1956 West German drama f...

Shopping mall in South Carolina, United StatesHaywood MallEntrance to Haywood Mall, October 2012LocationGreenville, South Carolina, United StatesCoordinates34°51′00″N 82°20′00″W / 34.85°N 82.333333°W / 34.85; -82.333333Opening dateJuly 30, 1980DeveloperHaywood Mall AssociatesManagementSimon Property GroupOwnerSimon Property GroupNo. of stores and services172No. of anchor tenants5 (4 open, 1 vacant)Total retail floor area1,237,411 sq ft (114,959.2&...

 

 

American fashion designer and television presenter (born 1961) Isaac MizrahiMizrahi in July 2018Born (1961-10-14) October 14, 1961 (age 62)Brooklyn New York, U.S.NationalityAmericanEducationYeshivah of FlatbushFiorello H. LaGuardia High School of Music & Art and Performing ArtsParsons School of DesignOccupation(s)Fashion designer, actor, singerLabels Isaac Mizrahi New York Isaac Mizrahi Isaac Mizrahi Jeans Isaac Mizrahi Fabulous IsaacMizrahiLIVE! Spouse Arnold Germer ​(...

 

 

Выборы главы Екатеринбурга1995 2003ИнформацияДата 19 декабря 1999 годаКандидатыФото­графия Цвет Кандидат Чернецкий Аркадий Михайлович Спектор Семен Исаакович Брусницын Юрий АлександровичПартия Наш дом — наш город Самовыдвижение СамовыдвижениеГолосов ??? (55,94%) ??? (11,74%) ??? (9...

Cristiano BertocchiCristiano Bertocchi al Rockin' field festival 2008 (Idroscalo, Milano) Nazionalità Italia GenerePower metalProgressive metal Periodo di attività musicale1994 – in attività Gruppi attualiWind Rose Gruppi precedentiVision DivineLabyrinth Sito ufficiale Modifica dati su Wikidata · Manuale Cristiano Bertocchi (Carrara, 1973) è un bassista e produttore artistico italiano, noto anche come Chris Breeze. Indice 1 Biografia 2 Discografia 2.1 Labyr...

 

 

Grade II listed lighthouse in the United kingdom LighthouseOrfordness Lighthouse Orfordness LighthouseLocationOrfordness SuffolkEnglandOS gridTM4498348865Coordinates52°05′02″N 1°34′27″E / 52.083940°N 1.574246°E / 52.083940; 1.574246TowerConstructed1637 (first)Constructionbrick towerAutomated1965Height30 m (98 ft)Shapetapered cylindrical tower with balcony and lanternMarkingswhite tower with two red bands, white lanternOperatorOrfordness Lighth...

 

 

Kembali kehalaman sebelumnya