844 Stimmen

Das Verständnis des "Zufalls"

Ich kann mir das nicht erklären, was ist zufälliger?

rand()

OR :

rand() * rand()

Ich finde es eine echte Denksportaufgabe, könnten Sie mir helfen?


EDITAR:

Intuitiv weiß ich, dass die mathematische Antwort lauten wird, dass sie gleichermaßen zufällig sind, aber ich kann mir nicht helfen, aber ich denke, dass, wenn man den "Zufallszahlenalgorithmus" zweimal laufen lässt, wenn man die beiden miteinander multipliziert, etwas Zufälligeres entsteht als wenn man es nur einmal macht.

5 Stimmen

Hier eine naive Definition für "Zufälliger": Für manche bedeutet "zufällig" "schwer zu erraten", z. B. den Wert der obersten Karte im Stapel zu erraten. Durch das Mischen des Stapels scheint es, dass der Zufallswert "noch schwerer zu erraten" ist, und von diesem praktischen, intuitiven Verständnis des Zufalls ausgehend, wäre es sinnvoll, den Stapel im Programm auf irgendeine Weise zu "mischen". Natürlich ist das nicht das, was "Zufall" bedeutet, und die Wissenschaft der Einführung von Entropie in einen pseudozufälligen Prozess ist nicht annähernd so einfach wie das Mischen des Prozesses mit seiner eigenen Ausgabe.

0 Stimmen

Danke @Yi Jiang und @Sam Saffron für die Korrekturen, ich bin eine Tippfehler-Maschine :)

0 Stimmen

@Mild Fuzz: Die Natur leugnet unendliche Unendlichkeiten? Sind das nicht Infinitesimale? Gibt es keine Fraktale in der Natur? Oder habe ich Ihre Aussage aufgrund meiner eigenen Dummheit völlig falsch verstanden?

9voto

Donal Fellows Punkte 125686

Es ist nicht ganz offensichtlich, aber rand() ist in der Regel zufälliger als rand()*rand() . Wichtig ist, dass dies für die meisten Verwendungszwecke eigentlich nicht sehr wichtig ist.

Aber erstens erzeugen sie unterschiedliche Verteilungen. Dies ist kein Problem wenn Sie das wollen, aber es ist wichtig. Wenn Sie eine bestimmte Verteilung benötigen, können Sie die Frage, welche Verteilung zufälliger ist, ignorieren. Warum ist also rand() mehr Zufall?

Der Kern des Warum rand() mehr zufällig ist (unter der Annahme, dass es Fließkommazahlen mit dem Bereich [0..1] erzeugt, was sehr üblich ist), ist, dass bei der Multiplikation von zwei FP-Zahlen mit vielen Informationen in der Mantisse ein gewisser Informationsverlust am Ende auftritt; es gibt einfach nicht genug Bits in einem IEEE Double-Precision Float, um alle Informationen zu speichern, die in zwei IEEE Double-Precision Floats waren, die gleichmäßig zufällig aus [0..1] ausgewählt wurden, und diese zusätzlichen Bits an Informationen gehen verloren. Natürlich ist das nicht so wichtig, da Sie diese Informationen (wahrscheinlich) nicht verwenden werden, aber der Verlust ist real. Es spielt auch keine Rolle, welche Verteilung Sie erzeugen (d. h. welche Operation Sie für die Kombination verwenden). Jede dieser Zufallszahlen hat (im besten Fall) 52 Bits an Zufallsinformationen - so viel kann ein IEEE-Doppelgänger enthalten - und wenn Sie zwei oder mehr zu einer kombinieren, haben Sie immer noch höchstens 52 Bits an Zufallsinformationen.

Bei den meisten Verwendungen von Zufallszahlen wird nicht einmal annähernd so viel Zufälligkeit verwendet, wie in der Zufallsquelle tatsächlich vorhanden ist. Besorgen Sie sich einen guten PRNG und machen Sie sich nicht zu viele Gedanken darüber. (Der Grad der "Güte" hängt davon ab, was Sie damit machen; bei Monte-Carlo-Simulationen oder in der Kryptografie müssen Sie vorsichtig sein, aber ansonsten können Sie wahrscheinlich den Standard-PRNG verwenden, da dieser normalerweise viel schneller ist).

7voto

Huub Punkte 91

Die Multiplikation von Zahlen würde je nach Computerarchitektur zu einem kleineren Lösungsbereich führen.

Wenn das Display Ihres Computers 16 Ziffern anzeigt rand() wäre etwa 0,1234567890123 multipliziert mit einer Sekunde rand() , 0,1234567890123, würde 0,0152415 etwas ergeben Sie würden definitiv weniger Lösungen finden, wenn Sie das Experiment 10^14 Mal wiederholen würden.

7voto

Fordi Punkte 2630

Fließkommazahlen basieren im Allgemeinen auf einem Algorithmus, der eine ganze Zahl zwischen Null und einem bestimmten Bereich erzeugt. Wenn Sie also rand()*rand() verwenden, sagen Sie im Wesentlichen int_rand()*int_rand()/rand_max^2 - das heißt, Sie schließen jede Primzahl / rand_max^2 aus.

Das verändert die zufällige Verteilung erheblich.

rand() ist auf den meisten Systemen gleichmäßig verteilt und schwer vorhersehbar, wenn sie richtig gesetzt wird. Verwenden Sie diese Methode, es sei denn, Sie haben einen besonderen Grund, sie zu berechnen (z. B. die Verteilung an eine benötigte Kurve anzupassen).

3voto

user479538 Punkte 31

Die meisten dieser Verteilungen entstehen, weil man die Zufallszahl begrenzen oder normalisieren muss.

Wir normalisieren sie so, dass sie alle positiv sind, in einen Bereich passen und sogar in die Beschränkungen der Speichergröße für den zugewiesenen Variablentyp passen.

Mit anderen Worten, da wir den Zufallsaufruf zwischen 0 und X begrenzen müssen (X ist die Größengrenze unserer Variablen), werden wir eine Gruppe von "zufälligen" Zahlen zwischen 0 und X haben.

Wenn man nun die Zufallszahl zu einer anderen Zufallszahl addiert, wird die Summe irgendwo zwischen 0 und 2X liegen... das verzerrt die Werte weg von den Randpunkten (die Wahrscheinlichkeit, zwei kleine Zahlen und zwei große Zahlen zu addieren, ist sehr gering, wenn man zwei Zufallszahlen über einen großen Bereich hat).

Stellen Sie sich vor, Sie hätten eine Zahl, die nahe bei Null liegt, und Sie addieren sie mit einer anderen Zufallszahl, die mit Sicherheit größer wird und sich von 0 entfernt (dies gilt auch für große Zahlen, da es unwahrscheinlich ist, dass zwei große Zahlen (Zahlen nahe bei X) von der Zufallsfunktion zweimal zurückgegeben werden.

Wenn Sie nun die Zufallsmethode mit negativen und positiven Zahlen (die sich gleichermaßen über die Nullachse erstrecken) einrichten würden, wäre dies nicht mehr der Fall.

Sagen wir zum Beispiel RandomReal({-x, x}, 50000, .01) dann würde man eine gleichmäßige Verteilung der Zahlen auf der negativen und der positiven Seite erhalten, und wenn man die Zufallszahlen zusammenzählen würde, würden sie ihre "Zufälligkeit" behalten.

Nun bin ich mir nicht sicher, was mit dem Random() * Random() mit der Spanne von negativ zu positiv... das wäre ein interessantes Diagramm... aber ich muss jetzt wieder Code schreiben. :-P

2voto

Tom Punkte 29
  1. Es gibt nicht so etwas wie mehr zufällig. Es ist entweder zufällig oder nicht. Zufällig bedeutet "schwer vorhersehbar". Es bedeutet nicht "nicht-deterministisch". Sowohl random() als auch random() * random() sind gleichermaßen zufällig, wenn random() zufällig ist. Die Verteilung ist für die Zufälligkeit unerheblich. Wenn eine ungleichmäßige Verteilung auftritt, bedeutet dies lediglich, dass einige Werte wahrscheinlicher sind als andere; sie sind immer noch unvorhersehbar.

  2. Da es sich um einen Pseudo-Zufall handelt, sind die Zahlen sehr deterministisch. In Wahrscheinlichkeitsmodellen und Simulationen ist der Pseudozufall jedoch oft ausreichend. Es ist hinlänglich bekannt, dass ein Pseudo-Zufallszahlengenerator, wenn man ihn kompliziert macht, nur noch schwerer zu analysieren ist. Es ist unwahrscheinlich, dass die Zufälligkeit dadurch verbessert wird; oft führt es dazu, dass er bei statistischen Tests versagt.

  3. Die gewünschten Eigenschaften der Zufallszahlen sind wichtig: Wiederholbarkeit und Reproduzierbarkeit, statistische Zufälligkeit, (in der Regel) gleichmäßig verteilt und eine große Periode sind einige davon.

  4. Bezüglich der Transformationen von Zufallszahlen: Wie bereits gesagt, ergibt die Summe von zwei oder mehr gleichmäßig verteilten Zahlen eine Normalverteilung. Dies ist die Zusatzstoff zentralen Grenzwertsatzes. Er gilt unabhängig von der Quellenverteilung, solange alle Verteilungen unabhängig und identisch sind. Die multiplikativ Der zentrale Grenzwertsatz besagt, dass das Produkt von zwei oder mehr unabhängigen und gleichverteilten Zufallsvariablen lognormal ist. Der von jemand anderem erstellte Graph sieht exponentiell aus, ist aber in Wirklichkeit lognormal. random() * random() ist also lognormalverteilt (auch wenn es möglicherweise nicht unabhängig ist, da die Zahlen aus demselben Strom gezogen werden). Dies kann in einigen Anwendungen wünschenswert sein. In der Regel ist es jedoch besser, eine Zufallszahl zu erzeugen und sie in eine lognormalverteilte Zahl umzuwandeln. Random() * random() kann schwierig zu analysieren sein.

Weitere Informationen finden Sie in meinem Buch unter www.performorama.org. Das Buch befindet sich noch im Aufbau, aber das relevante Material ist vorhanden. Beachten Sie, dass sich die Nummern der Kapitel und Abschnitte im Laufe der Zeit ändern können. Kapitel 8 (Wahrscheinlichkeitsrechnung) - Abschnitte 8.3.1 und 8.3.3, Kapitel 10 (Zufallszahlen).

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X