c++ - repetir - Genere un número aleatorio de menos de 4 dígitos, pero la probabilidad de que tenga 1, 2 o 3 dígitos es igual
generar numeros aleatorios en un arreglo en c++ (3)
Actualmente estoy usando 1 + (int)(rand() * 999.0 / RAND_MAX)
para generar un número aleatorio entre 1 y 999 inclusive, pero los números de dos y uno dígitos no ocurren tan a menudo como los números de tres dígitos.
¿Cómo puedo arreglar esto?
Tenga en cuenta que aunque el código original ofrece un rango de 0 a 999 inclusive, en realidad quiero un rango de 1 a 999 inclusive.
Puedes hacerlo en una declaración que usa 2 randoms. Multiplica el primero por 10 ** segundo. El segundo es 1, 2 o 3. Aquí está como una fórmula de Excel:
=Int(Rand()*10^(int(Rand()*3)+1))
Su observación de que los números de un dígito no ocurren tan a menudo como los de dos y tres dígitos no es sorprendente.
Solo hay 9 números de un dígito (sin incluir el cero), pero hay 90 números de dos dígitos y 900 números de tres dígitos. Así que un generador de números aleatorios uniforme dibujará números en esa frecuencia.
Para generar números aleatorios en el rango [1, 999] de manera que la probabilidad de que tengan 1, 2 y 3 dígitos sea igual, use su generador favorito para generar un número aleatorio p
, por ejemplo, en el rango [0, 1) (vea las nuevas funciones de biblioteca aleatoria en C ++ para hacer eso), y transforme usando std::pow(1000, p);
.
Debe tener en cuenta que la distribución resultante no será uniforme por partes : es decir, que la probabilidad de dibujar un número con un cierto número de dígitos no es la misma que la probabilidad de dibujar cualquier otro número con ese número de dígitos. Pero tiene una función de densidad acumulativa continua y diferenciable que puede ser importante matemáticamente.
(Para la inclinación matemática, la transformación que estoy aplicando es la función cuantil de la distribución que necesita el OP).
También puedes usar sentencias if, que son un poco más rápidas:
int m=rand();
if(m%3+1==3)
z=(int)rand()%900+100;
else if(m%3+1==2)
z=(int)rand()%90+10;
else if(m%3+1==1)
z=(int)rand()%10;
La diferencia de clock()
para 100,000,000 repeticiones es:
t_pow: 23912
t_if: 6640
Código de prueba usando tics de reloj para la distribución del rendimiento - IF , POW
Diferencia en la distribución entre if y pow variant: Parcela en wolframalpha.com