www.wikidata.de-de.nina.az
Dieser Artikel beschreibt einen Algorithmus zum Erzeugen von Permutationen Zu dem ahnlich genannten Sortier Algorithmus siehe Heapsort Der Heap Algorithmus generiert alle moglichen Permutationen von n displaystyle n Objekten Es wurde erstmals 1963 von B R Heap vorgeschlagen 1 Der Algorithmus minimiert die Anzahl der Bewegungen der Elemente Er generiert jede Permutation aus der vorherigen indem er ein einzelnes Elementpaar austauscht Die anderen n 2 displaystyle n 2 Elemente werden nicht verandert Bei einer Uberprufung von Algorithmen zur Erzeugung von Permutationen im Jahr 1977 kam Robert Sedgewick zu dem Schluss dass dies zu dieser Zeit der effektivste Algorithmus zur Erzeugung von Permutationen per Computer war 2 Ein Schema der 24 Permutationen und der 23 Vertauschungen die im Heap Algorithmus verwendet werden wobei die vier Buchstaben A braun B blau C cyan und D rot permutierenPolardiagramm aller Permutationen von n 4 displaystyle n 4 erzeugt durch den Heap Algorithmus bei dem jede Permutation farbcodiert ist 1 blau 2 grun 3 gelb 4 rot Die durch den Heap Algorithmus erzeugte Folge von Permutationen von n displaystyle n Objekten ist der Anfang der Folge von Permutationen von n 1 displaystyle n 1 Objekten Es gibt also eine unendliche Folge von Permutationen die vom Heap Algorithmus erzeugt werden Folge A280318 in OEIS Inhaltsverzeichnis 1 Details des Algorithmus 2 Haufige Fehlimplementierungen 3 Siehe auch 4 EinzelnachweiseDetails des Algorithmus BearbeitenFur eine Menge C displaystyle C nbsp aus n displaystyle n nbsp verschiedenen Elementen fand Heap eine systematische Methode bei jedem Schritt ein Elementpaar zum Vertauschen auszuwahlen um dabei jede mogliche Permutation dieser Elemente genau einmal zu erzeugen Der Heap Algorithmus wird rekursiv als Teile und herrsche Verfahren beschrieben und arbeitet bei jedem Schritt auf den ersten k displaystyle k nbsp Elementen der Menge anfanglich k n displaystyle k n nbsp und danach k lt n displaystyle k lt n nbsp Jeder Schritt generiert die k displaystyle k nbsp Permutationen die mit denselben n k displaystyle n k nbsp letzten Elementen enden Er macht dies indem er sich selbst einmal mit dem unveranderten k displaystyle k nbsp ten Element aufruft und dann k 1 displaystyle k 1 nbsp mal wobei jeweils das k displaystyle k nbsp te Element mit den k 1 displaystyle k 1 nbsp ersten Elementen ausgetauscht wird Die rekursiven Aufrufe verandern die ersten k 1 displaystyle k 1 nbsp Elemente Es wird eine Regel benotigt die bei jeder Iteration auswahlt welches Element mit dem letzten ausgetauscht werden soll Die Methode von Heap besagt dass diese Auswahl durch die Paritat der Anzahl k displaystyle k nbsp der Elemente getroffen werden kann die in diesem Schritt bearbeitet werden Wenn k displaystyle k nbsp gerade ist dann wird das letzte Element iterativ mit jedem vorhergehenden Element ausgetauscht Wenn k displaystyle k nbsp ungerade ist wird das letzte Element immer mit dem ersten ausgetauscht der anfangliche Aufruf von generate geschieht mit k length A procedure generate k integer A array of any if k 1 then output A else erzeuge Permutationen mit unverandertem kten Element generate k 1 A erzeuge Permutationen mit dem kten Element vertauscht mit jedem k 1 sten Element alle Array Zugriffe sind 0 basiert d h das kte Element ist bei k 1 for i 0 i lt k 1 i 1 do vertausche 2 Elemente in Abhangigkeit von der Paritat von k gerade oder ungerade if k is even then swap A i A k 1 else swap A 0 A k 1 end if generate k 1 A end for end if Man kann den Algorithmus auch in einem nicht rekursiven Format schreiben 3 procedure generate n integer A array of any c ist eine Codierung des Stapelzustands c k codiert den Schleifen Zahler wenn generate k 1 A aufgerufen wird c array of int for i 0 i lt n i 1 do c i 0 end for output A i verhalt sich ahnlich wie der Stapelzeiger i 1 while i lt n do if c i lt i then if i is even then swap A 0 A i else swap A c i A i end if output A Vertauschung ist durchgefuhrt worden und hat die Schleife beendet Simuliert das Inkrement des Schleifen Zahlers c i 1 Simuliert einen rekursiven Aufruf der den Basisfall erreicht indem der Zeiger auf den Basisfall analog im Array durchgefuhrt wird i 1 else das Aufrufen von generate i 1 A endet wenn die Schleife endet Setzt den Status zuruck und simuliert das Stapeln durch Inkrementieren des Zeigers c i 0 i 1 end if end whileHaufige Fehlimplementierungen BearbeitenEs ist verlockend die oben angegebene rekursive Version zu vereinfachen indem die Anzahl der rekursiven Aufrufe reduziert wird Zum Beispiel als procedure generate k integer A array of any if k 1 then output A else rekursiver Aufruf einmal fur jedes k for i 0 i lt k i 1 do generate k 1 A Vertauschung abhangig von der Paritat von k gerade oder ungerade if k is even then Nulloperation wenn i k 1 swap A i A k 1 else uberflussige zusatzliche Vertauschung wenn i k 1 swap A 0 A k 1 end if end for end if Diese Implementierung wird erfolgreich alle Permutationen erzeugen minimiert jedoch nicht die Anzahl der Vertauschungen Wenn sich die rekursiven Aufrufstapel zuruck abwickeln fuhrt dies zu zusatzlichen Vertauschungen auf jeder Ebene wenn i k 1 displaystyle i k 1 nbsp ist Die Halfte davon sind Nulloperationen von A i displaystyle A i nbsp und A k 1 displaystyle A k 1 nbsp wenn k displaystyle k nbsp gerade ist und wenn k displaystyle k nbsp ungerade ist fuhrt es zu zusatzlichen Vertauschungen des k displaystyle k nbsp ten mit dem null ten Element n displaystyle n nbsp n 1 displaystyle n 1 nbsp swaps zusatzlich swaps n 1 displaystyle n 1 nbsp 1 0 0 02 1 1 03 5 6 14 23 27 45 119 140 216 719 845 1267 5039 5922 8838 40319 47383 70649 362879 426456 63577Diese zusatzlichen Vertauschungen verandern die Reihenfolge der k 1 displaystyle k 1 nbsp Vor Elemente betrachtlich Die zusatzlichen Vertauschungen konnen vermieden werden indem entweder ein zusatzlicher rekursiver Aufruf vor der Schleife hinzugefugt und die Schleife k 1 displaystyle k 1 nbsp mal durchlaufen wird wie im 1 vorgestellten Code oder die Schleife k displaystyle k nbsp mal durchlaufen und i lt k 1 displaystyle i lt k 1 nbsp uberpruft wird wie in procedure generate k integer A array of any if k 1 then output A else rekursiver Aufruf einmal fur jedes k for i 0 i lt k i 1 do generate k 1 A vermeide Vertauschung wenn i k 1 if i lt k 1 Vertauschung abhangig von der Paritat von 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 Die Wahl der Implementierung ist in erster Linie asthetischer Natur aber letztere fuhrt zur doppelt so haufigen Uberprufung des Wertes von i displaystyle i nbsp Siehe auch BearbeitenSteinhaus Johnson Trotter AlgorithmusEinzelnachweise Bearbeiten B R Heap Permutations by Interchanges In The Computer Journal 6 Jahrgang Nr 3 1963 S 293 4 doi 10 1093 comjnl 6 3 293 oxfordjournals org PDF R Sedgewick Permutation Generation Methods In ACM Computing Surveys 9 Jahrgang Nr 2 1977 S 137 164 doi 10 1145 356689 356692 Robert Sedgewick a talk on Permutation Generation Algorithms Abgerufen im 1 Januar 1 Abgerufen von https de wikipedia org w index php title Heap Algorithmus amp oldid 235989920