Wie erstelle ich eine Liste von Zufallszahlen ohne Duplikate?
Versuchte ich mit random.randint(0, 100)
, aber einige zahlen waren die gleichen. Gibt es eine Methode/Modul zum erstellen einer Liste eindeutige Zufallszahlen?
def getScores():
# open files to read and write
f1 = open("page.txt", "r");
p1 = open("pgRes.txt", "a");
gScores = [];
bScores = [];
yScores = [];
# run 50 tests of 40 random queries to implement "bootstrapping" method
for i in range(50):
# get 40 random queries from the 50
lines = random.sample(f1.readlines(), 40);
- Wenn Sie sind einzigartig, Sie werden wirklich zufällig in den richtigen Kontext. Wie eine Stichprobe von Indizes ohne Ersatz noch völlig zufällig.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Dieser gibt eine Liste von 10 zahlen ausgewählt aus dem Bereich von 0 bis 99, ohne Duplikate.
Bezug auf Ihre spezifische code-Beispiel, werden Sie wahrscheinlich wollen, Lesen Sie bitte alle Zeilen aus der Datei einmal und dann wählen Sie zufällige Linien aus der gespeicherten Liste im Speicher. Zum Beispiel:
Diese Weise werden Sie nur brauchen, um tatsächlich aus der Datei gelesen einmal vor der Schleife. Es ist viel effektiver, als zu versuchen, zurück an den Anfang der Datei, und nennen
f1.readlines()
wieder für jede Schleife, iteration.Können Sie die shuffle Funktion aus der random Modul wie dieses:
Beachten Sie hier, dass die shuffle-Methode nicht wieder eine Liste, wie man erwarten kann, es nur schieben Sie die Liste per Referenz übergeben.
Können Sie zuerst erstellen Sie eine Liste der zahlen von
a
zub
, woa
undb
sind jeweils die kleinste und die größte Zahl in der Liste ist, dann mische es mit Fisher-Yates - Algorithmus oder mit dem Python -random.shuffle
Methode.Die Vorgestellte Lösung in diese Antwort funktioniert, aber es könnte problematisch mit dem Speicher, wenn die Stichprobe klein ist, aber die Bevölkerung ist riesig (z.B.
random.sample(insanelyLargeNumber, 10)
).Um das zu beheben, würde ich mit diesem:
So, ich weiß dieser Beitrag ist 6 Jahre alt, aber es gibt auch eine Antwort (meist) besser Algorithmische Leistung, obwohl weniger praktisch mit größeren overhead.
Anderen Antworten: die shuffle-Methode und die 'versuchen, bis gültige" Methode mit Sätzen.
Wenn wir die zufällige Auswahl von K zahlen ohne Ersatz aus dem Intervall 0...N-1, dann ist der shuffle-Methode nutzt O(N) Speicher und O(N) Operationen, das ist ärgerlich, wenn wir wählen kleine K aus großen N. Die set-Methode verwendet nur O(K) Speicher, aber hat worst-case O(inf) erwartet O(n*log(n)) für K in der Nähe N. (sich Vorstellen, versuchen, nach dem Zufallsprinzip Holen Sie sich die Letzte Zahl aus zwei zulässige Antworten, nachdem bereits ausgewählt 999998, für k=n-1=10^6).
Damit die set-Methode ist gut für K~1, und die shuffle-Methode ist gut für die K~N. Beide erwartet >K RNG-Aufrufe.
Andere Weise; Sie kann vorgeben zu tun, der Fisher–Yates-shuffle, und für jedes neue random-Auswahl, führen Sie eine binäre Suchoperation auf Ihre bereits ausgewählten Elemente um den Wert zu finden, dass Sie würde bekommen, wenn Sie tatsächlich speichern ein array mit allen Elementen, die Sie noch nicht gewählt noch nicht.
Wenn Ihr bereits gewählten Werte sind [2,4], und Ihre random number generator spuckt 2 im Intervall (N - num_already_selected), dann wird Sie so tun, wählen Sie aus [0,1,3,5,6,...] durch zählen der Werte weniger als die Antwort, die bereits ausgewählt wurden. In diesem Fall werden Ihre Dritten ausgewählten Wert wäre 3. Dann, im nächsten Schritt, wenn Ihr Zufallszahl wurden 2 wieder, würde es anzeigen zu 5 (in den vorgeben Liste [0,1,5,6]), weil die (Potenzial-index von 5 in der sortierten Liste der bereits gewählten Werte [2,3,4], 3) + 2 = 5.
So speichern Sie die bereits ausgewählten Werte in einem ausgeglichenen binären Suchbaum, store den Rang (Anzahl der Werte kleiner als dieser Wert) an jedem Knoten, wählen Sie eine Zufallszahl R aus dem Bereich (0... n-(Anzahl bereits ausgewählt ist)). Dann steigen Sie den Baum wie bei der Suche, aber Ihr Wert ist R plus der Rang von welchem Knoten Sie sich befinden. Wenn Sie erreichen, ein Blatt-Knoten, fügen Sie die Zufallszahl in den Rang von Knoten, und legen Sie die Summe in die balanced binary tree.
Sobald Sie haben K Elemente, Lesen Sie aus dem Baum in ein array und mische (wenn die Reihenfolge wichtig ist).
Dauert dies O(K) Speicher, O(K*log(K)) die Leistung, und genau K randint Anrufe.
Beispiel Umsetzung der zufälligen Probenahme (nicht-zufällige endgültige Bestellung, aber Sie können O(K) shuffle nach), O(k) Speicher und O(klog^2(k) Hochleistungs - (nicht O(klog(k)) da können wir nicht custom-Abstieg ausgeglichene binäre Bäume für diese Implementierung):
Und zu zeigen, Gültigkeit:
Wenn wir Taten das fisher-yates-shuffle, nachdem er bereits gewählt [1,4,6,7,8,9,15,16], random-Nummer 5, unser noch-zu-sein-gewählt array würde wie folgt Aussehen [0,2,3,5,10,11,12,...], so dass die element 5 ist 11. Damit sind unsere binsearch-Funktion zurückkehren sollte, 11, 5 und [1,4,6,7,8,9,15,16]:
Inverse von [1,2,3] ist [0,4,5,6,7,8,...], das 5. element, die ist 8, also:
Inverse von [2,3,5] ist [0,1,4,6,...], 1. element, die (noch) 1, also:
Inverse ist [0,6,7,8,...], 3. element 8, und:
Und zum test der Allgemeinen Funktion:
In der Praxis, obwohl, verwenden Sie die shuffle-Methode für die K ~> N/2 und die set-Methode für die K ~< N/2.
edit: Hier ist ein weiterer Weg, es zu tun mit Rekursion! O(k*log(n)), denke ich.
sortedcontainers
Modul? Ich habe versucht mit dem code auf Python2.7 und Python ist3.6, aber es existiert nicht, entweder.sample(4,2)
, aber ich kann nur 6 der 16 möglichen Lösungen. Ich bin mir nicht sicher, was passiert.Wenn Sie brauchen, um eine Probe von extrem großen zahlen, die Sie nicht verwenden können
range
weil es wirft:
Auch, wenn
random.sample
können nicht die Anzahl der Elemente, die Sie wollen wegen der Bereich zu kleinwirft:
Diese Funktion löst beide Probleme:
Nutzung mit extrem großen zahlen:
Beispiel-Ergebnis:
Nutzung, wo das Angebot kleiner ist als die Anzahl der angeforderten Elemente:
Beispiel-Ergebnis:
Er arbeitet auch mit negativen Bereichen und Stufen:
Beispiel-Ergebnisse:
Wenn die Liste von N zahlen von 1 bis N wird zufällig generiert, dann ja, es besteht die Möglichkeit, dass einige zahlen wiederholt werden können.
Wenn Sie möchten, eine Liste der zahlen von 1 bis N in zufälliger Reihenfolge füllen eines Arrays mit Ganzzahlen von 1 bis N, und verwenden Sie dann eine Fisher-Yates-shuffle oder Python ' s
random.shuffle()
.Linear Congruential Pseudo-random Number Generator
Dieses problem kann gelöst werden mit einem einfachen Linear Congruential Generator. Dies erfordert eine ständige Speicher-overhead (8 ganze zahlen) und in den meisten 2*(Sequenz, Länge) Berechnungen.
Alle anderen Lösungen verwenden, die mehr Speicher und mehr berechnen! Wenn Sie nur ein paar random-Sequenzen, wird diese Methode deutlich günstiger. Für die Bereiche der Größe
N
, wenn Sie wollen, zu generieren in der Größenordnung vonN
einzigartigek
-Sequenzen oder mehr, empfehle ich die akzeptierte Lösung unter Verwendung des builtin-Methodenrandom.sample(range(N),k)
als diese optimiert wurde in python für die Geschwindigkeit.Code
Nutzung
Durch die Nutzung dieser Funktion "random_range" ist das gleiche wie bei jedem generator (wie "range"). Ein Beispiel:
Beispiel-Ergebnisse
prime
, die Funktion liefert dann nur mir 4 mögliche Antworten, weilvalue
ist das nur zufällig gewählt, was mit der 4 möglichen Werte, wenn wir Sie brauchen mindestens (4 auswählen, 2) = 6, (so dass für nicht-zufällige Reihenfolge).random_range(2,4)
wird, die Werte zurückgeben {(1, 0), (3, 2), (2, 1), (0, 3)}, aber nie das paar (3,1) (oder (1,3)). Erwarten Sie neue, zufällig generierte große Primzahlen jedem Funktionsaufruf?random_range(v)
zurück bis zuv
einzigartige Sequenzen stattv!
)Können Sie Numpy Bibliothek für die schnelle Antwort-wie unten gezeigt -
Bestimmten code-snippet Listen unten 6 einzigartige zahlen, die zwischen den Bereich von 0 bis 5. Können Sie die Parameter für Ihren Komfort.
Ausgabe
Es keine Einschränkungen, wie wir sehen, im random.Probe im Sinne von hier.
Hoffe, das hilft ein bisschen.
Wenn Sie sicherstellen möchten, dass die zahlen, die Hinzugefügt einzigartig sind, könnten Sie ein Set-Objekt
wenn mit 2.7 oder höher ist, oder importieren Sie die sets Modul, wenn nicht.
Wie andere erwähnt haben, dies bedeutet, dass die zahlen nicht wirklich zufällig.
Haben eine sehr einfache Funktion, die auch Ihr problem löst
Die Antwort hier funktioniert sehr gut in Bezug auf Zeit
sowie Speicher, aber ein bisschen mehr kompliziert, wie es verwendet fortgeschrittene python
Konstrukte wie Ertrag. Die einfacher Antwort, funktioniert in der Praxis aber das Problem mit, dass
die Antwort ist, dass es erzeugen kann viele falsche ganze zahlen, bevor Sie tatsächlich gebaut
die erforderliche set. Probieren Sie es aus mit populationSize = 1000, sampleSize = 999.
In der Theorie gibt es eine chance, dass es nicht kündigen.
Die Antwort unten Adressen sowohl Probleme, als es deterministisch ist und etwas effizienter
obwohl derzeit nicht so effizient wie die anderen beiden.
wobei die Funktionen getElem, percolateUp sind, wie unten definiert,
Schließlich, das timing im Durchschnitt war etwa 15ms für einen großen Wert von n, wie unten gezeigt,
Das problem mit dem set-basierte Ansätze ("wenn zufälliger Wert in die Werte zurückgeben, versuchen Sie es erneut") ist, dass Ihre Laufzeit ist unbestimmt durch Kollisionen (bei dem eine "try again" iteration), vor allem, wenn eine große Menge von zufälligen Werten, die zurückgegeben werden aus der Palette.
Alternative, die nicht anfällig für diese nicht-deterministische Laufzeit ist folgende:
print len(result), len(set(result))
. Würden Sie erwarten, zu sehen, dassresult
hätte, einzigartige Elemente, die nur einmal alle1.0851831788708547256608362340568947172111832359638926... × 10^20
versucht.Vom CLI im win xp:
In Kanada haben wir die 6 aus 49 Lotto. Ich nur wickeln Sie den oben genannten code im lotto.bat, und führen Sie
C:\home\lotto.bat
oder nurC:\home\lotto
.Weil
random.randint
wiederholt oft eine Nummer, die ich verwendenset
mitrange(7)
und dann kürzen Sie es auf eine Länge von 6.Gelegentlich, wenn sich eine Zahl wiederholt, mehr als 2 mal die resultierende Liste wird die Länge weniger als 6.
EDIT: Allerdings
random.sample(range(6,49),6)
ist der richtige Weg zu gehen.