[PYTHON] Das Ende der katastrophalen Programmierung # 02 "Es ist schwer, 5 und 6 Würfel zu bekommen ... Ich denke, es ist eine Zufallszahlenüberlegung."

Das Ende der katastrophalen Programmierung # 02 "Es ist schwer, 5 und 6 Würfel zu bekommen ... Ich denke, es ist eine Zufallszahlenüberlegung."

Ein gewöhnlicher Programmierer versteht es intuitiv und reflexiv. Ich möchte einen Artikel über eine rudimentäre und einfache Geschichte schreiben. Es ist rudimentär, aber ich bin ein starker Programmierer, also mache ich es oft. Ich werde eine kleine Geschichte als Gebot für mich selbst schreiben.

Wenn es Fehler oder unangemessene Inhalte gibt, kommentieren Sie bitte Wir werden Korrekturen und Anpassungen des Inhalts berücksichtigen.

1. Zufällig

Wie Random.nextInt (), Ich denke, viele Programmierer haben die Methode verwendet, um den Zufallswert zu erhalten.

Eine Funktion oder Methode, die eine Zufallszahl von ganzzahligen Werten erhält, die größer oder gleich 0 und kleiner oder gleich 9 sind, ist beispielsweise Für Java Random.nextInt (10), Für C # Random.Next (10), Für Python wäre es "random.randint (0, 9)".

Für viele Programmierer ist die Art und Weise, wie Zufallszahlen gestreut werden, und ihre Periodizität Je frustrierender Sie sich manchmal fühlen, desto voreingenommener sind die Werte.

Die meiste Zeit beschäftigen wir uns normalerweise mit Pseudozufallszahlen, Zufällige Werte werden vom Algorithmus generiert. Abhängig vom verwendeten Algorithmus (intern verwendet) gibt es verschiedene Macken. Dieses Mal werde ich diesen Punkt vorerst verlassen.

(** Wenn nicht zur Verschlüsselung, ** Aufgrund seiner Variation und der Länge der Periodizität ist meine persönliche Empfehlung Eine von Mercenne Twister generierte Zufallszahl. )

Der folgende Artikel ist ein Beispiel für Java, aber ich denke, es ist ** dasselbe für andere Sprachen **. Der Teil von rand.nextInt (10) Wenn Sie es als "rand.Next (10)" für C #, "random.randint (0, 9)" für Python usw. lesen, können Sie es sich wahrscheinlich vorstellen.

2. Vorerst habe ich 10 Milliarden Mal versucht, mit Java zufällige Werte zu erhalten

Lassen Sie uns vorerst 10 Milliarden Mal mit Java einen zufälligen Wert erhalten. Verwenden Sie Random.nextInt (10), um die Zufallswerte von 0 bis 9 10 Milliarden Mal zu erhalten. Die Anzahl der Auftritte von jedem wurde gezählt.

Random rand = new Random();

long[] numCounter = new long[10];

for(long count = 0; count < 10000000000L; count++) {
  int value = rand.nextInt(10);
  numCounter[value]++;
}

** Das Ergebnis ist wie folgt. ** ** **

Wert des Wertes Anzahl der Auftritte
0 1,000,017,191
1 999,943,364
2 999,983,662
3 1,000,012,905
4 1,000,049,567
5 1,000,001,706
6 999,982,619
7 1,000,068,926
8 999,966,928
9 999,973,132

In Bezug auf die Variation ist es möglicherweise besser, sie mathematisch zu analysieren. Diesmal ist es keine Mathe-Sitzung, also treffen wir eine schnelle Entscheidung. Konzentrieren Sie sich nur auf die einfachen ** Vorkommen ** jeder Zahl für 10 Milliarden Versuche. Es scheint kein großes Problem zu geben.

In der Standard-Java-Implementierung werden Zufallszahlen durch die lineare Kongruenzmethode generiert. In Bezug auf diese Eigenschaften werde ich sie dieses Mal ins Regal stellen.

3. Sorgfältige Anpassungen der generierten Werte können katastrophale Folgen haben.

Für value von int value = rand.nextInt (10); Berechnen wir so, dass das Ergebnis das Ergebnis des Würfelns von 6 Würfeln ist. Der Grund, warum Sie es auf "rand.nextInt (6)" setzen sollten, ist ** diesmal kein gebundenes Spiel.

Wenn Sie int sainome = (Wert% 6) + 1; tun Es scheint, dass Sie 1 bis 6 der Würfel werfen können. Im Teil von "(Wert% 6)" ändert sich der Wert von "0" auf "5". Fügen Sie danach einfach einen nach den Würfeln hinzu.

Wenn Sie nach dem nächtlichen Spiel nicht genug Schlaf bekommen, scheint das in Ordnung zu sein, aber Diese Berechnung ist überhaupt nicht fair.

Wert von sainome Anzahl der Auftritte
1 1,999,999,810
2 2,000,012,290
3 1,999,979,833
4 1,999,986,037
5 1,000,049,567
6 1,000,001,706

Das 1. bis 4. Auge sind ungefähr 2 Milliarden Mal erschienen, Das 5. und 6. Auge sind nur etwa 1 Milliarde Mal erschienen, Es gibt ungefähr einen doppelten Unterschied.

4. Warum erschienen die 5 und 6 von Sagami nicht so oft ...

Dieses Mal habe ich es mit einer kleinen Anzahl versucht, daher denke ich, dass es leicht zu bemerken war. Sie können dies leicht herausfinden, indem Sie den Wertwert und den Wert (Wert% 6) nebeneinander anordnen.

Wert des Wertes (value % 6)Der Wert der
0 0
1 1
2 2
3 3
4 4
5 5
6 0
7 1
8 2
9 3

In der obigen Tabelle gibt es zwei "0, 1, 2, 3" als "(Wert% 6) Wert", Es gibt nur eine "4, 5". Das ist nicht fair.

5. Beenden

Zufällige Werte variieren manchmal frustrierend, Es kann noch katastrophaler sein, je nachdem, wie Sie Ihre Pflege hinzufügen (wenn Sie mehr Zufallszahlen berechnen möchten).

Dieses Beispiel betont die Leichtigkeit der Vorstellungskraft und ist daher ein ziemlich extremes Beispiel Tatsächlich kann es nur wenige Fälle geben, in denen Sie von etwas Ähnlichem wie dieser abhängig sind. Ich denke, es ist eine gute Idee, bei der Verwendung von Zufallszahlen immer wachsam zu sein.

6. Gegenmaßnahmen

In diesem Beispiel int value = rand.nextInt (6); ist in Ordnung, aber Lassen Sie uns über ** gebundenes Spiel ** nachdenken, dass rand.nextInt (6) nicht möglich ist.

Die Grenze für Fairness ist wahrscheinlich, ob der "Wertwert" "5 oder weniger" beträgt. Davon abgesehen scheint es ganz so, wenn man beurteilt, dass es unfair ist und den unfairen Wert ignoriert.

Betrachten Sie den Fall von "int value = rand.nextInt (1000);". value ist eine Zufallszahl von 0 bis 999. In diesem Fall beurteilen Sie, ob der "Wertwert" "5 oder weniger" ist. Wenn Sie "5 oder weniger als unfair" ignorieren, wird eine beträchtliche Anzahl ignoriert. Es wird ein ziemlich ineffizienter Algorithmus sein.

Was ignoriert werden sollte, liegt wahrscheinlich in der Nähe von "999".

Wert des Wertes (value % 6)Der Wert der
... ...
990 0
991 1
992 2
993 3
994 4
995 5
996 0
997 1
998 2
999 3

In diesem Fall ist bis zu 995 fair und ab 996 unfair.

Es sieht so aus, wenn es in den Algorithmus integriert ist.

  1. Finden Sie mit int group = (1000/6); heraus, wie viele faire Gruppen es gibt.
  2. Finden Sie den unfairen Mindestwert mit int unfairValueMin = (group * 6);.
  3. Überprüfen Sie den durch int value = rand.nextInt (1000); generierten Wert Wenn value <unfairValueMin`` true ist, wird es als fair beurteilt und angenommen. Davon abgesehen als unfair Generieren Sie erneut einen zufälligen Wert und wiederholen Sie die Überprüfung, um festzustellen, ob er fair ist.
  4. Finden Sie (Wert% 6) mit dem Wert, der als fair beurteilt wird.

Nun, es gibt viele Fälle, in denen es nicht notwendig ist, einen übermäßig fairen Wert zu finden. Anhand eines Beispiels wie diesem Im Gegenteil, es gibt auch eine Methode, um auf einfache Weise einen voreingenommenen Zufallszahlenwert durch Ihren eigenen Willen zu erzeugen.

Zum Beispiel im Beispiel der Ausgabe von "0 bis 5",

for(int i = 0; i < 100; i++) {
  int value = (rand.nextInt(6) + rand.nextInt(6)) / 2;

  System.out.println(value);
}

Und,

for(int i = 0; i < 100; i++) {
  int value = rand.nextInt(3) + rand.nextInt(4);

  System.out.println(value);
}

Und,

for(int i = 0; i < 100; i++) {
  int value = (rand.nextInt(6) + rand.nextInt(6) + rand.nextInt(6)) / 3;

  System.out.println(value);
}

Es kann Spaß machen, es tatsächlich zu bewegen oder darüber nachzudenken, was passiert. (Im letzten Code erscheint "5" selten, aber "2" und "3" sollten durcheinander erscheinen.)

Wie sehr Sie voreingenommen sind, hängt davon ab, wie Sie es tun. In der Praxis benötigen Sie möglicherweise eine strengere Methode.

Recommended Posts

Das Ende der katastrophalen Programmierung # 02 "Es ist schwer, 5 und 6 Würfel zu bekommen ... Ich denke, es ist eine Zufallszahlenüberlegung."
Das Ende der katastrophalen Programmierung # 04 "Fehlerhafter Ausnahmebereich"
Ich habe mir die Versionen von Blender und Python angesehen
Ich möchte die Natur von Python und Pip kennenlernen
[Einführung in Python] Ich habe die Namenskonventionen von C # und Python verglichen.
Ich habe zusammengefasst, wie die Boot-Parameter von GRUB und GRUB2 geändert werden
Ich untersuchte das Verhalten bezüglich des Unterschieds zwischen Hard Link und Symbolic Link
Ich habe mich sehr bemüht, die spektrale Normalisierung und die Singularwertzerlegung zu verstehen, die zur Stabilität von GAN beitragen.