Besserer Algorithmus zum Mischen (Shuffle) mehrerer Listen unterschiedlicher Länge

8

Ich schaue mir gerne meine Lieblings-TV-Sendungen an. Ich habe alle Folgen jeder Serie, der ich in meiner Playlist folge. Nicht alle Shows bestehen aus der gleichen Anzahl von Episoden. Im Gegensatz zu einigen, die Marathons bevorzugen, mag ich es, Episoden einer Show mit denen einer anderen zu verschachteln.

Wenn ich zum Beispiel eine Show namens ABC mit 2 Episoden und eine Show namens XYZ mit 4 Folgen habe, möchte ich, dass meine Playlist wie folgt aussieht:

%Vor%

Eine Möglichkeit, diese verschachtelte Wiedergabeliste zu erstellen, besteht darin, jede Show als eine Liste von Episoden darzustellen und bei allen Shows einen Riffle Shuffle durchzuführen. Man könnte eine Funktion schreiben, die für jede Episode ihre Position in einem Einheitszeitintervall berechnet (zwischen 0.0 und 1.0 exklusiv, 0.0 ist der Beginn der Saison, 1.0 ist das Ende der Saison), dann sortiere alle Episoden nach ihrer Position.

Ich habe die folgende einfache Funktion in Python 2.7 geschrieben, um eine In-Shuffle-Funktion auszuführen:

%Vor%

Um die Playlist für das obige Beispiel zu erhalten, muss ich einfach anrufen:

%Vor%

Das funktioniert die meiste Zeit ziemlich gut. Es gibt jedoch Fälle, in denen die Ergebnisse nicht optimal sind - zwei benachbarte Einträge in der Wiedergabeliste sind Episoden derselben Show. Zum Beispiel:

%Vor%

Beachten Sie, dass es zwei Episoden von "XYZ" gibt, die Seite an Seite erscheinen. Diese Situation kann trivial behoben werden (manuell 'ABCe1' durch 'XYZe2' ersetzen).

Ich bin gespannt, ob es auf mehreren Listen unterschiedlicher Länge bessere Möglichkeiten zum Interleave oder zum Ausführen von Riffle Shuffle gibt. Ich würde gerne wissen, ob Sie Lösungen haben, die einfacher, effizienter oder schlicht elegant sind.

Lösung von belisarius vorgeschlagen (danke!):

%Vor%

Beispiel run:

%Vor%     
Adeel Zafar Soomro 28.03.2011, 07:08
quelle

4 Antworten

5

Eine deterministische Lösung (dh nicht zufällig)

Sortieren Sie Ihre Sendungen, indem Sie die Anzahl der Episoden verringern.

Wählen Sie die größte und ordnen Sie eine Matrix mit der Anzahl der Spalten entsprechend der Anzahl der Episoden von diesem an, gefüllt in der folgenden Weise:

%Vor%

Sammeln Sie dann nach Spalten

%Vor%

Dann treten Sie

bei %Vor%

Und weisen Sie jetzt fortlaufende Nummern zu

%Vor%

Bearbeiten

Ihr Fall

%Vor%

Bearbeiten 2

Wie hier kein Python, könnte ein Mathematica-Code vielleicht von Nutzen sein:

%Vor%     
Dr. belisarius 28.03.2011, 08:13
quelle
1

Mein Versuch:

%Vor%     
Tony Veijalainen 28.03.2011 08:15
quelle
0

Dies würde sicherstellen, dass es mindestens 1 und nicht mehr als 2 weitere Episoden zwischen zwei aufeinander folgenden Episoden einer Show gibt:

  • Während es mehr als 3 Shows gibt, zeigt die kürzeste Kette (d. h. mit den wenigsten Episoden) zusammen Ende-zu-Ende.
  • Sei A die längste Show und B und C die anderen beiden.
  • Wenn B kürzer als A ist, packen Sie es mit None am Ende
  • Wenn C kürzer als A ist, füllen Sie es am Anfang mit None auf.
  • Die gemischte Playlist ist [x for x in itertools.chain(zip(A,B,C)) if x is not None]
Janne Karila 28.03.2011 09:40
quelle
0

Damit wird True Shuffle sichergestellt, d. h. jedes Mal ein anderes Ergebnis, ohne so viele zusammenhängende Elemente wie möglich.

Der, den Sie fragen, könnte wahrscheinlich einige (1, 2) Ergebnisse zurückgeben, die durch Ihre Anfragen begrenzt sind.

%Vor%

Bearbeiten:

Die Reihenfolge der gegebenen Episoden ist obligatorisch, einfach randpop function:

vereinfachen %Vor%     
neurino 28.03.2011 08:40
quelle