Random numbers are always the same

6

Why is this code always displaying the same random number results as a given?

// Figura 6.9: fig06_09.cpp
// Lança um dado de seis lados 6.000.000 de vezes.
#include <iostream>
using std::cout;
using std::endl;

#include <iomanip>
using std::setw;

#include <cstdlib> // contém o protótipo de função para rand
using std::rand;

int main()
{
    int frequency1 = 0; // contagem de 1s lançado
    int frequency2 = 0; // contagem de 2s lançado
    int frequency3 = 0; // contagem de 3s lançado
    int frequency4 = 0; // contagem de 4s lançado
    int frequency5 = 0; // contagem de 5s lançado
    int frequency6 = 0; // contagem de 6s lançado

    int face; // armazena o valor lançado mais recente

    // resume os resultados de 6,000,000 lançamentos de um dado
    for(int roll = 1; roll <= 6000000; roll++ )
    {
        face = 1 + rand() % 6;

        // determina valor de lançamento de 1 a 6 e incrementa o contador apropriado
        switch(face)
        {
            case 1:
                ++frequency1;
                break;
            case 2:
                ++frequency2;
                break;
            case 3:
                ++frequency3;
                break;
            case 4:
                ++frequency4;
                break;
            case 5:
                ++frequency5;
                break;
            case 6:
                ++frequency6;
                break;
            default:
                cout << "Program should never get here!";
        } // fim do switch
    } // fim do for

    cout << "Face" << setw(13) << "Frequency" << endl;
    cout << "   1" << setw(13) << frequency1
        << "\n  2" << setw(13) << frequency2
        << "\n  3" << setw(13) << frequency3
        << "\n  4" << setw(13) << frequency4
        << "\n  5" << setw(13) << frequency5
        << "\n  6" << setw(13) << frequency6 << endl;
    return 0; // indica terminação bem-sucedida
}  // fim de main
    
asked by anonymous 29.08.2017 / 16:44

3 answers

5

You need to initialize the seed of random numbers. Usually this is done by the computer clock, which attends well simple situations. If you need a better distribution it is better to use the random generator of C ++ itself and not C, it is much better.

#include <iostream>
#include <iomanip>
#include <ctime>
#include <cstdlib> // contém o protótipo de função para rand
using namespace std;

int main() {
    srand(time(NULL));
    int frequency1 = 0; // contagem de 1s lançado
    int frequency2 = 0; // contagem de 2s lançado
    int frequency3 = 0; // contagem de 3s lançado
    int frequency4 = 0; // contagem de 4s lançado
    int frequency5 = 0; // contagem de 5s lançado
    int frequency6 = 0; // contagem de 6s lançado
    int face; // armazena o valor lançado mais recente
    for (int roll = 1; roll <= 6000000; roll++) {
        face = 1 + rand() % 6;
        switch (face) {
            case 1:
                ++frequency1;
                break;
            case 2:
                ++frequency2;
                break;
            case 3:
                ++frequency3;
                break;
            case 4:
                ++frequency4;
                break;
            case 5:
                ++frequency5;
                break;
            case 6:
                ++frequency6;
                break;
            default:
                cout << "Program should never get here!";
        } // fim do switch
    } // fim do for
    cout << "Face" << setw(13) << "Frequency" << endl;
    cout << "  1" << setw(13) << frequency1
        << "\n  2" << setw(13) << frequency2
        << "\n  3" << setw(13) << frequency3
        << "\n  4" << setw(13) << frequency4
        << "\n  5" << setw(13) << frequency5
        << "\n  6" << setw(13) << frequency6 << endl;
}  // fim de main

See running on ideone . And no Coding Ground . Also I put GitHub for future reference .

    
29.08.2017 / 16:54
5

The rand function generates numbers that are pseudo-random. That is, in order to have the sensation of something more random, it is necessary to modify the seed of the numbers. This is accomplished by the srand () function. At the beginning of the main function you can put something like:

#include <ctime>

int main()
{
    std::srand(std::time(0));
    (...)
}
    
29.08.2017 / 16:52
3

The sequence of random numbers generated, in fact, will always be the same for the same seed, this is a key feature of a PRNG .

In order to obtain different sequences it is necessary that the seed used be "random".

This random seed can be obtained from the computer's internal clock, making the seed different at every "moment."

Here are two (tested) examples based on the original program of your question.

In C++98 :

#include <iostream>
#include <cstdlib>
#include <ctime>

#define QTD_LADOS        (6)
#define QTD_LANCES_MAX   (6000000)

int main()
{
    int p[ QTD_LADOS ] = {};

    std::srand( std::time(NULL) );

    for( int i = 0; i < QTD_LANCES_MAX; i++ )
        p[ std::rand() % 6 ]++;

    for( int i = 0; i < QTD_LADOS; i++ )
        std::cout << i+1 << ". " << p[i] << " [" << ( ( p[i] * 100.0 ) / QTD_LANCES_MAX ) << "%]" << std::endl;

    return 0;
}

In C++11 :

#include <iostream>
#include <random>
#include <chrono>

#define QTD_LADOS        (6)
#define QTD_LANCES_MAX   (6000000)

int main()
{
    int p[ QTD_LADOS ] = {};

    unsigned int seed = std::chrono::system_clock::now().time_since_epoch().count();

    std::default_random_engine gen( seed );
    std::uniform_int_distribution<int> dist( 1, 6 );

    for( int i = 0; i < QTD_LANCES_MAX; i++ )
        p[ dist(gen) - 1 ]++;

    for( int i = 0; i < QTD_LADOS; i++ )
        std::cout << i+1 << ". " << p[i] << " [" << ( ( p[i] * 100.0 ) / QTD_LANCES_MAX ) << "%]" << std::endl;

    return 0;
}

Possible output:

$ ./rand
1. 999484 [16.6581%]
2. 998792 [16.6465%]
3. 1000396 [16.6733%]
4. 1001144 [16.6857%]
5. 1000860 [16.681%]
6. 999324 [16.6554%]
    
30.08.2017 / 21:27