Quebra-cabeças: Como gerar 7 números inteiros com igual probabilidade usando uma moeda tendenciosa que tem um pr (cabeça) = p?


58

Esta é uma pergunta que encontrei no Glassdoor : Como gerar 7 números inteiros com igual probabilidade usando uma moeda que possui ?Pr(Head)=p(0,1)

Basicamente, você tem uma moeda que pode ou não ser justa, e esse é o único processo de geração de número aleatório que você possui; portanto, crie um gerador de número aleatório que produz números inteiros de 1 a 7, onde a probabilidade de obter cada um desses números inteiros é 1/7.

A eficiência dos dados gera questões de processo.



12
Existem inúmeras maneiras de conseguir isso. Uma versão mais interessante da pergunta pede o melhor método em um sentido bem definido. Um senso natural de melhor seria o número menos esperado de inversões por número inteiro gerado. Outra versão interessante é descrever todas as soluções possíveis (que dependem de lançamentos independentes da moeda e nada mais).
whuber

11
boa sugestão @whuber, editei a pergunta para refletir seu comentário.
amazônica

<<< Basicamente, você tem uma moeda que pode ou não ser justa, e esse é o único processo de geração de número aleatório que você possui >>> Isso significa que a moeda é usada de qualquer maneira que não seja a lançada e verificada a cabeça vs. tail é "proibido", pois seria outro processo de geração de números aleatórios?
TinglTanglBob

9
Mod 7 do ano na moeda.
Nat

Respostas:


56

Jogue a moeda duas vezes. Se ele cair HHou TT, ignore-o e gire-o duas vezes novamente.

Agora, a moeda tem igual probabilidade de aparecer HTou TH. Se aparecer HT, ligue para isso H1. Se aparecer TH, ligue para isso T1.

Continue obtendo H1ou T1até ter três em sequência. Esses três resultados fornecem um número com base na tabela abaixo:

H1 H1 H1 -> 1
H1 H1 T1 -> 2
H1 T1 H1 -> 3
H1 T1 T1 -> 4
T1 H1 H1 -> 5
T1 H1 T1 -> 6
T1 T1 H1 -> 7
T1 T1 T1 -> [Throw out all results so far and repeat]

Argumento que isso funcionaria perfeitamente bem, apesar de você ter perdido muitos arremessos no processo!


4
A única restrição é que a probabilidade de cabeças é "p". Observe que p pode ser ou . Portanto, não é garantido que isso funcione, mas o Sycorax (ou o Sephan) funcionaria, mesmo nesses casos. 101
gung - Restabelece Monica

8
@gung: Não tenho certeza se trabalharia por uma moeda com duas cabeças ou duas caudas.
S. Kolassa - Restabelece Monica

6
Com probabilidade , terminará em tempo finito. 1
5118 clark

18
Isso se chama clareamento de Von-Neuman.
31418 DonFusili

4
É possível iterar o extrator von Neumann para extrair mais completamente a entropia da sequência. Reunir todos os pares HH e TT, consideram que uma sequcia, aplicar o extractor de von Neumann para que, etc ..
Um Simmons

47

Suponha que .p(0,1)

Passo 1: . Atire a moeda 5 vezes.

Se o resultado for

1(H,H,H,T,T) , retorne e pare.1

2(H,H,T,T,H) , retorne e pare.2

3(H,T,T,H,H) , retorne e pare.3

4(T,T,H,H,H) , retorne e pare.4

5(T,H,H,H,T) , retorne e pare.5

6(H,H,T,H,T) , retorne e pare.6

7(H,T,H,T,H) , retorne e pare.7

Passo 2: . Se o resultado não estiver acima, repita a Etapa 1.

Observe que, independentemente do valor de , cada um dos sete resultados listados acima tem probabilidade , e o número esperado de sorteios é . O tosser não precisa saber o valor de (exceto que e ); é garantido que os sete inteiros têm a mesma probabilidade de serem retornados pelo experimento quando ele terminar (e é garantido que termine com a probabilidade ).q = p 3 ( 1 - p ) 2 5p(0,1)q=p3(1p)2 pp0p1157qpp0p11


6
Podemos reduzir o número esperado de lançamentos para isso, permitindo a sequência especificada aqui OU a sequência com cada inversão invertida. por exemplo: Para 1, (H, H, H, T, T) ou (T, T, T, H, H)?
moreON

5
Você pode adicionar o complemento também. Se o resultado for (H, H, H, T, T) ou (T, T, T, H, H), retorne 1 e pare, etc. Nesse caso, a probabilidade de cada resultado é . q=p3(1p)2+p2(1p)3
Sextus Empiricus

2
Não seria possível adicionar apenas outro lançamento de moeda se o resultado não estiver em nenhum arranjo (H, H, H, T, T)? Com o sorteio adicional, você precisaria de outro mapeamento de (H, H, H, T, T, T) e (H, H, T, T, T, T) e cada combinação xT (7-x) H que podem ser dispostos em 7 ou mais diferentes ordens para os números de 1 a 7. em vez de retossing todas as 5 moedas este acrescentaria apenas 1 lance adicional, mas eu não tenho certeza se ele funciona: D
TinglTanglBob

5
Talvez seja a melhor coisa para jogar a moeda instantaneamente 7 vezes, desde que seja garantido, que você obterá um número aleatório (a única exceção é que a moeda cai de cabeça para baixo ou nas 7 tentativas) . Assim, com 7 lançamentos, você pode terminar com 1 a 6 cabeças (eu excluo a opção 0 e 7 aqui, pois é inútil). Se uma cabeça existem 7 arranjos diferentes de (H, T, T, T, T, T, T) possíveis; Se 2 lidera seus 21; se 3 lidera seus 35; se 4 35 cabeças; se 5 21 cabeças; se 6 7 cabeças; Cada um pode ser perfeitamente mapeado para o número 1-7 sem nenhuma combinação perdida.
TinglTanglBob

2
@TinglTanglBob Esta é essencialmente Martijn resposta Weterings ;-)
M.Herzkamp

22

Generalizando o caso descrito por Dilip Sarwate

Alguns dos métodos descritos nas outras respostas usam um esquema no qual você joga uma sequência de moedas em um 'turn' e, dependendo do resultado, escolhe um número entre 1 ou 7 ou descarta o turn e joga novamente.n

O truque é encontrar na expansão de possibilidades um múltiplo de 7 resultados com a mesma probabilidade e combinar os resultados entre si.pk(1p)nk

Como o número total de resultados não é um múltiplo de 7, temos alguns resultados que não podemos atribuir a um número e temos alguma probabilidade de que precisamos descartá-los e recomeçar.


O caso de usar 7 lançamentos de moedas por turno

Intuitivamente, poderíamos dizer que rolar os dados sete vezes seria muito interessante. Uma vez que só precisamos jogar fora 2 das possibilidades. Ou seja, as 7 vezes cabeças e 0 vezes cabeças.27

Para todas as outras possibilidades há sempre um múltiplo de 7 casos com o mesmo número de cabeças. Nomeadamente 7 casos com 1 cabeça, 21 casos com 2 cabeças, 35 casos com 3 cabeças, 35 casos com 4 cabeças, 21 casos com 5 cabeças e 7 casos com 6 cabeças.272

Portanto, se você calcular o número (descartando 0 e 7 cabeças)

X=k=17(k1)Ck

com as variáveis ​​distribuídas Bernoulli (valor 0 ou 1), o módulo X 7 é uma variável uniforme com sete resultados possíveis.Ck


Comparando diferentes números de lançamentos de moedas por turno

A questão permanece qual seria o número ideal de jogadas por turno. Jogar mais dados por turno custa mais, mas você reduz a probabilidade de ter que jogar novamente.

A imagem abaixo mostra um cálculo manual para os primeiros números de lançamentos de moedas por turno. (possivelmente pode haver uma solução analítica, mas acredito que seja seguro dizer que um sistema com 7 lançamentos de moedas fornece o melhor método em relação ao valor esperado para o número necessário de lançamentos de moedas)

número esperado de lançamentos de moedas

# plot an empty canvas
plot(-100,-100,
     xlab="flips per turn",
     ylab="E(total flips)",
     ylim=c(7,400),xlim=c(0,20),log="y")
title("expectation value for total number of coin flips
(number of turns times flips per turn)")

# loop 1
# different values p from fair to very unfair 
# since this is symmetric only from 0 to 0.5 is necessary 

# loop 2
# different values for number of flips per turn
# we can only use a multiple of 7 to assign 
#   so the modulus will have to be discarded
#   from this we can calculate the probability that the turn succeeds
#   the expected number of flips is 
#       the flips per turn 
#             divided by 
#       the probability for the turn to succeed 

for (p in c(0.5,0.2,0.1,0.05)) {
  Ecoins <- rep(0,16)
  for (dr in (5:20)){
    Pdiscards = 0
    for (i in c(0:dr)) { 
      Pdiscards = Pdiscards + p^(i)*(1-p)^(dr-i) * (choose(dr,i) %% 7)
    }
    Ecoins[dr-4] = dr/(1-Pdiscards)
  }
  lines(5:20, Ecoins)
  points(5:20, Ecoins, pch=21, col="black", bg="white", cex=0.5)
  text(5, Ecoins[1], paste0("p = ",p), pos=2)
}

Usando uma regra de parada antecipada

nota: os cálculos abaixo, para o valor esperado do número de lançamentos, são para uma moeda justa , seria uma bagunça fazer isso para diferente , mas o princípio permanece o mesmo (embora contabilidade diferente da casos é necessário)p=0.5p

Deveríamos poder escolher os casos (em vez da fórmula para ) para que possamos parar mais cedo.X

  • Com 5 lançamentos de moedas , temos para os seis conjuntos diferentes possíveis de cara e coroa:

    1 + 5 + 10 + 10 + 5 + 1 conjuntos ordenados

    E podemos usar os grupos com dez casos (ou seja, o grupo com 2 cabeças ou o grupo com 2 caudas) para escolher (com igual probabilidade) um número. Isso ocorre em 14 dos 2 ^ 5 = 32 casos. Isso nos deixa com:

    1 + 5 + 3 + 3 + 5 + 1 conjuntos ordenados

  • Com um lançamento de moeda extra (6ª) , temos para os sete possíveis conjuntos diferentes de cara e coroa:

    1 + 6 + 8 + 6 + 8 + 6 + 1 conjuntos ordenados

    E podemos usar os grupos com oito casos (ou seja, o grupo com 3 cabeças ou o grupo com 3 caudas) para escolher (com igual probabilidade) um número. Isso ocorre em 14 de 2 * (2 ^ 5-14) = 36 casos. Isso nos deixa com:

    1 + 6 + 1 + 6 + 1 + 6 + 1 conjuntos ordenados

  • Com outro (7º) lançamento de moeda extra , temos para os oito possíveis conjuntos diferentes de cabeças e coroas não ordenadas:

    1 + 7 + 7 + 7 + 7 + 7 + 7 + 1 conjuntos ordenados

    E podemos usar os grupos com sete casos (todos, exceto os casos com todas as caudas e todas as cabeças) para escolher (com igual probabilidade) um número. Isso ocorre em 42 dos 44 casos. Isso nos deixa com:

    1 + 0 + 0 + 0 + 0 + 0 + 0 + 1 conjuntos ordenados

    (poderíamos continuar, mas somente na 49ª etapa isso nos dá uma vantagem)

Portanto, a probabilidade de selecionar um número

  • em 5 movimentos é1432=716
  • em 6 movimentos é9161436=732
  • em 7 movimentos é11324244=231704
  • não em 7 movimentos é1716732231704=227

Isso torna o valor esperado para o número de lançamentos em um turno, desde que haja sucesso ep = 0,5:

5716+6732+7231704=5.796875

O valor esperado para o número total de lançamentos (até que haja sucesso), condicional que p = 0,5, se torne:

(5716+6732+7231704)27272=539=5.88889


A resposta de NcAdams usa uma variação dessa estratégia de regra de parada (cada vez que surgem dois novos lançamentos de moedas), mas não é a melhor escolha para todos os lançamentos.

A resposta de Clid também pode ser semelhante, embora possa haver uma regra de seleção desigual de que cada duas moedas vira um número que pode ser escolhido, mas não necessariamente com igual probabilidade (uma discrepância que está sendo reparada durante os lançamentos de moedas posteriores)


Comparação com outros métodos

Outros métodos que usam um princípio semelhante são os de NcAdams e AdamO.

O princípio é : Uma decisão para um número entre 1 e 7 é tomada após um certo número de caras e coroa. Após um número de inversões, para cada decisão que leva a um número existe uma decisão semelhante, igualmente provável, que leva a um número (o mesmo número de caras e coroa, mas apenas em uma ordem diferente). Algumas séries de cara e coroa podem levar a uma decisão de recomeçar.xij

Para esse tipo de método, o método colocado aqui é o mais eficiente, porque toma as decisões o mais cedo possível (assim que houver a possibilidade de 7 sequências de probabilidade igual de cara e coroa, após o ésimo giro, podemos usar eles tomam uma decisão sobre um número e não precisamos mudar mais se encontrarmos um desses casos).x

Isso é demonstrado pela imagem e simulação abaixo:

comparação

#### mathematical part #####
set.seed(1)


#plotting this method
p <- seq(0.001,0.999,0.001)
tot <- (5*7*(p^2*(1-p)^3+p^3*(1-p)^2)+
       6*7*(p^2*(1-p)^4+p^4*(1-p)^2)+
       7*7*(p^1*(1-p)^6+p^2*(1-p)^5+p^3*(1-p)^4+p^4*(1-p)^3+p^5*(1-p)^2+p^6*(1-p)^1)+
        7*1*(0+p^7+(1-p)^7) )/
             (1-p^7-(1-p)^7)
plot(p,tot,type="l",log="y",
     xlab="p",
     ylab="expactation value number of flips"
     )

#plotting method by AdamO
tot <- (7*(p^20-20*p^19+189*p^18-1121*p^17+4674*p^16-14536*p^15+34900*p^14-66014*p^13+99426*p^12-119573*p^11+114257*p^10-85514*p^9+48750*p^8-20100*p^7+5400*p^6-720*p^5)+6*
          (-7*p^21+140*p^20-1323*p^19+7847*p^18-32718*p^17+101752*p^16-244307*p^15+462196*p^14-696612*p^13+839468*p^12-806260*p^11+610617*p^10-357343*p^9+156100*p^8-47950*p^7+9240*p^6-840*p^5)+5*
          (21*p^22-420*p^21+3969*p^20-23541*p^19+98154*p^18-305277*p^17+733257*p^16-1389066*p^15+2100987*p^14-2552529*p^13+2493624*p^12-1952475*p^11+1215900*p^10-594216*p^9+222600*p^8-61068*p^7+11088*p^6-1008*p^5)+4*(-
          35*p^23+700*p^22-6615*p^21+39235*p^20-163625*p^19+509425*p^18-1227345*p^17+2341955*p^16-3595725*p^15+4493195*p^14-4609675*p^13+3907820*p^12-2745610*p^11+1592640*p^10-750855*p^9+278250*p^8-76335*p^7+13860*p^6-
          1260*p^5)+3*(35*p^24-700*p^23+6615*p^22-39270*p^21+164325*p^20-515935*p^19+1264725*p^18-2490320*p^17+4027555*p^16-5447470*p^15+6245645*p^14-6113275*p^13+5102720*p^12-3597370*p^11+2105880*p^10-999180*p^9+371000
           *p^8-101780*p^7+18480*p^6-1680*p^5)+2*(-21*p^25+420*p^24-3990*p^23+24024*p^22-103362*p^21+340221*p^20-896679*p^19+1954827*p^18-3604755*p^17+5695179*p^16-7742301*p^15+9038379*p^14-9009357*p^13+7608720*p^12-
           5390385*p^11+3158820*p^10-1498770*p^9+556500*p^8-152670*p^7+27720*p^6-2520*p^5))/(7*p^27-147*p^26+1505*p^25-10073*p^24+49777*p^23-193781*p^22+616532*p^21-1636082*p^20+3660762*p^19-6946380*p^18+11213888*p^17-
           15426950*p^16+18087244*p^15-18037012*p^14+15224160*p^13-10781610*p^12+6317640*p^11-2997540*p^10+1113000*p^9-305340*p^8+55440*p^7-5040*p^6)
lines(p,tot,col=2,lty=2)

#plotting method by NcAdam
lines(p,3*8/7/(p*(1-p)),col=3,lty=2)

legend(0.2,500,
       c("this method calculation","AdamO","NcAdams","this method simulation"),
       lty=c(1,2,2,0),pch=c(NA,NA,NA,1),col=c(1,2,3,1))


##### simulation part ######

#creating decision table
mat<-matrix(as.numeric(intToBits(c(0:(2^5-1)))),2^5,byrow=1)[,c(1:12)]
colnames(mat) <- c("b1","b2","b3","b4","b5","b6","b7","sum5","sum6","sum7","decision","exit")

# first 5 rolls
mat[,8] <- sapply(c(1:2^5), FUN = function(x) {sum(mat[x,1:5])})

mat[which((mat[,8]==2)&(mat[,11]==0))[1:7],12] = rep(5,7) # we can stop for 7 cases with 2 heads
mat[which((mat[,8]==2)&(mat[,11]==0))[1:7],11] = c(1:7)   
mat[which((mat[,8]==3)&(mat[,11]==0))[1:7],12] = rep(5,7) # we can stop for 7 cases with 3 heads
mat[which((mat[,8]==3)&(mat[,11]==0))[1:7],11] = c(1:7)    

# extra 6th roll
mat <- rbind(mat,mat)
mat[c(33:64),6] <- rep(1,32)
mat[,9] <- sapply(c(1:2^6), FUN = function(x) {sum(mat[x,1:6])})

mat[which((mat[,9]==2)&(mat[,11]==0))[1:7],12] = rep(6,7) # we can stop for 7 cases with 2 heads
mat[which((mat[,9]==2)&(mat[,11]==0))[1:7],11] = c(1:7)   
mat[which((mat[,9]==4)&(mat[,11]==0))[1:7],12] = rep(6,7) # we can stop for 7 cases with 4 heads
mat[which((mat[,9]==4)&(mat[,11]==0))[1:7],11] = c(1:7)    

# extra 7th roll
mat <- rbind(mat,mat)
mat[c(65:128),7] <- rep(1,64)
mat[,10] <- sapply(c(1:2^7), FUN = function(x) {sum(mat[x,1:7])})

for (i in 1:6) {
  mat[which((mat[,10]==i)&(mat[,11]==0))[1:7],12] = rep(7,7) # we can stop for 7 cases with i heads
  mat[which((mat[,10]==i)&(mat[,11]==0))[1:7],11] = c(1:7)   
}


mat[1,12] = 7           # when we did not have succes we still need to count the 7 coin tosses
mat[2^7,12] = 7


draws = rep(0,100)
num = rep(0,100)
# plotting simulation
for (p in seq(0.05,0.95,0.05)) {
  n <- rep(0,1000)
  for (i in 1:1000) {
    coinflips <- rbinom(7,1,p)  # draw seven numbers
    I <- mat[,1:7]-matrix(rep(coinflips,2^7),2^7,byrow=1) == rep(0,7)                      # compare with the table
    Imatch = I[,1]*I[,2]*I[,3]*I[,4]*I[,5]*I[,6]*I[,7]        # compare with the table 
      draws[i] <- mat[which(Imatch==1),11]                 # result which number
      num[i]   <- mat[which(Imatch==1),12]                 # result how long it took
  }
  Nturn <- mean(num)                   #how many flips we made
  Sturn <- (1000-sum(draws==0))/1000   #how many numbers we got (relatively)
  points(p,Nturn/Sturn)
}

outra imagem dimensionada por para melhor comparação:p(1p)

comparação com valores de expectativa em escala

ampliar os métodos de comparação descritos neste post e comentários

métodos de comparação descritos aqui

o 'salto condicional do 7º passo' é uma ligeira melhora que pode ser feita na regra de parada antecipada. Nesse caso, você não seleciona grupos com probabilidades iguais após o sexto flips. Você tem 6 grupos com probabilidades iguais e 1 grupo com uma probabilidade ligeiramente diferente (para este último grupo, você precisa inverter mais um tempo extra quando tiver 6 caras ou coroa e porque você descarta as 7 caras ou 7 coroas) afinal, com a mesma probabilidade)


Escrito por StackExchangeStrike


Eu estava começando a fazer os cálculos para o caso n = 7, porque tinha a sensação de que poderia ser melhor que n = 1. Tenha minha votação, senhor!
M.Herzkamp

@ M.Herzkamp uma pequena melhoria ainda é possível. Um número (uma moeda) não é necessário para o cálculo de , porque possui o coeficiente 0. Esse número é necessário apenas para determinar o caso de todas as cabeças ou caudas, e pode ser omitido quando já sabemos que tem um caso misto. XCkX
Sextus Empiricus

Portanto, a melhoria reduz para um pouco mais de 6 lançamentos de moeda como valor esperado para o número de lançamentos de moedas necessários. No entanto, isso pode variar para provar que esta é a solução ideal. O esquema criado por Clid diverge um pouco, permitindo escolher um número em um número específico de lançamentos de moedas, mas não com igual probabilidade (pelo menos não para esse passo específico, será corrigido posteriormente).
Sextus Empiricus

Mas se você decidir jogar a sexta moeda com base nos cinco primeiros resultados, as probabilidades de cada conjunto são condicionadas a que você tenha seis flips, o mesmo que para os outros conjuntos?
Acccumulation

@ Accumulation você pode desenhar como uma árvore binária com 7 níveis. Somente selecionaremos entre os nós se houver 7 com igual probabilidade. É como cortar alguns galhos mais cedo (no nível 5 ou 6). Se você preferir, poderá continuar até 7 etapas, em vez de antes, mas para esses casos em particular, o lançamento da 6ª e 7ª moedas não faz diferença.
Sextus Empiricus

20

Divida uma caixa em sete regiões de área igual, cada uma rotulada com um número inteiro. Jogue a moeda na caixa de maneira a ter igual probabilidade de aterrissagem em cada região.

Isso é apenas metade da brincadeira - é essencialmente o mesmo procedimento que estimar usando um procedimento físico de Monte Carlo, como jogar grãos de arroz no papel com um círculo desenhado nele.π

Essa é uma das únicas respostas que funcionam no caso de ou .p=1p=0


2
Você pode sugerir uma maneira de dividir a caixa em sete regiões de áreas iguais, para minimizar o viés de capotar, quicar nas paredes etc.? Sete setores do ângulo 360/7?
smci

11
@smci É por isso que estipulo que você deve jogar a moeda para que haja probabilidade uniforme de que ela desembarque em cada quadrado. Se saltar de um muro influencia essa probabilidade, você deve dar conta disso em seu arremesso.
Reponha Monica

17
Sim, eu sei disso, e estou apontando para você que simplesmente dizer "jogue de maneira imparcial" sem definir exatamente como conseguir isso, não é realmente uma resposta completa ... nesse caso, o flipping-H / T métodos baseados são superiores.
smci 6/07/19

11
"Áreas iguais, com lances com probabilidade igual de aterrissagem em cada região" podem ser difíceis de estabelecer na prática. Na prática, pode ser mais fácil marcar um grande número de "corridas de prática" e depois subdividir a área de aterrissagem em espaços equiprobáveis ​​empiricamente (por exemplo, com 700 arremessos, descarte uma linha que corta os 100 arremessos mais afastados, depois outra para os próximos 100 e assim por diante). A simplificação deste para gerar um único bit aleatório seria a de lançar a moeda duas vezes - se o primeiro lance vai mais longe, o bit é 0, e se o segundo lance vai mais longe é um1
Silverfish

4
Há uma boa resposta de @TheScienceBoy que infelizmente é excluída com uma alternativa interessante para isso - efetivamente, usando a moeda como um girador e marcando 7 seções ao longo de sua circunferência - que retém muito do espírito dessa resposta, mas pode ser mais direto fisicamente realizar!
Silverfish

8

EDIT: com base no feedback dos outros.

Aqui está um pensamento interessante:

defina a lista de {1,2,3,4,5,6,7}. Jogue a moeda para cada elemento da lista sequencialmente. Se cair de cabeça para cima para um elemento específico, remova o número da lista. Se todos os números de uma iteração específica da lista forem removidos, repita a amostragem. Faça isso até restar apenas um número.

drop.one <- function(x, p) {
  drop <- runif(length(x)) < p
  if (all(drop))
    return(x)
  return(x[!drop])
}

sample.recur <- function(x, p) {
  if (length(x) > 1)
    return(sample.recur(drop.one(x, p), p))
  return(x)
}

# x <- c(1:7,7:1)
x <- 1:7
p <- 0.01

out <- replicate(1e5, sample.recur(x, p))

round(prop.table(table(out)), 2)

me dá uma distribuição aproximadamente uniforme

> round(prop.table(table(out)), 2)
out
   1    2    3    4    5    6    7 
0.14 0.14 0.15 0.14 0.14 0.14 0.14 

É interessante notar (se não cometi um erro grave) que isso produz um resultado diferente do que gerar resultados binomiais de como a soma de 13 arremessos da moeda (contando 0 cabeças como resultado) e mapear o {0,1 , 2, ..., 12,13} indexe na lista anterior de {1,2,3, ..., 3,2,1}. Não sei como provar que meu método funciona.N


Avaliação do valor esperado para o número de lançamentos de moedas

O valor esperado para o número de lançamentos de moedas pode ser calculado usando a matriz de transição abaixo (respondendo à pergunta quando começamos com números não eliminados, qual é a probabilidade de obter números não eliminados)xy

M=[q700000117p1q6q600000021p2q56p1q5q50000035p3q415p2q45q4q4000035p4q320p3q310p2q34p1q3q300021p5q215p4q210p3q26p2q23p1q2q2007p6q16p5q15p4q14p3q13p2q12p1q100p7p6p5p4p3p200]

O vetor próprio associado ao valor próprio 1 (que pode ser encontrado resolvendo ) mostra quanto tempo é gasto relativamente em qual estado. Então, o sétimo estado é a frequência com que você poderá desenhar um número de 1 a 7. Os outros estados dizem quantas moedas são lançadas.(MI)v=0

Abaixo está a imagem que se compara à resposta de NcAdams, que tem valor esperado para lançamentos de moedas, sendoE(n)=247p(1p)

comparação do valor esperado para lançamentos de moedas

Notável é que o método tem um desempenho melhor para . Mas também o desempenho não é simétrico. Um desempenho geral simétrico e melhor poderia ser feito quando uma regra de comutação probabilística fosse feita, que altera a regra de decisão de caudas para cabeças quando as cabeças são improváveis.p>2/3

Solução encontrada com wxMaxima

M: matrix(
 [(1-p)^7,        0,          0,0,0,0,1,1], 
 [7* p*(1-p)^6,   (1-p)^6,        0,0,0,0,0,0], 
 [21*p^2*(1-p)^5, 6*p*(1-p)^5,    (1-p)^5,0,0,0,0,0], 
 [35*p^3*(1-p)^4, 15*p^2*(1-p)^4, 5*p*(1-p)^4,(1-p)^4,0,0,0,0], 
 [35*p^4*(1-p)^3, 20*p^3*(1-p)^3, 10*p^2*(1-p)^3,4*p*(1-p)^3,(1-p)^3,0,0,0], 
 [21*p^5*(1-p)^2, 15*p^4*(1-p)^2, 10*p^3*(1-p)^2,6*p^2*(1-p)^2,3*p*(1-p)^2,(1-p)^2,0,0], 
 [7* p^6*(1-p)^1, 6*p^5*(1-p),    5*p^4*(1-p),4*p^3*(1-p),3*p^2*(1-p),2*(1-p)*p,0,0], 
 [p^7,        p^6,        p^5,p^4,p^3,p^2,0,0]
);
z: nullspace(M-diagmatrix(8,1));
x : apply (addcol, args (z));
t : [7,6,5,4,3,2,0,0];
plot2d(t.x/x[7],[p,0,1],logy);

Cálculos em R

# plotting empty canvas
plot(-100,-100,
     xlab="p",
     ylab="E(total flips)",
     ylim=c(10,1000),xlim=c(0,1),log="y")

# plotting simulation
for (p in seq(0.1,0.9,0.05)) {

  n <- rep(0,10000)
  for (i in 1:10000) {
    success  = 0
    tests = c(1,1,1,1,1,1,1)     # start with seven numbers in the set
    count = 0
    while(success==0) {
      for (j in 1:7)  {
        if (tests[j]==1) {
          count = count + 1
          if  (rbinom(1,1,p) == 1) {
            tests[j] <- 0        # elliminate number when we draw heads
          }
        }
      }
      if (sum(tests)==1) {
        n[i] = count
        success = 1              # end     when 1 is left over
      }
      if (sum(tests)==0) {
        tests = c(1,1,1,1,1,1,1) # restart when 0 are left over
      }
    }
  }
  points(p,mean(n))
}

# plotting formula
p <- seq(0.001,0.999,0.001)

tot <- (7*(p^20-20*p^19+189*p^18-1121*p^17+4674*p^16-14536*p^15+34900*p^14-66014*p^13+99426*p^12-119573*p^11+114257*p^10-85514*p^9+48750*p^8-20100*p^7+5400*p^6-720*p^5)+6*
    (-7*p^21+140*p^20-1323*p^19+7847*p^18-32718*p^17+101752*p^16-244307*p^15+462196*p^14-696612*p^13+839468*p^12-806260*p^11+610617*p^10-357343*p^9+156100*p^8-47950*p^7+9240*p^6-840*p^5)+5*
    (21*p^22-420*p^21+3969*p^20-23541*p^19+98154*p^18-305277*p^17+733257*p^16-1389066*p^15+2100987*p^14-2552529*p^13+2493624*p^12-1952475*p^11+1215900*p^10-594216*p^9+222600*p^8-61068*p^7+11088*p^6-1008*p^5)+4*(-
    35*p^23+700*p^22-6615*p^21+39235*p^20-163625*p^19+509425*p^18-1227345*p^17+2341955*p^16-3595725*p^15+4493195*p^14-4609675*p^13+3907820*p^12-2745610*p^11+1592640*p^10-750855*p^9+278250*p^8-76335*p^7+13860*p^6-
    1260*p^5)+3*(35*p^24-700*p^23+6615*p^22-39270*p^21+164325*p^20-515935*p^19+1264725*p^18-2490320*p^17+4027555*p^16-5447470*p^15+6245645*p^14-6113275*p^13+5102720*p^12-3597370*p^11+2105880*p^10-999180*p^9+371000
   *p^8-101780*p^7+18480*p^6-1680*p^5)+2*(-21*p^25+420*p^24-3990*p^23+24024*p^22-103362*p^21+340221*p^20-896679*p^19+1954827*p^18-3604755*p^17+5695179*p^16-7742301*p^15+9038379*p^14-9009357*p^13+7608720*p^12-
 5390385*p^11+3158820*p^10-1498770*p^9+556500*p^8-152670*p^7+27720*p^6-2520*p^5))/(7*p^27-147*p^26+1505*p^25-10073*p^24+49777*p^23-193781*p^22+616532*p^21-1636082*p^20+3660762*p^19-6946380*p^18+11213888*p^17-
  15426950*p^16+18087244*p^15-18037012*p^14+15224160*p^13-10781610*p^12+6317640*p^11-2997540*p^10+1113000*p^9-305340*p^8+55440*p^7-5040*p^6)
lines(p,tot)

#plotting comparison with alternative method
lines(p,3*8/7/(p*(1-p)),lty=2)

legend(0.2,500,
       c("simulation","calculation","comparison"),
       lty=c(0,1,2),pch=c(1,NA,NA))

11
Idéia inteligente (+1). Intuitivamente, deve funcionar, pois a simetria parece anular o viés em relação a qualquer número específico. Ainda assim, eu adoraria ver uma prova.
Reintegrar Monica

6
Essa idéia é muito boa, mas com uma alta probabilidade de cabeça (nocauteie esse número), acho que o último número na linha tem as melhores chances de "sobreviver", já que todos os outros na frente são expulsos muito provavelmente antes da corrida 1? Talvez pudesse ser alterado não jogando a moeda sequencialmente, mas paralelo para todos os números em x? Runtime do script pode aumentar eu acho :)
TinglTanglBob

2
Concordo com @TinglTanglBob - quando eu definir p <- 0.99I obter a saída0.89 0.02 0.02 0.02 0.02 0.02 0.02
Silverfish

6
Realizar a eliminação em 'rodadas' não resolveria o problema de preconceito? Comece com 7 números. Jogue a moeda para cada número restante e elimine os que jogam a cabeça. Se todos os números restantes forem eliminados em uma rodada, risque os resultados dessa rodada e tente novamente. Eu não sei como provar, mas intuitivamente a ordem dos números que não são mais assuntos em se eles são o 'vencedor'
Phil

11
@TinglTanglBob obrigado por apontar isso. Eu brinquei um pouco mais com o script e minha solução proposta é: use o lado com menos probabilidade de ser o critério de eliminação. Definir estranhamente corrige o problema. Faço eco ao desejo de alguém melhor do que oferecer uma prova a favor / contra essa "solução". p=0.01
21418 AdamO

5

A pergunta é um pouco ambígua, está perguntando "gerar um número inteiro aleatório igual ou menor que 7 com probabilidade igual" ou está perguntando "gerar 7 números inteiros aleatórios com probabilidade igual?" - mas qual é o espaço dos números inteiros?!?

Suponho que seja o primeiro, mas a mesma lógica que estou aplicando também pode ser estendida ao último caso, uma vez que o problema seja resolvido.

Com uma moeda tendenciosa, você pode produzir uma moeda justa seguindo o procedimento a seguir: https://en.wikipedia.org/wiki/Fair_coin#Fair_results_from_a_beased_coin

Um número 7 ou menos pode ser escrito em binário como três dígitos {0,1}. Portanto, basta seguir o procedimento acima três vezes e converter o número binário produzido novamente em decimal.


11
comparando minha resposta com @NcAdams, é claro que estou incluindo 0 como um possível resultado desejável!
precisa saber é o seguinte

Não entendo como sua resposta é diferente. Se você incluir {0,0,0} -> 1, para que {1,1,1} será mapeado? Existem 8 possibilidades.
21420 AdamOf:

11
000 mapeia para 0, daí o meu comentário sobre a inclusão de 0 como um valor possível. Isso foi publicado antes da edição do OP e quase simultaneamente como NcAdams.
CamDavidson.Pilon

Metade desta resposta é um comentário e o conteúdo real da resposta é apenas para link. Soletre sua resposta real em vez de apenas vincular a ela.
Cubic

3

Uma solução que nunca desperdiça flips, o que ajuda muito em moedas muito tendenciosas.

A desvantagem desse algoritmo (como escrito, pelo menos) é que ele está usando aritmética de precisão arbitrária. Praticamente, você provavelmente deseja usar isso até o número inteiro exceder o limite e só então jogá-lo fora e começar de novo.

Além disso, você precisa saber o que o viés é ... que você não pode, por exemplo, se for como a maioria dos fenômenos físicos dependente da temperatura.


Supondo que a chance de cabeças seja, digamos, 30%.

  • Comece com o intervalo [1, 8).
  • Jogue sua moeda. Se tiver cara, use os 30% restantes, então seu novo alcance é [1, 3.1). Senão, use os 70% certos, então seu novo alcance é [3.1, 8).
  • Repita até que todo o intervalo tenha a mesma parte inteira.

Código completo:

#!/usr/bin/env python3
from fractions import Fraction
from collections import Counter
from random import randrange


BIAS = Fraction(3, 10)
STAT_COUNT = 100000


calls = 0
def biased_rand():
    global calls
    calls += 1
    return randrange(BIAS.denominator) < BIAS.numerator


def can_generate_multiple(start, stop):
    if stop.denominator == 1:
        # half-open range
        stop = stop.numerator - 1
    else:
        stop = int(stop)
    start = int(start)
    return start != stop


def unbiased_rand(start, stop):
    if start < 0:
        # negative numbers round wrong
        return start + unbiased_rand(0, stop - start)
    assert isinstance(start, int) and start >= 0
    assert isinstance(stop, int) and stop >= start
    start = Fraction(start)
    stop = Fraction(stop)
    while can_generate_multiple(start, stop):
        if biased_rand():
            old_diff = stop - start
            diff = old_diff * BIAS
            stop = start + diff
        else:
            old_diff = stop - start
            diff = old_diff * (1 - BIAS)
            start = stop - diff
    return int(start)


def stats(f, *args, **kwargs):
    c = Counter()
    for _ in range(STAT_COUNT):
        c[f(*args, **kwargs)] += 1

    print('stats for %s:' % f.__qualname__)
    for k, v in sorted(c.items()):
        percent = v * 100 / STAT_COUNT
        print('  %s: %f%%' % (k, percent))


def main():
    #stats(biased_rand)
    stats(unbiased_rand, 1, 7+1)
    print('used %f calls at bias %s' % (calls/STAT_COUNT, BIAS))


if __name__ == '__main__':
    main()

3
Você pode melhorar esse processo. Comece a partir do intervalo [0,1]; você pode ver sua sequência de lançamentos de moedas como um processo infinito que gera um único número aleatório em , uniformemente. Esse número aleatório possui uma expansão base-7 exclusiva (além de um conjunto de probabilidade-0, onde você tem duas expansões, uma terminando em e uma em ). Quando o intervalo é estreito o suficiente para que você possa determinar seu ésimo dígito (base-7) exclusivamente, você o produz. Faz um tempo desde que li sobre isso, mas se bem me lembro, isso gera dígitos na taxa ideal pela entropia de Shannon. 0000 6666 k[0,1]00006666k
Federico Poloni 07/07

É o mesmo para uma única saída, certo? Apenas melhor para vários? Eu escreveria como diff *= 7penso ... de fato, não há necessidade específica de usar a mesma base para cada tentativa.
o11c

Sim, é o mesmo se você quiser uma única saída; só melhora a eficiência se você quiser vários.
Federico Poloni 07/07

+1 Isso está de acordo com o procedimento de codificação aritmética. E se for fornecido como um número racional, isso poderá ser facilmente implementado exatamente, com aritmética inteira (ilimitada). Mas, é claro, isso requer saber . ppp
Leonbloy 7/07

Isso desperdiça absolutamente flips se você deseja uma única saída. Para uma moeda justa, a técnica padrão (jogue a moeda três vezes e repita se você conseguir TTT) fornece um número esperado de 24/7 = jogadas de 3 + 3/7. Se você usar essa técnica de codificação aritmética, role pelo menos quatro vezes, a menos que obtenha HHH ou TTT, o que fornece um número esperado de mais de 15/4 = 3 + 3/4 rolos.
315 Peter Peter Shor

3

Como mencionado nos comentários anteriores, esse quebra-cabeça está relacionado ao artigo de John von Neumann, de 1951 , "Various Techniques Used in Connection With Random Digits", publicado na revista de pesquisa do National Bureau of Standards:

insira a descrição da imagem aqui

Existe uma literatura mais ampla sobre tais problemas que se chama “ problemas de fábrica de Bernoulli” , ou seja, dada uma moeda com probabilidade de cauda , como simular uma moeda com probabilidade de cauda . Se possível, uma vez que algumas funções não podem ser usadas como, por exemplo, . Nacu e Peres (2005) estudam algoritmos rápidos para resolver problemas de fábrica [solucionáveis] de Bernoulli, onde rápido significa decaimento exponencial da cauda da distribuição do número de ensaios.pf(p)f f(p)=min{1,2p}N


2

Isso também só funciona para e .p1p0

Primeiro, transformamos a moeda (possivelmente) injusta em uma moeda justa, usando o processo da resposta do NcAdams :

Jogue a moeda duas vezes. Se ele cair HHou TT, ignore-o e gire-o duas vezes novamente.

Agora, a moeda tem igual probabilidade de aparecer HTou TH. Se aparecer HT, ligue para isso H1. Se aparecer TH, ligue para isso T1.

Agora usamos a moeda justa para gerar um número real entre e em binário. Seja e . Comece com a corda , jogue a moeda e anexe o dígito resultante ao final da corda. Repita com a nova sequência. Por exemplo, a sequência forneceria o número .01H1=1T1 =00.H1 H1 T10.110

1/7 é um decimal repetido e, com o lado direito na base 2, temos o seguinte:

1/7=0.001001001...

2/7=0.010010010...

3/7=0.011011011...

4/7=0.100100100...

5/7=0.101101101...

6/7=0.110110110...

Continue jogando a moeda correta para gerar os dígitos decimais até que os dígitos da sua sequência não correspondam a uma das seqüências acima e, em seguida, escolha o número que o número gerado seja menor que e maior que . Como cada número gerado é igualmente provável, escolhemos um número entre e com igual probabilidade.nn/7(n1)/717


11
Ignorando que esse método requer muitos movimentos, é interessante como a separação dos bits em 7 partes igualmente prováveis ​​é gerada. Essas partes são realmente igualmente prováveis? Por exemplo, o número aparece quando você gira 0,000 ou quando você não lança 0,001001001 acaba no lado errado, que é 1/8 + 1/16 dos casos, ou vejo isso errado? 1/7
Sextus Empiricus

11
A correção na probabilidade de inverter desse último número não é 1/16. Assim você flip 000 ou 001.000 ou 001.001 mil, etc., que tem probabilidade1/7k=1(1/8)k=17
Sexto Empírico

11
Portanto, a probabilidade de terminação dentro de bits é (para caso contrário, é zero) e, em seguida, o valor esperado para o número necessário de bits é isso não é uma melhoria em comparação com a solução NcAdams que precisa de bits. (o principal culpado é que, depois de 3 bits este método tem apenas uma decisão para 25% dos casos)nT(n)=2n62nn3
3+n=31T(n)=4.5
8733.42
Sexto Empírico

2

Inspirado na resposta do AdamO, aqui está uma solução Python que evita preconceitos:

def roll(p, n):
    remaining = range(1,n+1)
    flips = 0
    while len(remaining) > 1:
        round_winners = [c for c in remaining if random.choices(['H','T'], [p, 1.0-p]) == ['H']]
        flips += len(remaining)
        if len(round_winners) > 0:
            remaining = round_winners
        p = 1.0 - p
    return remaining[0], flips

Existem duas mudanças principais aqui: a principal é que, se todo o número for descartado em uma rodada, repita a rodada. Também mudo a escolha de se cara ou coroa significa descartar sempre. Isso reduz o número de inversões necessárias nos casos em que p é próximo de 0 ou 1 em ~ 70% quando p = 0,999


2
"Eu alterno entre escolher cara ou coroa significa descartar sempre. Isso reduz o número de movimentos necessários nos casos em que p é próximo de 0 ou 1 em ~ 70% quando p = 0,999" - pensamento inteligente!
6288 Silverfish

11
Alternar cara ou coroa é definitivamente uma melhoria em relação a sempre descartar as cabeças - mas talvez seja melhor se, depois de lançar uma moeda para cada opção restante, se elas forem iguais repetirmos a reflexão de todas elas, caso contrário, se houver pelo menos tantas cabeças quanto coroa, eliminamos as opções restantes correspondentes às cabeças, caso contrário, eliminamos as opções restantes correspondentes às coroa.
David Cary

2

Parece que temos permissão para alterar o mapeamento do resultado de cada flip, toda vez que fazemos flip . Portanto, usando por conveniência os sete primeiros números inteiros positivos, damos as seguintes ordens:

1st Flip, mapear 2nd Flip, mapear ... 7th flip, mapear 8th flip, mapearH1
H2

H7
H1

etc

Repita, sempre em lotes de 7 movimentos. Mapeie os resultados para nada.T

ALGUMAS OBSERVAÇÕES SOBRE EFICIÊNCIA
Nosso RNG, indexado pelo , gerará zero resultados úteis em um lote de 7 flip se obtivermos em todos os 7 flips. assimAPT

PAP(no integers generated)=(1p)7

À medida que executamos lotes 7 flip, o número total de inúteis tenderá aNb

CountAP(useless flips)7Nb(1p)7

Considere agora o RNG do @DilipSarwate. Aqui, usamos um binômio e lotes de 5 flip. Os sete resultados que geram um número inteiro têm probabilidade de ocorrer , portanto, em um lote de 5 flipB(p,n=5)p3(1p)2

PDS(no integers generated)=17p3(1p)2

A contagem de lançamentos inúteis aqui tenderá a

CountDS(useless flips)5Nb[17p3(1p)2]

Para o RNG da tender a produzir lançamentos menos inúteis, deve ser o caso queAP

CountAP(useless flips)<CountDS(useless flips)

7Nb(1p)7<5Nb[17p3(1p)2]

7(1p)7<5[17p3(1p)2]

O exame numérico mostra que se , o RNG gera menos movimentos inúteis. p>0.0467AP

Também descobrimos que o número de inversões inúteis está diminuindo monotonicamente em para o RNG , enquanto que para o RNG ele tem um mínimo em torno de e depois aumenta novamente, enquanto em geral permanece alto. A proporçãoA P D S p 0,5967pAPDSp0.5967

CountAP(useless flips)CountDS(useless flips)

declina muito rapidamente. Por exemplo, é igual a para , igual a para , igual a para .p = 0,1 0,3 p = 0,2 0,127 p = 0,40.67p=0.10.3p=0.20.127p=0.4


Suponha que desejamos minimizar o número total de inversões necessárias para gerar um número inteiro. Eu acho que sua resposta fornece o mínimo total de inversões em todos os . Você pode elaborar sobre esse ponto? p(0,1)
Reintegrar Monica

11
@ Sycorax Eu adicionei algo, embora não tenha certeza de que é ao longo das linhas que você sugeriu.
Alecos Papadopoulos

@MartijnWeterings Why? se obtivermos todo , obteremos cada número inteiro uma vez. Por que isso é um problema? H
Alecos Papadopoulos

11
Se você entrar nessa interpretação do (extremamente pseudo) gerador de números "aleatórios", como qualquer sequência com a mesma quantidade de 1,2,3,4,5,6,7, poderá também não jogar nenhuma moeda e pegue diretamente a sequência de dígitos no número . 12345679999999
Sextus Empiricus

11
Essa sequência pode ser claramente distinguida de uma sequência de uniformes de iid em {1..7}. Para todos, exceto um valor específico de , a probabilidade de o primeiro valor ser 1 não é . Para qualquer valor de , o evento em que o segundo valor for 2 não será independente do evento em que o primeiro valor for 1. Uma sequência que possui, em média, um número igual de cada valor, é uma condição muito mais fraca que iid uniformes. Por exemplo, uma sequência em que escolho um número de maneira justa e o repito um milhão de vezes, satisfaz a primeira condição (e é muito mais "eficiente" do que esta resposta). 1p p17p
GTC
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.