Ich habe eine große Liste von Elementen, die ich in zufälliger Reihenfolge durchlaufen möchte. Allerdings kann ich die Liste nicht ändern und ich möchte auch keine Kopie davon erstellen, weil 1) sie groß ist und 2) es erwartet werden kann, dass die Iteration früh abgebrochen wird.Lazy Shuffle-Algorithmen
List<T> data = ...;
Iterator<T> shuffled = shuffle(data);
while (shuffled.hasNext()) {
T t = shuffled.next();
if (System.console().readLine("Do you want %s?", t).startsWith("y")) {
return t;
}
}
System.out.println("That's all");
return t;
Ich bin für einen Algorithmus der Suche waren der Code oben in O(n)
laufen würde (und erfordern vorzugsweise nur O(log n)
Raum), so die Elemente zwischenspeichern, die früher hergestellt wurden, ist keine Option. Es ist mir egal, ob der Algorithmus verzerrt ist (solange er nicht offensichtlich ist).
(I verwendet pseudo-Java in meiner Frage, aber Sie können andere Sprachen verwenden, wenn Sie möchten)
Hier ist das Beste, was ich so weit gekommen.
Iterator<T> shuffle(final List<T> data) {
int p = data.size();
while ((data.size() % p) == 0) p = randomPrime();
return new Iterator<T>() {
final int prime = p;
int n = 0, i = 0;
public boolean hasNext() { return i < data.size(); }
public T next() {
i++; n += prime;
return data.get(n);
}
}
}
Iterieren alle Elemente in O(n)
, konstanten Raum, aber offensichtlich voreingenommen, da es nur data.size()
Permutationen erzeugen kann.
Vielleicht haben Sie dies könnte einen Hinweis geben: http: // Stackoverflow.com/questions/352203/generating-permutations-träge – dsd
Die Antwort scheint ein Steinhaus-Johnson-Trotter-Algorithmus zu sein, der alle Permutationen iterativ erzeugt. Ich suche nach einer einzigen (zufällig gewählten) Permutation, iteratibel gebaut. – Cephalopod
Eine Antwort auf eine ähnliche Frage auf dieser Website schlug vor, einen Verschlüsselungsalgorithmus mit variabler Blockgröße zu verwenden, um die Sequenz 0, 1, 2, ... http://stackoverflow.com/a/18185810/154770 zu verschlüsseln –