Gibt es einen linearen Time-In-Place-Riffle-Shuffle-Algorithmus? Dies ist der Algorithmus, den einige besonders geschickte Hände ausführen können: Ein Eingangsarray mit gerader Größe wird gleichmäßig aufgeteilt und die Elemente der beiden Hälften werden verschachtelt.
Mathworld hat eine kurze Seite über Riffle Shuffle . Insbesondere interessiert mich die Out-Shuffle-Variante, mit der das Eingangsarray 1 2 3 4 5 6 in 1 4 2 5 3 6 umgewandelt wird. Beachten Sie, dass die Eingangslänge in ihrer Definition beträgt .
Es ist unkompliziert, dies in linearer Zeit durchzuführen, wenn wir ein zweites Array mit der Größe oder mehr zur Hand haben. Kopieren Sie zuerst die letzten Elemente in das Array. Dann, unter der Annahme , 0 basierte Indizierung, kopiert die ersten Elemente aus Indizes auf . Dann kopieren Sie die Elemente aus der zweiten Anordnung zurück zu der Eingangsanordnung, Abbilden Indizes auf . (Wir können etwas weniger arbeiten, da das erste und das letzte Element in der Eingabe nicht verschoben werden.)
Eine Möglichkeit, dies an Ort und Stelle zu versuchen, besteht darin, die Permutation in disjunkte Zyklen zu zerlegen und die Elemente dann nach jedem Zyklus neu anzuordnen. Unter der Annahme einer 0-basierten Indizierung ist die Permutation im 6-Element-Fall wieder
Wie erwartet sind das erste und das letzte Element feste Punkte, und wenn wir die mittleren 4 Elemente permutieren, erhalten wir das erwartete Ergebnis.
Leider ist mein Verständnis der Mathematik der Permutationen (und deren ) basiert hauptsächlich auf Wikipedia, und ich weiß nicht, ob dies in linearer Zeit möglich ist. Vielleicht können die mit diesem Mischen verbundenen Permutationen schnell aufgelöst werden? Außerdem brauchen wir nicht einmal die vollständige Zerlegung. Nur ein einzelnes Element aus jedem der disjunkten Zyklen zu bestimmen, würde ausreichen, da wir den Zyklus aus einem seiner Elemente rekonstruieren können. Möglicherweise ist ein völlig anderer Ansatz erforderlich.
Gute Ressourcen zur verwandten Mathematik sind ebenso wertvoll wie ein Algorithmus. Vielen Dank!
Antworten:
Das Problem ist überraschend nicht trivial. Hier ist eine schöne Lösung von Ellis und Markov, In-Situ, Stabiles Zusammenführen mittels Perfect Shuffle (Abschnitt 7). Ellis, Krahn und Fan, Computing the Cycles in the Perfect Shuffle Permutation , schaffen es, "Cycle Leader" auf Kosten von mehr Speicher auszuwählen. Ebenfalls verwandt ist das schöne Paper von Fich, Munro und Poblete, Permuting In Place , das einen allgemeinen -Zeitalgorithmus für das Orakelmodell liefert . Wenn nur ein Orakel für die Permutation verfügbar ist, benötigt der Algorithmus logarithmischen Speicherplatz. Wenn wir auch ein Orakel für das Inverse haben, benötigt es konstanten Raum.O(nlogn)
Nun zu Ellis und Markovs Lösung. Nehmen wir zunächst . Dann wird die Berechnung der perfekten Mischung der Ordnungen n auf die Berechnung der perfekten Mischung der Ordnungen x und y mit einer Rotation vor ihnen reduziert . Hier ist ein Beweis durch Beispiel ( n = 5 , x = 3 , y = 2 ): 012 345 67 89 012 567 34 89 051627 3849n=x+y n x y n=5 x=3 y=2
Ellis und Markov fanden einen einfachen Weg, um die perfekte Verschiebung zu berechnen, wenn , und zwar unter Verwendung von konstantem Raum und linearer Zeit. Damit erhalten wir einen Algorithmus zur Berechnung des perfekten Shuffle für beliebiges n . Schreiben Sie zunächst n = 2 k 0 + ⋯ + 2 k w unter Verwendung der binären Codierung von n und lassen Sie n i = 2 k i + ⋯ + 2 k w . Drehe die mittleren n 0 Bits, mische die rechten 2 kn=2k n n=2k0+⋯+2kw n ni=2ki+⋯+2kw n0 Bits. Ignorieren Sie die rechten2 k 0 Bits, drehen Sie die mittlerenn1Bits und mischen Sie die rechten2 k 1 Bits. Und so weiter. Beachten Sie, dass die Drehung einfach ist, da die ersten gedrehten Elemente als Zyklusleiter fungieren. Die Gesamtkomplexität der Rotation istO(n0+⋯+nw)=O(n), dan t + 1 <nt/2. Die Gesamtkomplexität der inneren Mischen istO(2k0 2k0 n1 2k1 O(n0+⋯+nw)=O(n) nt+1<nt/2 .O(2k0+⋯+2kw)=O(n)
Es bleibt zu zeigen, wie der perfekte Shuffle berechnet wird, wenn . In der Tat werden wir in der Lage sein, nach klassischer Arbeit an Halsketten Fahrradführer zu identifizieren (Fredricksen und Maiorana, Halsketten aus Perlen in k Farben und k -ary de Bruijn Sequenzen ; Fredricksen und Kessler, Ein Algorithmus zur Erzeugung von Halsketten aus Perlen in zwei Farben ).n=2k k k
Was ist die Verbindung? Ich behaupte, dass die Shuffle-Permutation einer Verschiebung der Binärdarstellung nach rechts entspricht. Hier ist ein beispielhafter Beweis für : 000 001 010 011 100 101 110 111 000 100 001 101 010 110 011 111 Um Zyklusleiter zu finden, müssen wir aus jeder Äquivalenzklasse der Rotation von einen Vertreter finden binäre Zeichenfolgen der Länge k . Die oben erwähnten Arbeiten geben den folgenden Algorithmus zum Erzeugen aller Zyklusleiter an. Beginnen Sie mit 0 kn=8
Wenn beispielsweise wird die Sequenz 0000 , 0001 , 0010 , 0011 , 0101 , 0110 , 0111 , 1111 generiert .n=16
Die Fahrradführer sind hervorgehoben.
quelle
Dies war eine Seeding-Frage bei cs.stackexchange.com und eine Antwort finden Sie hier: /cs/332/in-place-algorithm-for-interleaving-an-array/400#400
Es ist eine Erklärung des Papiers: http://arxiv.org/abs/0805.1598 .
quelle
quelle