Rompecabezas: ¿Cómo generar 7 enteros con la misma probabilidad usando una moneda sesgada que tiene una pr (cabeza) = p?


58

Esta es una pregunta que encontré en Glassdoor : ¿Cómo se generan 7 enteros con la misma probabilidad usando una moneda que tiene un ?PAGSr(Cabeza)=pags(0 0,1)

Básicamente, tiene una moneda que puede ser justa o no, y este es el único proceso de generación de números aleatorios que tiene, por lo tanto, cree un generador de números aleatorios que genere enteros del 1 al 7 donde la probabilidad de obtener cada uno de estos enteros es 1/7.

La eficiencia del proceso de generación de datos es importante.


Relacionado, no engañado
Reinstale Monica el

12
Hay miles de formas de lograr esto. Una versión más interesante de la pregunta pide el mejor método en un sentido bien definido. Un sentido natural de mejor sería el número menos esperado de lanzamientos por entero generado. Otra versión interesante es describir todas las soluciones posibles (que se basan en lanzamientos independientes de la moneda y nada más).
whuber

1
@buena sugerencia, he editado la pregunta para reflejar su comentario.
Amazonian

<<< Básicamente, usted tiene una moneda que puede ser justa o no, y este es el único proceso de generación de números aleatorios que tiene >>> ¿Significa esto que usa la moneda en un método diferente a voltearla y verificar la cabeza? vs cola está "prohibido", ya que sería otro proceso de generación de números aleatorios?
TinglTanglBob

99
Mod 7 del año en la moneda.
Nat

Respuestas:


56

Lanza la moneda dos veces. Si aterriza HHo TT, ignóralo y dale la vuelta dos veces.

Ahora, la moneda tiene la misma probabilidad de aparecer HTo TH. Si aparece HT, llame a esto H1. Si aparece TH, llame a esto T1.

Sigue obteniendo H1o T1hasta que tengas tres seguidos. Estos tres resultados le dan un número basado en la tabla a continuación:

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 esto funcionaría perfectamente bien, aunque tendrías muchos tiros desperdiciados en el proceso!


44
La única restricción es que la probabilidad de caras es "p". Tenga en cuenta que p podría ser o 1 . Por lo tanto, no se garantiza que funcione, pero Sycorax (o Sephan's) funcionaría, incluso en esos casos. 01
gung - Restablece a Monica

8
@gung: No estoy seguro de que trabajaría para una moneda con dos caras o dos colas.
S. Kolassa - Restablece a Mónica el

66
Con probabilidad terminará en tiempo finito. 1
clark

18
Esto se llama blanqueamiento de Von-Neuman.
DonFusili

44
Puede iterar el extractor von Neumann para extraer más completamente la entropía de la secuencia. Reúna todos los pares HH y TT, considere que es una secuencia, aplique el extractor von Neumann a eso, etc.
Un Simmons el

47

Suponga que .pags(0 0,1)

Paso 1: . Lanza la moneda 5 veces.

Si el resultado es

, regrese 1 y pare.(H,H,H,T,T)1

, regrese 2 y pare.(H,H,T,T,H)2

, regrese 3 y pare.(H,T,T,H,H)3

, regrese 4 y pare.(T,T,H,H,H)4 4

, regrese 5 y pare.(T,H,H,H,T)5 5

, regrese 6 y pare.(H,H,T,H,T)6 6

, regrese 7 y pare.(H,T,H,T,H)7 7

Paso 2: . Si el resultado no es ninguno de los anteriores, repita el Paso 1.

Tenga en cuenta que, independientemente del valor de , cada uno de los siete resultados enumerados anteriormente tiene una probabilidad q = p 3 ( 1 - p ) 2 , y el número esperado de lanzamiento de monedas es 5pags(0 0,1)q=p3(1p)2 . El lanzador no necesita saber el valor dep(excepto quep0yp1); se garantiza que los siete enteros tienen la misma probabilidad de ser devueltos por el experimento cuando finaliza (y se garantiza que terminará con la probabilidad1).57qpagspags0 0pags11


66
¿Podemos reducir el número esperado de lanzamientos para esto al permitir la secuencia especificada aquí O esa secuencia con cada giro invertido? Por ejemplo: para 1, ¿(H, H, H, T, T) o (T, T, T, H, H)?
moreON

55
También puedes agregar el complemento. Si el resultado es (H, H, H, T, T) o (T, T, T, H, H), devuelva 1 y pare, etc. En ese caso, la probabilidad de cada resultado es . q=p3(1p)2+p2(1p)3
Sextus Empiricus

2
¿No sería posible agregar otro lanzamiento de moneda si el resultado no está dentro de ningún arreglo (H, H, H, T, T)? Con el lanzamiento de moneda adicional, necesitaría otro mapeo de (H, H, H, T, T, T) y (H, H, T, T, T, T) y cada combinación de xT (7-x) H que se pueden organizar en 7 o más órdenes diferentes a los números del 1 al 7. En lugar de desafiar las 5 monedas, esto agregaría solo 1 lanzamiento adicional, pero no estoy seguro de si funciona: D
TinglTanglBob

55
Tal vez sea lo mejor tirar la moneda al instante 7 veces, ya que está garantizado que obtendrá un número aleatorio (por lo tanto, la única excepción es que la moneda cae cara arriba o cola los 7 intentos) . Entonces, con 7 lanzamientos, podría terminar con 1 hasta 6 caras (excluyo la opción 0 y 7 aquí porque no tiene sentido). Si una cabeza hay 7 arreglos diferentes de (H, T, T, T, T, T, T) posibles; Si 2 encabeza sus 21; si 3 encabeza sus 35; si 4 35 cabezas; si 5 21 cabezas; si 6 7 cabezas; Cada uno se puede asignar perfectamente al número 1-7 sin perder ninguna combinación.
TinglTanglBob

2
@TinglTanglBob Esta es esencialmente la respuesta de Martijn Weterings ;-)
M.Herzkamp

22

Generalizando el caso descrito por Dilip Sarwate

Algunos de los métodos descritos en las otras respuestas usan un esquema en el que lanzas una secuencia de n monedas en un 'turno' y, dependiendo del resultado, eliges un número entre 1 o 7 o descartas el turno y vuelves a lanzar.

El truco consiste en encontrar en la expansión de posibilidades un múltiplo de 7 resultados con la misma probabilidad pk(1p)nk y compararlos entre sí.

Debido a que el número total de resultados no es un múltiplo de 7, tenemos algunos resultados que no podemos asignar a un número, y tenemos alguna probabilidad de que debamos descartar los resultados y comenzar de nuevo.


El caso de usar 7 lanzamientos de monedas por turno

Intuitivamente podríamos decir que tirar los dados siete veces sería muy interesante. Ya que solo necesitamos tirar 2 de las 27 posibilidades. A saber, las cabezas de 7 veces y las cabezas de 0 veces.

Para todas las otras 272 posibilidades, siempre hay un múltiplo de 7 casos con el mismo número de cabezas. A saber, 7 casos con 1 cabezales, 21 casos con 2 cabezas, 35 casos con 3 cabezas, 35 casos con 4 cabezas, 21 casos con 5 cabezas y 7 casos con 6 cabezas.

Entonces, si calcula el número (descartando 0 cabezas y 7 cabezas)

X=k=17(k1)Ck

con Ck variables distribuidas de Bernoulli (valor 0 o 1), entonces X módulo 7 es una variable uniforme con siete resultados posibles.


Comparar diferentes números de lanzamientos de monedas por turno

La pregunta sigue siendo cuál sería el número óptimo de rollos por turno. Tirar más dados por turno le cuesta más, pero reduce la probabilidad de tener que tirar nuevamente.

La imagen a continuación muestra cálculos manuales para los primeros números de lanzamientos de monedas por turno. (posiblemente podría haber una solución analítica, pero creo que es seguro decir que un sistema con 7 monedas arroja el mejor método con respecto al valor esperado para la cantidad necesaria de monedas)

número esperado de lanzamientos de monedas

# 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)
}

Usar una regla de detención temprana

nota: los cálculos a continuación, para el valor esperado del número de lanzamientos, son para una moneda justa p=0.5 , sería un desastre hacer esto para diferentes p , pero el principio sigue siendo el mismo (aunque la contabilidad diferente del se necesitan casos)

Deberíamos poder elegir los casos (en lugar de la fórmula para X ) de modo que podamos detenernos antes.

  • Con 5 lanzamientos de monedas tenemos los seis posibles conjuntos diferentes de cabezas y colas desordenadas:

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

    Y podemos usar los grupos con diez casos (es decir, el grupo con 2 cabezas o el grupo con 2 colas) para elegir (con igual probabilidad) un número. Esto ocurre en 14 de 2 ^ 5 = 32 casos. Esto nos deja con:

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

  • Con un lanzamiento de moneda adicional (6º) tenemos para los siete posibles conjuntos diferentes de cabezas y colas desordenadas:

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

    Y podemos usar los grupos con ocho casos (es decir, el grupo con 3 cabezas o el grupo con 3 colas) para elegir (con igual probabilidad) un número. Esto ocurre en 14 de 2 * (2 ^ 5-14) = 36 casos. Esto nos deja con:

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

  • Con otro lanzamiento de moneda adicional (7º) tenemos para los ocho posibles conjuntos de cabezas y colas diferentes sin ordenar:

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

    Y podemos usar los grupos con siete casos (todos excepto los casos con todas las colas y todas las cabezas) para elegir (con igual probabilidad) un número. Esto ocurre en 42 de 44 casos. Esto nos deja con:

    Conjuntos ordenados 1 + 0 + 0 + 0 + 0 + 0 + 0 + 1

    (podríamos continuar esto, pero solo en el paso 49 nos da una ventaja)

Entonces la probabilidad de seleccionar un número

  • a 5 vueltas es 1432=716
  • a las 6 vueltas es 9161436=732
  • a las 7 vueltas es 11324244=231704
  • no en 7 flips es 1716732231704=227

Esto hace que el valor esperado para el número de vueltas en un turno, sea condicional que haya éxito y p = 0.5:

5716+6732+7231704=5.796875

El valor esperado para el número total de vueltas (hasta que haya un éxito), condicional de que p = 0.5, se convierte en:

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


La respuesta de NcAdams utiliza una variación de esta estrategia de regla de detención (cada vez que aparece dos nuevos lanzamientos de monedas) pero no está seleccionando de manera óptima todos los lanzamientos.

La respuesta de Clid también podría ser similar, aunque podría haber una regla de selección desigual de que cada moneda arroje un número podría elegirse, pero no necesariamente con la misma probabilidad (una discrepancia que se repara durante las monedas lanzadas posteriormente)


Comparación con otros métodos.

Otros métodos que utilizan un principio similar son el de NcAdams y AdamO.

El principio es : una decisión para un número entre 1 y 7 se toma después de un cierto número de caras y colas. Después de un número x de vueltas, para cada decisión que conduce a un número i hay una decisión similar, igualmente probable, que conduce a un número j (el mismo número de caras y colas pero solo en un orden diferente). Algunas series de cara y cruz pueden llevar a la decisión de comenzar de nuevo.

Para este tipo de métodos, el que se coloca aquí es el más eficiente porque toma las decisiones lo antes posible (tan pronto como exista la posibilidad de 7 secuencias de igual probabilidad de cara y cruz, después de la x giro -th, podemos usar para que tomen una decisión sobre un número y no es necesario que volteemos más si encontramos uno de esos casos).

Esto se demuestra en la imagen y simulación a continuación:

comparación

#### 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)
}

otra imagen que está escalada por p(1p) para una mejor comparación:

comparación con valores de expectativa escalados

amplíe los métodos de comparación descritos en esta publicación y comentarios

métodos de comparación descritos aquí

El 'salto condicional del séptimo paso' es una ligera mejora que se puede hacer en la regla de detención temprana. En este caso, selecciona no grupos con probabilidades iguales después de la sexta vuelta. Tienes 6 grupos con probabilidades iguales, y 1 grupos con una probabilidad ligeramente diferente (para este último grupo necesitas voltear una vez más cuando tienes 6 caras o colas y porque descartas las 7 caras o 7 colas, terminarás con la misma probabilidad después de todo)


Escrito por StackExchangeStrike


Estaba a punto de comenzar a hacer los cálculos para el caso n = 7, porque tenía la sensación de que podría ser mejor que n = 1. ¡Tenga mi voto a favor, señor!
M.Herzkamp

@ M.Herzkamp todavía es posible una pequeña mejora. No es necesario un número (una moneda) para el cálculo de X , ya que tiene el coeficiente 0. Este número solo es necesario para determinar el caso de todas las caras o todas las colas, y puede omitirse cuando ya sabemos que Tenemos un caso mixto. CkX
Sextus Empiricus

Entonces, la mejora lo reduce a un poco más de 6 lanzamientos de monedas como valor esperado para el número de lanzamientos de monedas requeridos. Sin embargo, sería diferente para probar que esta es la solución óptima. El esquema creado por Clid diverge un poco, lo que permite elegir un número en un número particular de lanzamientos de monedas, pero no con la misma probabilidad (al menos no para ese paso en particular, se corregirá más adelante).
Sextus Empiricus

Pero si está decidiendo si lanza la sexta moneda en función de los primeros cinco resultados, ¿las probabilidades de cada conjunto están condicionadas a que haya obtenido seis lanzamientos, lo mismo que para los otros conjuntos?
Acumulación

@ Acumulación, puede dibujarlo como un árbol binario con 7 niveles. Solo seleccionaremos entre nodos si hay 7 con igual probabilidad. Es como cortar algunas ramas antes (en el nivel 5 o 6). Si lo desea, puede continuar hasta los 7 pasos, en lugar de antes, pero para estos casos particulares, el lanzamiento de la sexta y la séptima moneda no hace la diferencia.
Sextus Empiricus

20

Divida una caja en siete regiones de área igual, cada una etiquetada con un número entero. Tire la moneda en la caja de tal manera que tenga la misma probabilidad de aterrizar en cada región.

π usando un procedimiento físico de Monte Carlo, como dejar caer granos de arroz en papel con un círculo dibujado sobre él.

p=1p=0


2
¿Puede sugerir una forma de dividir la caja en siete regiones de igual área, para minimizar el sesgo de voltear, rebotar en las paredes, etc.? ¿Siete sectores de ángulo 360/7?
smci

1
@smci Es por eso que estipulo que debes tirar la moneda para que haya una probabilidad uniforme de que caiga en cada casilla. Si rebotar en un muro influye en esa probabilidad, entonces debes tenerlo en cuenta en tu lanzamiento.
Restablece a Mónica el

17
Sí lo sé, y yo estoy señalando a usted que simplemente diciendo "tirarlo de una manera imparcial" , sin definir exactamente cómo lograr que, en realidad no es una respuesta completa ... en cuyo caso el mover de un tirón-H / T Los métodos basados ​​son superiores.
smci

1
"Áreas iguales, con lanzamientos que tienen la misma probabilidad de aterrizar en cada región" podría ser difícil de establecer en la práctica. En la práctica, podría ser más fácil marcar una gran cantidad de "carreras de práctica" y luego subdividir el área de aterrizaje en espacios equipables empíricamente (por ejemplo, con 700 lanzamientos, descartar una línea que corta los 100 lanzamientos más lejanos, y luego otra para el siguiente 100 y así sucesivamente). Una simplificación de esto para generar un solo bit aleatorio sería lanzar la moneda dos veces: si el primer lanzamiento va más allá, el bit es 0, y si el segundo lanzamiento va más lejos es un1
Silverfish

44
Hay una buena respuesta de @TheScienceBoy que lamentablemente se elimina con una alternativa interesante a esto: efectivamente, usar la moneda como un hilandero y marcar 7 secciones a lo largo de su circunferencia, que retiene gran parte del espíritu de esta respuesta, pero puede ser físicamente más directo ¡llevar a cabo!
Silverfish

8

EDITAR: basado en los comentarios de otros.

Aquí hay un pensamiento interesante:

establecer la lista de {1,2,3,4,5,6,7}. Lanza la moneda para cada elemento de la lista secuencialmente. Si aterriza con la cabeza hacia arriba para un elemento en particular, elimine el número de la lista. Si se eliminan todos los números de una iteración particular de la lista, repita el muestreo. Hazlo hasta que solo quede un 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 da una distribución 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 

norte


Evaluación del valor esperado para el número de lanzamientos de monedas.

Xy

METRO=[q7 70 00 00 00 00 0117 7pags1q6 6q6 60 00 00 00 00 00 021pags2q5 56 6pags1q5 5q5 50 00 00 00 00 035pags3q4 415pags2q4 45 5q4 4q4 40 00 00 00 035pags4 4q320pags3q310pags2q34 4pags1q3q30 00 00 021pags5 5q215pags4 4q210pags3q26 6pags2q23pags1q2q20 00 07 7pags6 6q16 6pags5 5q15 5pags4 4q14 4pags3q13pags2q12pags1q10 00 0pags7 7pags6 6pags5 5pags4 4pags3pags20 00 0]

(METRO-yo)v=0 0 ) representa cuánto tiempo se pasa relativamente en qué estado. Luego, el séptimo estado es la frecuencia con la que podrá dibujar un número del 1 al 7. Los otros estados indican cuántas monedas arroja.

mi(norte)=247 7pags(1-pags)

comparación del valor esperado para lanzar monedas

pags>2/ /3 . Pero también el rendimiento no es simétrico. Se podría lograr un rendimiento general simétrico y mejor cuando se hiciera una regla de cambio probabilístico que cambie la regla de decisión de colas a cabezas cuando las cabezas sean improbables.

Solución encontrada con 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 en 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))

1
Idea inteligente (+1). Intuitivamente, debería funcionar, ya que la simetría parecería anular el sesgo hacia cualquier número en particular. Aún así, me encantaría ver una prueba.
Vuelva a instalar Mónica

66
Esta idea es realmente buena, pero con una alta probabilidad de cabeza (elimine ese número), ¿creo que el último número de la fila tiene las mejores posibilidades de "sobrevivir" ya que todos los demás en el frente son expulsados ​​muy probablemente antes en la carrera 1? ¿Tal vez podría cambiarse no lanzando secuencialmente la moneda sino en paralelo para todos los números en x? El tiempo de ejecución del script podría aumentar, supongo :)
TinglTanglBob

2
Estoy de acuerdo con @TinglTanglBob: cuando configuro p <- 0.99obtengo la salida0.89 0.02 0.02 0.02 0.02 0.02 0.02
Silverfish el

66
¿Realizar la eliminación en 'rondas' no solucionaría el problema de sesgo? Comience con 7 números. Lanza la moneda por cada número restante y elimina los que arrojan cabeza. Si todos los números restantes se eliminan en una ronda, anote los resultados de esa ronda e intente nuevamente. No sé cómo demostrarlo, pero intuitivamente el orden de los números ya no importa si son el 'ganador'
Phil

1
pags=0,01

5

La pregunta es un poco ambigua, ¿está preguntando "generar un número entero aleatorio igual o menor a 7 con igual probabilidad", o es "generar 7 números enteros aleatorios con igual probabilidad"? - ¿Pero cuál es el espacio de los enteros?

Asumiré que es el primero, pero la misma lógica que estoy aplicando también se puede extender al último caso, una vez que se solucione el problema.

Con una moneda sesgada, puede producir una moneda justa siguiendo el siguiente procedimiento: https://en.wikipedia.org/wiki/Fair_coin#Fair_results_from_a_limited_coin

Un número 7 o menos puede escribirse en binario como tres {0,1} dígitos. Entonces, todo lo que hay que hacer es seguir el procedimiento anterior tres veces y convertir el número binario producido de nuevo a decimal.


1
Al comparar mi respuesta con @NcAdams, ¡está claro que incluyo 0 como posible resultado deseable!
Cam.Davidson.Pilon

No entiendo cómo tu respuesta es diferente. Si incluye {0,0,0} -> 1, ¿a qué se asigna {1,1,1}? Hay 8 posibilidades.
AdamO

1
000 mapas a 0, de ahí mi comentario sobre la inclusión de 0 como un posible valor. Esto fue publicado antes de la edición de OP y casi simultáneamente como NcAdams.
Cam.Davidson.Pilon

La mitad de esta respuesta es un comentario, y el contenido real de la respuesta es solo de enlace. Por favor, deletree su respuesta real en lugar de simplemente vincularla.
Cubic

3

Una solución que nunca desperdicia lanzamientos, lo que ayuda mucho a las monedas muy sesgadas.

La desventaja de este algoritmo (como está escrito, al menos) es que está usando aritmética de precisión arbitraria. Prácticamente, es probable que desee usar esto hasta que se desborde el número entero, y solo luego desecharlo y comenzar de nuevo.

Además, es necesario saber lo que el sesgo es ... que no se puede, por ejemplo, si es dependiente de la temperatura como la mayoría de los fenómenos físicos.


Suponiendo que la probabilidad de que salgan cabezas es, digamos, 30%.

  • Comience con el rango [1, 8).
  • Lanza tu moneda. Si sale cara, use el 30% de la izquierda, entonces su nuevo rango es [1, 3.1). De lo contrario, use el 70% correcto, por lo que su nuevo rango es [3.1, 8).
  • Repita hasta que todo el rango tenga la misma parte entera.

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
[0 0,1]0000...6666...k

Eso es lo mismo para una sola salida, ¿verdad? ¿Solo mejor para múltiples? Lo escribiría como diff *= 7creo ... de hecho, no hay necesidad particular de usar la misma base para cada intento.
o11c

Sí, es lo mismo si quieres una sola salida; solo mejora la eficiencia si quieres múltiples.
Federico Poloni

pagspags

Esto absolutamente desperdicia volteretas si desea una sola salida. Para una moneda justa, la técnica estándar (tira la moneda tres veces y repite si obtienes TTT) da un número esperado de 24/7 = 3 + 3/7 rollos. Si utiliza esta técnica de estilo de codificación aritmética, tira al menos cuatro veces a menos que obtenga HHH o TTT, lo que le da un número esperado de más de 15/4 = 3 + 3/4 rollos.
Peter Shor

3

Como se mencionó en los comentarios anteriores, este rompecabezas se relaciona con John von Neumann 1951 papel "diferentes técnicas utilizadas en conexión con al azar dígitos", publicado en la revista de investigación de la Oficina Nacional de Normalización:

ingrese la descripción de la imagen aquí

pagsF(pags)F F(pags)=min{1,2pags}norte de juicios.


2

pags1pags0 0

Primero convertimos la (posiblemente) moneda injusta en una moneda justa usando el proceso de la respuesta de NcAdams :

Lanza la moneda dos veces. Si aterriza HHo TT, ignóralo y dale la vuelta dos veces.

Ahora, la moneda tiene la misma probabilidad de aparecer HTo TH. Si aparece HT, llame a esto H1. Si aparece TH, llame a esto T1.

0 01H1=1T1 =0 00.H1 H1 T10.110

1/ /7 7

1/ /7 7=0.001001001...

2/ /7 7=0,010010010...

3/ /7 7=0,011011011...

4 4/ /7 7=0.100100100...

5 5/ /7 7=0,101101101...

6 6/ /7 7=0.110110110...

nortenorte/ /7 7(norte-1)/ /7 717 7


1
1/ /7 7

1
1/ /7 7k=1(1/ /8)k=17 7

1
norteT(norte)=2norte-6 62nortenorte3
3+norte=31-T(norte)=4.5 4.5
87 733,42

2

Inspirado por la respuesta de AdamO, aquí hay una solución de Python que evita el sesgo:

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

Aquí hay dos cambios principales: el principal es que si todos los números se descartan en una ronda, repita la ronda. También cambio la elección de si cara o cruz significa descartar todo el tiempo. Esto reduce el número de vueltas necesarias en casos donde p está cerca de 0 o 1 en ~ 70% cuando p = 0.999


2
"Volteo la opción de si cara o cruz significa descartar todo el tiempo. Esto reduce la cantidad de vueltas necesarias en casos donde p está cerca de 0 o 1 en ~ 70% cuando p = 0.999" - ¡pensamiento inteligente!
Silverfish

1
Alternar caras o colas es definitivamente una mejora sobre descartar siempre caras, pero tal vez sería mejor si, después de lanzar una moneda por cada opción restante, si son todas iguales, repetimos volver a colocarlas todas, de lo contrario si hay al menos tantas caras como colas eliminamos las opciones restantes correspondientes a cabezas, de lo contrario eliminamos las opciones restantes correspondientes a colas.
David Cary

2

Parece que podemos cambiar el mapeo del resultado de cada volteo, cada vez que volteamos . Entonces, usando por conveniencia los primeros siete enteros positivos, damos las siguientes órdenes:

H1
H2

H7 7
H1

etc.

T


UNAPAGST

PAGSUNAPAGS(no se generan enteros)=(1-pags)7 7

nortesi

ContarUNAPAGS(volteretas inútiles)7 7nortesi(1-pags)7 7

si(pags,norte=5 5)pags3(1-pags)2

PAGSreS(no se generan enteros)=1-7 7pags3(1-pags)2

El recuento de volteretas inútiles tenderá aquí a

ContarreS(volteretas inútiles)5 5nortesi[1-7 7pags3(1-pags)2]

Para el UNAPAGS

ContarUNAPAGS(volteretas inútiles)<ContarreS(volteretas inútiles)

7 7nortesi(1-pags)7 7<5 5nortesi[1-7 7pags3(1-pags)2]

7 7(1-pags)7 7<5 5[1-7 7pags3(1-pags)2]

pags>0,0467UNAPAGS

pagsUNAPAGSreSpags0,5967

ContarUNAPAGS(volteretas inútiles)ContarreS(volteretas inútiles)

0,67pags=0.10,3pags=0.2 0.20,127pags=0.4 0.4


pags(0 0,1)

1
@Sycorax Agregué algo, aunque no estoy seguro de que esté en la línea que sugirió.
Alecos Papadopoulos

H

1
Si entras en esta interpretación del generador de números (extremadamente pseudo) "aleatorio", como cualquier secuencia con la misma cantidad de 1,2,3,4,5,6,7, entonces tampoco puedes tirar ninguna moneda y tomar directamente la secuencia de dígitos en el número 12345679999999

1
pags17 7pags
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.