Pólya urn flip and roll


13

Declaração do problema

Pólya está brincando com sua urna novamente e ele quer que você o ajude a calcular algumas probabilidades.

Neste experimento de urna, Pólya possui uma urna que contém inicialmente 1 conta vermelha e 1 conta azul.

Para cada iteração, ele alcança e recupera uma conta, depois inspeciona a cor e a coloca novamente na urna.

Em seguida, ele vira uma moeda justa, se a moeda cair na cabeça, ele inserirá uma quantidade justa de rolagem de 6 faces da mesma conta colorida na urna; se ela cair, ele removerá metade do número da mesma conta colorida da urna ( Usando divisão inteira - portanto, se o número de contas da cor selecionada for ímpar, ele removerá (c-1)/2onde c é o número de contas dessa cor)

Dado um número inteiro n ≥ 0 e um decimal r> 0, forneça a probabilidade de 2 casas decimais de que a proporção entre as cores das contas após n iterações seja maior ou igual a r no menor número de bytes.

Um conjunto de exemplos de iterações:

Deixe (x, y) definir a urna de forma que ela contenha x contas vermelhas e y contas azuis.

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

Como pode ser visto, a relação r é sempre ≥ 1 (então é o maior de vermelho ou azul dividido pelo menor)

Casos de teste:

Deixe F (n, r) definir a aplicação da função para n iterações e uma razão 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

Isso é código de golfe, então a solução mais curta em bytes vence.


Eu sinto que existe uma fórmula para isso ...
Modalidade de Ignorância

Talvez algo a ver com os binômios beta, mas pode demorar mais tempo para escrever isso #
Data expirada

depende do idioma; R e Mathematica podem ser capazes de fazê-lo eficientemente.
Giuseppe

Respostas:


6

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

Toma entrada como (r)(n). Esta é uma solução ingênua que realmente executa toda a simulação.

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

Experimente online!

Muito lento para os dois últimos casos de teste.

Comentado

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

Eu realmente gosto desta resposta, descobri que, para resolver os casos de teste posteriores, era necessário adicionar código para mesclar as mesmas probabilidades de proporção. Portanto, não estou surpreso que seja muito lento
Data

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.