Zufallswiedergabe Probleme

Man kommt auch ohne Speichern einer Zufallsplaylist aus:

Der Zweck einer Zufallsplaylist ist ja, dass alle Tracks eines Ordners ohne Wiederholung abgespielt werden sollen, aber in keiner erkennbaren Reihenfolge. Außerdem soll die verwendete Reihenfolge bei jedem Auflegen anders sein. Das geht mit ein wenig Mathematik auch vollkommen ohne Speichern einer Zufallspermutation. Mit dem folgenden Trick erhält man für einen Ordner mit N Tracks eine von mindestens N·(N-1) Playlist-Permutationen. Das sind zwar längst nicht alle möglichen Permutationen, aber mehr als genug, um keine Wiederholungsmuster zu hören.

Der Trick ist der Folgende:

Für zufällig wahrgenommene Abspielreihenfolgen reicht im Grunde eine konstante Schrittweite von Tracknummer zu anschließend abgespielter Tracknummer. Dazu muss man nur einmal beim Auflegen der Karte per Zufall eine Schrittweite wählen (und einen zufälligen Startpunkt setzen). Mittels der Modulo-Funktion wird nun immer der nächste Track ermittelt. So erhält man bei N Tracks und festem Startpunkt N-1 verschiedene Playlists ohne jegliche Wiederholung, sofern N eine Primzahl ist. Und wenn man nun noch den Startpunkt zufällig wählt, sind es N·(N-1) garantiert verschiedene Playlists. Das reicht vollkommen aus.

Das Prinzip funktioniert so aber nur dann, wenn die Anzahl der Tracks in einem Ordner eine Primzahl ist. Sonst könnte es zu kürzeren Zyklen kommen. Man kannn aber einfach eine Primzahl wählen, die größer ist als die Anzahl der Tracks, und überspringt einfach zu große Werte der Permutation. Damit funktioniert das Prinzip auch für Nicht-Primzahlen. So ergeben sich teilweise sogar noch mehr als N·(N-1) unterschiedliche Playlists (wenn man noch den Umbruch der zu großen Werte mit einem zufälligen Offset variiert). Jede Playlist umfasst dabei garantiert alle Tracks.

Auch das Ermitteln einer Primzahl, die größer ist als N, ist für N<256 algorithmisch lösbar. Es muss ja nicht zwingend die nächstgrößte Primzahl sein. Theoretisch würde es reichen, eine feste Primzahl über 255 zu wählen (z.B. 257). Aber dann müsste man teilweise schon sehr viele Werte überspringen. Es geht aber auch etwas besser: Die Funktion 11+(60·ceil(N-11)/60) liefert für jedes N<256 eine Primzahl P>=N (und zwar eine der Folgenden: 11, 71, 131, 191, 251, 311).

Die Implementation sieht dann so aus:

Initialisierung (beim Auflegen der Karte):

firstTrack=random(numTracksInFolder)+1;
periodLength=11+60*ceil((numTracksInFolder-11)/60);
step=random(1,numTracksInFolder);
currentPos=random(numTracksInFolder);
currentTrack=firstTrack;

Anwählen des nächsten Tracks:

do{
    currentPos=(currentPos+step)%periodLength;
} while (currentPos>=numTracksInFolder);
currentTrack=(currentPos+firstTrack-1)%numTracksInFolder+1;

Anwählen des vorhergehenden Tracks:

do{
    currentPos=(currentPos+periodLength-step)%periodLength;
} while (currentPos>=numTracks);
currentTrack=(currentPos+firstTrack-1)%numTracksInFolder+1;

Die While-Schleifen werden jeweils maximal 60 mal durchlaufen, im Durchschnitt aber nicht öfter als 1,53 mal.

Man könnte auch die vier nötigen Werte (firstTrack, periodLength, currentPos, step) auf der Karte speichern und so eine Playlist beim nächsten Auflegen fortsetzen. Wenn man möchte, dass nach dem Durchlaufen eines Zyklus eine neue Reihenfolge erstellt wird, reicht es, sobald currentTrack wieder gleich firstTrack ist, step neu zu setzen. Damit ist auch gewährleistet, dass auch der aktuelle Track nicht zufällig wieder gleich als nächstes kommt.

3 „Gefällt mir“