Viernes 19 de marzo de 2021, hace buen tiempo [No te lamentes del pasado, no desperdicies el presente, no temas al futuro]
Contenido de este artículo
1. Introducción
470. Implementar Rand10 () con Rand7 ()
2. Solución del problema (muestreo rechazado)
(randX () - 1) * Y + randY () puede generar números aleatorios en el rango de [1, X * Y] con la misma probabilidad.
Para obtener más información, consulte: Cómo generar números aleatorios de manera uniforme desde el punto de vista más básico
2.1 Método uno
class Solution {
public:
int rand10() {
while(true){
int a = rand7();
int b = rand7();
int num = (a-1)*7 + b; // rand 49
if(num <= 40) return num % 10 + 1; // 拒绝采样
a = num - 40; // rand 9
b = rand7();
num = (a-1)*7 + b; // rand 63
if(num <= 60) return num % 10 + 1;
a = num - 60; // rand 3
b = rand7();
num = (a-1)*7 + b; // rand 21
if(num <= 20) return num % 10 + 1;
}
}
};
Cálculo esperado:
A = 2 + 9/49 * (1 + 3/63 * 1) = 2.192419825072886
p = 9/49 * 3/63 * 1/21 = 0.00041649312786339027
EX = A + A * p + A * p^2 + ... = A / (1 - p) = 2.1933333333333334
2.2 Método 2
class Solution {
public:
int rand10() {
while(true){
int a = rand7(), b = rand7();
while(a == 7) a = rand7(); //让a只能为1到6,保证奇数偶数个数相同
while(b > 5) b = rand7(); //让b只能为1到5
return (a & 1 ? 0 : 5) + b; //相当于将10分解为两个部分,1/2 * 1/5 = 1/10
}
}
};
Cálculo esperado:
E1 = 2 (int a = rand7(), b = rand7();)
E2 = 1/7 * 1 + 1/7 * 1/7 * 1 + 1/7 * 1/7 * 1/7 * 1... = 1/6 (while(a == 7) a = rand7();)
E2 = 2/7 * 1 + 2/7 * 2/7 * 1 + 2/7 * 2/7 * 2/7 * 1... = 2/5 (while(b > 5) b = rand7();)
E = E1 + E2 + E3 = 2 + 1/6 + 2/5 = 2.566666666666667
referencias
https://leetcode-cn.com/problems/implement-rand10-using-rand7/solution/yong-rand7-shi-xian-rand10-by-leetcode/
https://leetcode-cn.com/problems/implement-rand10-using-rand7/solution/cong-zui-ji-chu-de-jiang-qi-ru-he-zuo-dao-jun-yun-/