Pólya Urne drehen und rollen


13

Problemstellung

Pólya spielt wieder mit seiner Urne und möchte, dass Sie ihm bei der Berechnung einiger Wahrscheinlichkeiten helfen.

In diesem Urnenexperiment hat Pólya eine Urne, die zunächst 1 rote und 1 blaue Perle enthält.

Bei jeder Iteration greift er zu und holt eine Perle heraus, inspiziert dann die Farbe und legt die Perle zurück in die Urne.

Er wirft dann eine helle Münze um. Wenn die Münze auf dem Kopf landet, wirft er eine helle 6-seitige Würfelwurfmenge der gleichen Farbe in die Urne. Wenn sie auf dem Schwanz landet, entfernt er die Hälfte der gleichen Farbe aus der Urne. Verwenden der Ganzzahlteilung - Wenn also die Anzahl der Perlen der ausgewählten Farbe ungerade ist, entfernt er, (c-1)/2wobei c die Anzahl der Perlen dieser Farbe ist.

Geben Sie bei einer Ganzzahl n ≥ 0 und einer Dezimalzahl r> 0 die Wahrscheinlichkeit mit 2 Dezimalstellen an, dass das Verhältnis zwischen den Farben der Kügelchen nach n Iterationen in der kürzesten Anzahl von Bytes größer oder gleich r ist.

Ein Beispielsatz von Iterationen:

Lassen Sie (x, y) die Urne so definieren, dass sie x rote Perlen und y blaue Perlen enthält.

Iteration    Urn       Ratio
0            (1,1)     1
1            (5,1)     5        //Red bead retrieved, coin flip heads, die roll 4
2            (5,1)     5        //Blue bead retrieved, coin flip tails
3            (3,1)     3        //Red bead retrieved, coin flip tails
4            (3,4)     1.333... //Blue bead retrieved, coin flip heads, die roll 3

Wie zu sehen ist, ist das Verhältnis r immer ≥ 1 (also das Größere aus Rot oder Blau geteilt durch das Kleinere).

Testfälle:

F (n, r) definiere die Anwendung der Funktion für n Iterationen und ein Verhältnis von r

F(0,5) = 0.00
F(1,2) = 0.50
F(1,3) = 0.42
F(5,5) = 0.28
F(10,4) = 0.31
F(40,6.25) = 0.14

Dies ist Codegolf, daher gewinnt die kürzeste Lösung in Bytes.


Ich habe das Gefühl, es gibt eine Formel dafür ...
Verkörperung der Ignoranz

Etwas, das vielleicht mit Beta-Binomialzahlen zu tun hat, aber es könnte länger dauern, das auszuschreiben
Abgelaufene Daten

hängt von der Sprache ab; R und Mathematica sind möglicherweise in der Lage, dies effizient auszuführen.
Giuseppe

Antworten:


6

JavaScript (ES7),  145 ... 129 124  123 Byte

Übernimmt die Eingabe als (r)(n). Dies ist eine naive Lösung, die die gesamte Simulation ausführt.

r=>g=(n,B=s=0,R=0,h=d=>++d<7?h(d,[0,d].map(b=>g(n,B/-~!!b,R/-~!b)&g(n,B+b,R+d-b))):s/24**-~n)=>n--?h``:s+=~B<=r*~R|~R<=r*~B

Probieren Sie es online!

Zu langsam für die letzten 2 Testfälle.

Kommentiert

r =>                    // r = target ratio
g = (                   // g is a recursive function taking:
  n,                    //   n = number of iterations
  B =                   //   B = number of blue beads, minus 1
  s = 0,                //   s = number of times the target ratio was reached
  R = 0,                //   R = number of red beads, minus 1
  h = d =>              //   h = recursive function taking d = 6-sided die value
    ++d < 7 ?           // increment d; if d is less than or equal to 6:
      h(                //   do a recursive call to h:
        d,              //     using the new value of d
        [0, d].map(b => //     for b = 0 and b = d:
          g(            //       do a first recursive call to g:
            n,          //         leave n unchanged
            B / -~!!b,  //         divide B by 2 if b is not equal to 0
            R / -~!b    //         divide R by 2 if b is equal to 0
          ) & g(        //       do a second recursive call to g:
            n,          //         leave n unchanged
            B + b,      //         add b blue beads
            R + d - b   //         add d - b red beads
          )             //       end of recursive calls to g
        )               //     end of map()
      )                 //   end of recursive call to h
    :                   // else (d > 6):
      s / 24 ** -~n     //   stop recursion and return s / (24 ** (n + 1))
) =>                    // body of g:
  n-- ?                 //   decrement n; if n was not equal to 0:
    h``                 //     invoke h with d = [''] (coerced to 0)
  :                     //   else:
    s +=                //     increment s if:
      ~B <= r * ~R |    //       either (-B-1) <= r*(-R-1), i.e. (B+1)/(R+1) >= r
      ~R <= r * ~B      //       or     (-R-1) <= r*(-B-1), i.e. (R+1)/(B+1) >= r

Diese Antwort gefällt mir sehr gut. Um die späteren Testfälle zu lösen, musste ich Code hinzufügen, um die gleichen Verhältniswahrscheinlichkeiten zusammenzuführen. Ich bin also nicht überrascht, dass es zu langsam ist
abgelaufene Daten

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.