Saltar al contenido

Generando booleano aleatorio

Hacemos una verificación exhaustiva cada uno de los enunciados de nuestra página web con el objetivo de enseñarte siempre información más veraz y actualizada.

Solución:

El STL en C ++ 11 tiene incorporados métodos de generación de números aleatorios que son superiores a rand(). Puede simular un booleano aleatorio a través de un entero aleatorio que sea 0 o 1:

#include 
#include 

int main(int argc, char *argv[]) 
    auto gen = std::bind(std::uniform_int_distribution<>(0,1),std::default_random_engine());
    const unsigned int N = 100;
    unsigned int numTrue = 0;
    unsigned int numFalse = 0;
    for (int i = 0; i < 100; ++i) 
        bool b = gen();
        if (b) ++ numTrue;
        else ++numFalse;
    
    std::cout << numTrue << " TRUE, " << numFalse << " FALSE" << std::endl;

Puede encontrar más detalles sobre esta biblioteca en las referencias estándar de C ++. Por ejemplo, si desea algo diferente a una proporción de 50/50 de "true" y "false", puede crear un número de punto flotante aleatorio entre 0 y 1 y llamar a valores inferiores a un umbral z true, de lo contrario false.

¿Por qué ves largas rayas? Creo

No he abordado por qué obtiene 30 valores de "true" o "false"en una fila con su código. Aunque rand() ya no debería usarse, y parece que tiene algunas sumas y restas innecesarias de unos y ceros en su código, no debería haber tal problema. Sin embargo, ahora me doy cuenta de que el texto de su pregunta es ambiguo. Si está ejecutando y saliendo de su programa 30 veces seguidas, debería esperar ver valores repetidos, incluso con mi código. La mayoría de los generadores de números aleatorios son en realidad generadores de números pseudoaleatorios. Cada vez que ejecute el programa, producirán el mismo secuencia de números aleatorios; esto es importante para la coherencia de los resultados. Sin embargo, mientras el programa se está ejecutando (p. Ej. randomBool() en un bucle), no debería ver rayas de tal longitud, ya que serían muy improbables.

Improbabilidad de rachas largas

Me sorprendió recibir comentarios que no estaban de acuerdo con mi afirmación de que una racha de 30 "true" o "false"booleanos aleatorios es improbable (cuando true o false son igualmente probables). Me doy cuenta de que un malentendido común de la probabilidad es que la "suerte" intenta igualar las cosas, de modo que si el lanzamiento de una moneda sale cara un par de veces seguidas, el universo intentará corregir esto y hacer cruz más. probable. Debido a este malentendido, la gente subestima la probabilidad de obtener rayas de todas las caras y todas las cruces, y creo que las motivaciones de los comentarios sobre esta respuesta y la pregunta principal fueron corregir este error común.

Sin embargo, hay una verdadero razón por la que las rachas largas (especialmente de hasta 30) son cada vez más improbables. Usando el lenguaje de los lanzamientos de monedas sin sesgo al azar, cada lanzamiento de moneda IID (independiente y distribuido de manera idéntica) tiene solo un 50% de probabilidad de ser el mismo que el anterior. Por lo tanto, la probabilidad de una racha larga disminuye exponencialmente con la longitud de la racha. Para una racha de longitud L, la probabilidad de una racha de todas las caras es 1 en 2 ^ L; la probabilidad de una racha de cualquier tipo es 2 en 2 ^ L o 1 en 2 ^ (L-1). Aquí hay un código para demostrar:

#include 
#include 
#include 

bool randomBool() 
    static auto gen = std::bind(std::uniform_int_distribution<>(0,1),std::default_random_engine());
    return gen();


int main(int argc, char *argv[]) 

    const unsigned int N = 1e8;
    std::map histogram;
    bool current = randomBool();
    unsigned int currentLength = 1;
    for (int i = 0; i < N; ++i) 
        bool b = randomBool();
        if (b == current) 
            ++currentLength;
         else 
            auto it = histogram.find(currentLength);
            if (it != histogram.end())
                it->second += 1;
            else
                histogram.insert(std::make_pair(currentLength,1));
            currentLength = 1;
        
        current = b;
    

    for (auto pair : histogram) 
        std::cout << "STREAK LENGTH " << pair.first << " OCCURS " << pair.second << " TIMES" << std::endl;

El histograma de salida es:

STREAK LENGTH 1 OCCURS 25011106 TIMES
STREAK LENGTH 2 OCCURS 12503578 TIMES
STREAK LENGTH 3 OCCURS 6249056 TIMES
STREAK LENGTH 4 OCCURS 3125508 TIMES
STREAK LENGTH 5 OCCURS 1560812 TIMES
STREAK LENGTH 6 OCCURS 781206 TIMES
STREAK LENGTH 7 OCCURS 390143 TIMES
STREAK LENGTH 8 OCCURS 194748 TIMES
STREAK LENGTH 9 OCCURS 97816 TIMES
STREAK LENGTH 10 OCCURS 48685 TIMES
STREAK LENGTH 11 OCCURS 24327 TIMES
STREAK LENGTH 12 OCCURS 12176 TIMES
STREAK LENGTH 13 OCCURS 6149 TIMES
STREAK LENGTH 14 OCCURS 3028 TIMES
STREAK LENGTH 15 OCCURS 1489 TIMES
STREAK LENGTH 16 OCCURS 811 TIMES
STREAK LENGTH 17 OCCURS 383 TIMES
STREAK LENGTH 18 OCCURS 193 TIMES
STREAK LENGTH 19 OCCURS 104 TIMES
STREAK LENGTH 20 OCCURS 43 TIMES
STREAK LENGTH 21 OCCURS 20 TIMES
STREAK LENGTH 22 OCCURS 14 TIMES
STREAK LENGTH 23 OCCURS 4 TIMES
STREAK LENGTH 24 OCCURS 3 TIMES

Es difícil calcular el número esperado de rayas de longitud L en varios giros N, ya que hay muchos tramos superpuestos de longitud L donde podría existir tal racha. Sin embargo, tenga en cuenta que este histograma sigue una distribución aproximadamente exponencial, con cada entrada aproximadamente la mitad de la entrada anterior.

La racha máxima es 24 [note: a bug in the previous version counted this as 23]. La probabilidad de una racha de esta longitud en cualquier string de 24 lanzamientos es 1 en 2 ^ (24-1), o aproximadamente 1 en 8 millones. Dado que en 1e8 lanzamientos hay alrededor de 1e8 / 24 ~ 4.3 millones de estiramientos separados, esperamos una pequeña cantidad de tales rachas, por lo que esto parece correcto [with my above caveat that calculating the exact expectation is difficult]. Mientras tanto, una racha de longitud 30 tiene una probabilidad de 1 en 537 millones en cualquier tramo independiente de 30 lanzamientos, y es mucho menos probable incluso que una racha de longitud 24.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *