Frage

Okay, das nervte mich seit einigen Jahren jetzt. Wenn Sie in der Statistik und höhere Mathematik in der Schule angesaugt, abwendet, jetzt . Zu spät.

Okay. Tief durchatmen. Hier sind die Regeln. Nehmen Sie zwei dreißig seitige Würfel (ja, sie existieren ) und rollen sie sie gleichzeitig.

  • Fügen Sie die beiden Zahlen
  • Wenn beide Würfel zeigen <= 5 oder> = 26, werfen wieder und in das Ergebnis zu dem, was Sie haben
  • Wenn man <= 5 und die andere> = 26, wirft wieder und subtrahiert das Ergebnis von dem, was Sie haben
  • Wiederholen, bis entweder> 5 und <26

Wenn Sie einen Code (siehe unten) schreiben, rollt diejenigen Würfel ein paar Millionen Mal und Sie zählen, wie oft Sie jede Zahl als das Endergebnis erhalten, erhalten Sie eine Kurve, die ziemlich flach links von 1 ist, um 45 ° Grad zwischen 1 und 60 und flach über 60. Die Chance 30,5 oder besser zu rollen, ist größer als 50%, zu rollen besser als 18 bis 80% und besser zu rollen als 0 ist 97%.

Nun ist die Frage: Ist es möglich, ein Programm zu berechnet die genau f (x), dh die Wahrscheinlichkeit, schreibt einen bestimmten Wert zu rollen

Hintergrund: Für unser Rollenspiel „Jungle of Stars“ haben wir einen Weg sahen zufällige Ereignisse in Schach zu halten. Die oben genannten Regeln garantieren eine wesentlich stabilere Ergebnis für etwas, das Sie versuchen:)

Für die Geeks um, wird der Code in Python:

import random
import sys

def OW60 ():
    """Do an open throw with a "60" sided dice"""
    val = 0
    sign = 1

    while 1:
        r1 = random.randint (1, 30)
        r2 = random.randint (1, 30)

        #print r1,r2
        val = val + sign * (r1 + r2)
        islow = 0
        ishigh = 0
        if r1 <= 5:
            islow += 1
        elif r1 >= 26:
            ishigh += 1
        if r2 <= 5:
            islow += 1
        elif r2 >= 26:
            ishigh += 1

        if islow == 2 or ishigh == 2:
            sign = 1
        elif islow == 1 and ishigh == 1:
            sign = -1
        else:
            break

        #print sign

    #print val
    return val

result = [0] * 2000
N = 100000
for i in range(N):
    r = OW60()
    x = r+1000
    if x < 0:
        print "Too low:",r
    if i % 1000 == 0:
        sys.stderr.write('%d\n' % i)
    result[x] += 1

i = 0
while result[i] == 0:
    i += 1

j = len(result) - 1
while result[j] == 0:
    j -= 1

pSum = 0
# Lower Probability: The probability to throw this or less
# Higher Probability: The probability to throw this or higher
print "Result;Absolut Count;Probability;Lower Probability;Rel. Lower Probability;Higher Probability;Rel. Higher Probability;"
while i <= j:
    pSum += result[i]
    print '%d;%d;%.10f;%d;%.10f;%d;%.10f' % (i-1000, result[i], (float(result[i])/N), pSum, (float(pSum)/N), N-pSum, (float(N-pSum)/N))
    i += 1
War es hilfreich?

Lösung

Ich musste zuerst den Code neu schreiben, bevor ich es verstehen konnte:

def OW60(sign=1):
    r1 = random.randint (1, 30)
    r2 = random.randint (1, 30)
    val = sign * (r1 + r2)

    islow  = (r1<=5)  + (r2<=5)
    ishigh = (r1>=26) + (r2>=26)

    if islow == 2 or ishigh == 2:
        return val + OW60(1)
    elif islow == 1 and ishigh == 1:
        return val + OW60(-1)
    else:
        return val

Vielleicht finden Sie vielleicht diese weniger lesbar; Ich weiß es nicht. (Sie überprüfen, ob es entspricht dem, was Sie im Sinn hatte.) Auch in Bezug auf die Art und Weise Sie „Ergebnis“ in Ihrem Code verwenden - kennen Sie Pythons dict s?

Wie auch immer, Sachen Programmierstil beiseite: Angenommen, F (x) ist das CDF OW60 (1), dh

F(x) = the probability that OW60(1) returns a value ≤ x.

Ebenso lassen

G(x) = the probability that OW60(-1) returns a value ≤ x.

Dann können Sie F (x) aus der Definition berechnen, indem alle Summieren über (30 × 30) mögliche Werte des Ergebnisses des ersten Wurfes. Zum Beispiel, wenn der erste Wurf (2,3), dann werden Sie wieder rollen, so dass dieser Begriff dazu beiträgt (30.01) (30.01) (5 + F (x-5)) mit dem Ausdruck für F ( X). So werden Sie einig obszön langen Ausdruck erhalten wie

F(x) = (1/900)(2+F(x-2) + 3+F(x-3) + ... + 59+F(x-59) + 60+F(x-60))

, der eine Summe über 900 Begriffe ist, eine für jedes Paar (a, b) in [30] × [30]. Die Paare (a, b) sowohl mit ≤ 5 oder ≥ 26 sowohl einen Term a hat + b + F (XAB), wobei die Paare mit einem ≤5 und ein ≥26 hat eine Laufzeit a + b + G (XAB), und der Rest hat einen Begriff wie (a + b), weil Sie nicht wieder werfen.

Ebenso haben Sie

G(x) = (1/900)(-2+F(x-2) + (-3)+F(x-3) + ... + (-59)+F(x-59) + (-60)+F(x-60))

Natürlich können Sie Koeffizienten sammeln; F die einzigen Bedingungen, die auftreten, sind von F (x-60) bis F (x-52) und aus F (x-10) bis F (x-2) (für ein, b≥26 oder both≤5) und G die einzigen Bedingungen, die auftreten, sind von G (x-35) bis G (x-27) (für eine der Gruppen a, und den anderen b≥26 ≤5), so gibt es weniger als 30 Begriffe Begriffe. In jedem Fall definiert, den Vektor V (x) als

V(x) = [F(x-60) G(x-60) ... F(x-2) G(x-2) F(x-1) G(x-1) F(x) G(x)]

(sagen wir), Sie haben (aus diesen Ausdrücken für F und G) eine Beziehung der Form

V(x) = A*V(x-1) + B

für eine geeignete Matrix A und eine geeigneten Vektor B (die man berechnen kann), so von den Anfangswerten der Form V beginnend (x) = [0 0] für x hinreichend klein ist, kann man finden, F (x) und G (x) für x im Bereich möchten Sie beliebig nahe Präzision. (Und Ihre f (x), die Wahrscheinlichkeit von x zu werfen, ist nur F (x) -F (x-1), so dass auch herauskommt.)

Es könnte ein besserer Weg geben. Alle gesagt und getan, aber, warum tust du das? Unabhängig von der Art der Verteilung Sie wollen, gibt es schöner und einfache Wahrscheinlichkeitsverteilungen, mit den entsprechenden Parametern, die guten Eigenschaften aufweisen (zum Beispiel kleine Abweichung einseitige Fehler, was auch immer). Es gibt keinen Grund, Ihr eigenes Ad-hoc-Verfahren, um bis zu Zufallszahlen zu erzeugen.

Andere Tipps

Ich habe einige grundlegenden Statistiken an einer Probe durchgeführt von 20 Millionen werfen. Hier sind die Ergebnisse:

Median: 17 (+18, -?) # This result is meaningless
Arithmetic Mean: 31.0 (±0.1)
Standard Deviation: 21 (+1, -2)
Root Mean Square: 35.4 (±0.7)
Mode: 36 (seemingly accurate)

Die Fehler wurden experimentell bestimmt. Das arithmetische Mittel und der Modus ist wirklich genau, und ganz auch aggressiv die Parameter zu ändern scheint sie nicht viel zu beeinflussen. Ich nehme an, das Verhalten des Median bereits erläutert.

Hinweis: nehmen Sie nicht diese Zahl für eine korrekte mathematische Beschreibung der Funktion. Verwenden Sie sie, um schnell ein Bild von dem, was die Verteilung aussieht. Für alles andere, sind sie nicht genau genug (obwohl sie genau sein könnten.

Vielleicht ist dies hilfreich für jemanden.

Edit 2:

Graph

Basierend auf nur 991 Werte. Ich hätte mehr Werte hineingestopft, aber sie würden das Ergebnis verzerrt haben. Diese Probe geschieht ziemlich typisch.

Bearbeiten 1:

hier sind die oben genannten Werte für nur einen sechzigseitigen Würfel, zum Vergleich:

Median: 30.5
Arithmetic Mean: 30.5
Standard Deviation: 7.68114574787
Root Mean Square: 35.0737318611

Beachten Sie, dass diese Werte berechnet werden, nicht experimentell.

Die Verbindung unbegrenzt Wahrscheinlichkeit ist ... nicht trivial. Ich würde das Problem auf die gleiche Weise wie James Curran in Angriff zu nehmen, aber dann sah ich aus dem Quellcode, dass es einen dritten Satz von Walzen sein könnte, und eine vierte, und so weiter. Das Problem ist lösbar, aber weit über die meisten sterben Roll Simulatoren.

Gibt es einen besonderen Grund, dass Sie einen zufälligen Bereich von -Inf bis + Inf müssen mit einer solchen komplexen Kurve um 1-60? Warum ist die Glockenkurve von 2D30 nicht akzeptabel? Wenn Sie Ihre Anforderungen erklären, ist es wahrscheinlich jemand einen einfacheren und beschränkten Algorithmus bieten könnte.

Nun, mal sehen. Die zweiten throw (die manchmal hinzugefügt oder auf die erste Rolle abgezogen wird) hat eine schöne leicht vorhersehbar Glockenkurve um 31. Die erste Rolle, natürlich, ist das Problem.

Für die erste Rolle, wir haben 900 mögliche Kombinationen.

  • 50 Kombinationen ergeben die zweite Rolle in hinzuzufügen.
  • 25 Kombinationen ergeben die zweite Rolle in subtrahiert wird.
  • Verlassen 825 Kombinationen, die die Glockenkurve der zweiten Walze entsprechen.

Der Subtraktionseinheit Satz (pre-Subtraktion) eine Glockenkurve im Bereich (27..35) bilden. Die untere Hälfte des Zugabe wird Satzes eine Glockenkurve im Bereich (2..10) bilden, während die obere Hälfte wird in dem Bereich (52 ... 60)

eine Glockenkurve bilden

Meine probablity ist ein bisschen rostig, so kann ich die genauen Werte für Sie nicht verstehen, aber es soll, dass diese führen zu vorhersagbaren Werten klar sein.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top