Random numbers are always the same

Asked

Viewed 957 times

6

Why is this code always displaying the same random number results of 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

3 answers

5

The function rand 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 function srand(). At the beginning of the function main you can put something like:

#include <ctime>

int main()
{
    std::srand(std::time(0));
    (...)
}

5


You need to initialize the seed of random numbers. This is usually done by the computer clock, which meets simple situations. If you need a better distribution it is better to use the random generator of the C++ itself and not the 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

Behold working in the ideone. And in the repl it.. Also put on the Github for future reference.

3

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

To obtain different sequences it is necessary that the seed used is "random".

This random seed can be obtained from the computer’s internal clock, making the seed different 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 exit:

$ ./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%]

Browser other questions tagged

You are not signed in. Login or sign up in order to post.