In einer kleinen Anwendung, die in C / C ++ geschrieben wurde, habe ich ein Problem mit der rand
Funktion und möglicherweise dem Startwert:
Ich möchte eine Folge von Zufallszahlen erzeugen, die unterschiedliche Ordnungen haben, dh unterschiedliche Logarithmuswerte (Basis 2). Es scheint jedoch, dass alle produzierten Zahlen in derselben Größenordnung liegen und nur zwischen 2 ^ 25 und 2 ^ 30 schwanken.
Liegt es daran, dass rand()
Unix-Zeit verwendet wird, die mittlerweile eine relativ große Zahl ist? Was vergesse ich? Ich säe rand()
nur einmal am Anfang des main()
.
rand()
, gleichmäßig verteilte Zahlen zurückzugeben (Dokumentation mit hohem Google-Ranking sagt dies ausdrücklich aus), halte ich diese Frage für zukünftige Leser nicht für nützlich. Deshalb stimmen Sie ab, aber lassen Sie sich nicht davon abhalten, SO zu verwenden.Antworten:
Es gibt nur 3% der Zahlen zwischen 1 und 2 30, die NICHT zwischen 2 25 und 2 30 liegen . Das klingt also ziemlich normal :)
Da 2 25 /2 30 = 2 -5 = 1/32 = 0,03125 = 3,125%
quelle
>>
Bitverschiebung abzuschneiden - dies gibt Ihnen kleinere Zahlen. (Oder nehmen Sie einen Modul mit%
.)0
- und wenn jedes Bit zufällig ist ...Das hellere Grün ist der Bereich zwischen 0 und 2 25 ; Das dunklere Grün ist der Bereich zwischen 2 25 und 2 30 . Die Zecken sind Potenzen von 2.
quelle
Sie müssen genauer sein: Sie möchten unterschiedliche Logarithmuswerte für Basis 2, aber welche Verteilung möchten Sie dafür? Die Standardfunktionen von rand () erzeugen eine gleichmäßige Verteilung. Sie müssen diese Ausgabe mithilfe der Quantilfunktion transformieren, die der gewünschten Verteilung zugeordnet ist.
Wenn Sie uns die Verteilung mitteilen, können wir Ihnen die
quantile
Funktion mitteilen, die Sie benötigen.quelle
Wenn Sie unterschiedliche Größenordnungen wünschen, warum nicht einfach versuchen
pow(2, rand())
? Oder wählen Sie die Reihenfolge direkt als rand (), wie Harold vorgeschlagen hat?quelle
rand()
kann bis zu gehenRAND_MAX
, müssen Sie wirklich Ihre Zufallszahl skalieren, damit das Ergebnis nicht überläuft ...@ C4stor machte einen tollen Punkt. Für einen allgemeineren Fall, der für den Menschen leichter zu verstehen ist (Basis 10): Für den Bereich von 1 bis 10 ^ n liegen ~ 90% der Zahlen daher zwischen 10 ^ (n-1) und 10 ^ n ~ 99% der Zahlen gehen von 10 ^ (n-2) bis 10 ^ n. Fügen Sie so viele Dezimalstellen hinzu, wie Sie möchten.
Lustige Mathematik, wenn Sie dies für n fortsetzen, können Sie sehen, dass von 1 bis 10 ^ n, 99,9999 ...% = 100% der Zahlen mit dieser Methode von 10 ^ 0 bis 10 ^ n sind.
Wenn Sie nun eine Zufallszahl mit zufälligen Größenordnungen von 0 bis 10 ^ n für den Code wünschen, können Sie Folgendes tun:
Generieren Sie eine kleine Zufallszahl von 0 bis n
Wenn Sie den Bereich kennen, den n hat, generieren Sie eine große Zufallszahl der Ordnung 10 ^ k, wobei k> max {n} ist.
Schneiden Sie die längere Zufallszahl, um die n Ziffern dieser großen Zufallszahl zu erhalten.
quelle
Die grundlegende (und richtige) Antwort wurde bereits oben gegeben und akzeptiert: Es gibt 10 Zahlen zwischen 0 und 9, 90 Zahlen zwischen 10 und 99, 900 zwischen 100 und 999 usw.
Um eine rechnerisch effiziente Methode zum Erhalten einer Verteilung mit ungefähr logarithmischer Verteilung zu erhalten, möchten Sie Ihre Zufallszahl um eine Zufallszahl nach rechts verschieben:
Es ist nicht perfekt, aber viel schneller als das Rechnen
pow(2, rand()*scalefactor)
. Es wird in dem Sinne "klumpig" sein, dass die Verteilung für Zahlen innerhalb eines Faktors 2 gleichmäßig ist (einheitlich für 128 bis 255, die halbe Dichte für 256 bis 1023 usw.).Hier ist ein Histogramm der Häufigkeit der Zahlen 0 bis 31 (in 1M-Stichproben):
quelle
rand()>>(rand()&31);
würde man intuitiv erwarten, dass 1/32 der Zahlen 32 Bit und 1/32 der Zahlen 31 Bit und 1/32 der Zahlen 30 Bit usw. haben. Aber das ist es Nicht die Ergebnisse, die Sie erhalten, nur etwa 1/64 der Zahlen würden 32 Bit ergeben, während fast die Hälfte 0 sein sollte. Da meine mentale Mathematik nicht mit Ihren Messungen übereinstimmt, muss ich meine eigenen Messungen durchführen, um sie zu ermitteln das raus.Es gibt genau die gleiche Anzahl von Zahlen zwischen 0 und 2 ^ 29 und 2 ^ 29 und 2 ^ 30.
Eine andere Sichtweise auf das Problem: Betrachten Sie die binäre Darstellung der von Ihnen erzeugten Zufallszahl, die Wahrscheinlichkeit, dass das höchste Bit 1 ist, entspricht 1/2, und daher erhalten Sie in halben Fällen die Ordnung 29. Was Sie wollen, ist eine Zahl zu sehen, die unter 2 ^ 25 liegt, aber das bedeutet, dass 5 höchste Bits alle Null sind, was mit einer geringen Wahrscheinlichkeit von 1/32 geschieht. Es besteht die Möglichkeit, dass selbst wenn Sie es längere Zeit ausführen, die Reihenfolge unter 15 überhaupt nicht angezeigt wird (die Wahrscheinlichkeit ist ungefähr 6 bis 6 Mal hintereinander zu würfeln).
Nun der Teil Ihrer Frage zum Samen. Nein, der Startwert kann möglicherweise nicht den Bereich bestimmen, aus dem die Zahlen generiert werden, sondern nur das erste Anfangselement. Stellen Sie sich rand () als eine Folge aller möglichen Zahlen im Bereich vor (vorgegebene Permutation). Der Startwert bestimmt, wo Sie mit dem Zeichnen von Zahlen aus der Sequenz beginnen. Wenn Sie (Pseudo-) Zufälligkeit wünschen, verwenden Sie daher die aktuelle Zeit, um die Sequenz zu initialisieren: Es ist Ihnen egal, dass die Position, von der Sie ausgehen, nicht gleichmäßig verteilt ist. Alles, was zählt, ist, dass Sie nie von derselben Position aus starten.
quelle
Verwenden
pow(2,rand())
Sie es, um die Antworten in der Reihenfolge der gewünschten Größe zu geben!quelle
Wenn Sie Zufallszahlen aus einem Onlinedienst verwenden möchten, für den Sie wget verwenden können, möchten Sie möglicherweise sehen, dass Sie auch Dienste wie random.org für Ihre Zufallszahlengenerierung verwenden können. Sie können sie mit wget abfangen und dann die Zahlen von lesen die heruntergeladene Datei
http://programmingconsole.blogspot.in/2013/11/a-better-and-different-way-to-generate.html
quelle