2011-12-16 16 views
6

me gustaría generar un número aleatorio entre 0 y 3, y tengo el siguiente en mi código:cambiar probabilidad de obtener un número aleatorio

int random = rand() % 4; 

Esto funciona bien, pero me gustaría que genere 1, 2 y 3 la mayoría del tiempo y 0 solo ocasionalmente.

¿Cuál es la mejor manera de hacerlo? ¿Cuáles son los nombres de los algoritmos comunes para abordar este problema?

+0

No es un número aleatorio. Esa es una distribución de probabilidad, que es algo opuesto al azar (la previsibilidad es horrible cuando se habla de un RNG). –

Respuesta

15

Aquí hay una manera. Supongamos que quiere 0, 1, 2, 3 para tener una distribución del 5%, 20%, 30%, 45%.
Se podía hacerlo de esta manera:

double val = (double)rand()/RAND_MAX; 

int random; 
if (val < 0.05)  // 5% 
    random = 0; 
else if (val < 0.25) // 5% + 20% 
    random = 1; 
else if (val < 0.55) // 5% + 20% + 30% 
    random = 2; 
else 
    random = 3; 

Por supuesto que no tiene que ser hecho con coma flotante. Lo hice de esta manera, ya que es más intuitivo.

+0

Por lo que vale, este es el método que realmente uso cuando necesito lidiar con las probabilidades. –

0

¿cuántos números ha probado esto? si es realmente cierto, en su lugar puede generar un rango de 0-> 3999 usando a = rand()%4000 y use int = a/1000 esto debería eliminar el peso del cero aparentemente producido.

+1

Creo que malinterpretaste la pregunta al preguntar exactamente lo contrario de lo que es. El OP dice que 'rand()% 4' distribuye los números de manera uniforme, pero que quiere que el cero ocurra con menos frecuencia. – ruakh

+1

Creo que el OP * quiere * el cero subproducido. No es una observación, es un requisito. –

+0

ah mi mal de alguna manera me perdí las palabras 'Me gustaría' en esa oración – smitec

0

Me gustaría asignar más valores a 1,2,3 desde un conjunto más grande. Por ejemplo: 9 y mapa 1,2,3 => 1, 3,4,5 => 2, 6,7,8 => 3 y 0 para cero. Hay otras formas, pero estoy trabajando en su pregunta

0

código sólo exactamente lo que quiere:

int myrand(void) 
{ 
    const int percentZero = 10; 
    if ((rand()%100) < percentZero) return 0; 
    return 1 + (rand() % 3); 
} 

Puede cambiar el porcentaje de tiempo cero se devuelve a lo que quieras.

1

No proporcionó las proporciones exactas, pero suponga que desea 1, 2 y 3 para que ocurran cada uno el 32% del tiempo, y 0 para que ocurra el otro 4%. Posteriormente, se podría escribir:

int random = rand() % 25; 
if(random > 0) 
    random = random % 3 + 1; 

(Obviamente que había necesidad de ajustar que por diferentes proporciones Y lo anterior es sólo una aproximación, muchos enfoques similares podrían trabajar..)

0

Es necesario encontrar una probabilidad distribución que funcione para su caso. Ya que sólo estamos hablando de los números 0-3 esto es bastante fácil, ya sea que usted podría llamar rand() de nuevo si el primer resultado es un 0, o puede utilizar pesos:

int random = rand() % 16; 

if(random > 10) 
{ 
    random = 3; 
} 
else if(random > 5) 
{ 
    random = 2; 
} 
else if(random > 0) 
{ 
random = 1; 
} 

Esto no es un particular elegante, pero con suerte le muestra cómo puede crear una distribución personalizada para satisfacer sus necesidades.

6

Puede usar la clase discrete_distribution de la biblioteca aleatoria.

#include <iostream> 
#include <random> 
#include <ctime> 

int main() 
{ 
    std::discrete_distribution<> dist({ 1.0, 4.0, 4.0, 4.0 }); 
    std::mt19937 eng(std::time(0)); 
    for (int i=0; i<100; ++i) 
     std::cout << dist(eng); 
} 

Demostración: http://ideone.com/z8bq4

Si no puede utilizar C++ 11, estas clases también existen en alza.

Cuestiones relacionadas