Pólya urn flip and roll


13

Énoncé du problème

Pólya joue à nouveau avec son urne et il veut que vous l'aidiez à calculer certaines probabilités.

Dans cette expérience sur l'urne, Pólya a une urne qui contient initialement 1 perle rouge et 1 perle bleue.

Pour chaque itération, il atteint et récupère une perle, puis inspecte la couleur et replace la perle dans l'urne.

Il lance ensuite une pièce équitable, si la pièce atterrit, il insérera un jet de dé à 6 faces équitable de la même perle de couleur dans l'urne, si elle atterrit, il enlèvera la moitié du nombre de la même perle de couleur de l'urne ( En utilisant la division entière - donc si le nombre de perles de la couleur sélectionnée est impair, il supprimera (c-1)/2où c est le nombre de perles de cette couleur)

Étant donné un entier n ≥ 0 et une décimale r> 0, donnez la probabilité à 2 décimales que le rapport entre les couleurs des perles après n itérations soit supérieur ou égal à r dans le nombre d'octets le plus court.

Un exemple d'ensemble d'itérations:

Soit (x, y) la définition de l'urne telle qu'elle contienne x perles rouges et y perles bleues.

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

Comme on peut le voir, le rapport r est toujours ≥ 1 (c'est donc le plus grand du rouge ou du bleu divisé par le moins)

Cas de test:

Soit F (n, r) définir l'application de la fonction pour n itérations et un rapport de 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

C'est le golf de code, donc la solution la plus courte en octets l'emporte.


J'ai l'impression qu'il existe une formule pour cela ...
Incarnation de l'ignorance

Quelque chose à voir avec les binômes bêta peut-être, mais cela pourrait être plus long à écrire
Expired Data

dépend de la langue; R et Mathematica pourraient le faire efficacement.
Giuseppe

Réponses:


6

JavaScript (ES7),  145 ... 129124123  octets

Prend l'entrée comme (r)(n). Il s'agit d'une solution naïve qui effectue en fait toute la simulation.

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

Essayez-le en ligne!

Trop lent pour les 2 derniers cas de test.

Commenté

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

J'aime vraiment cette réponse, j'ai trouvé que pour résoudre les cas de test ultérieurs, j'avais besoin d'ajouter du code pour fusionner les mêmes probabilités de rapport. Je ne suis donc pas surpris que ce soit trop lent
Expired Data

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.