vendredi 25 décembre 2015

Why does my use of pcg64_once_insecure() not produce unique random numbers?

I'm attempting to use the PCG random number generator functions that are described as producing "each number exactly once during their period", such as pcg64_once_insecure. However, in my hands they produce some duplicate numbers. My question is, why? Am I using the functions incorrectly, or do I misunderstand their documentation and their purpose?

Here is a simple test program using one of the functions; you can substitute others from the *_once_insecure list instead of pcg64_oneseq_once_insecure used here. Also, you get repeats even when the upper bound is removed (i.e., calling rng() without arguments), although I don't show that code here (but I did try it):

#include <random>       // for random_device
#include "pcg_random.hpp"

using namespace std;

int main(int argc, char** argv)
{
    // Default values.
    int upper_bound = -1;
    int how_many    = 5000000;

    // Read command line arguments.
    int c;
    while ((c = getopt(argc, argv, "n:u:")) != -1) {
        switch (c) {
        case 'n':
            how_many = atoi(optarg);
            break;
        case 'u':
            upper_bound = atoi(optarg);
            break;
        }
    }

    // Set things up.
    pcg64_oneseq_once_insecure rng(42u);
    rng.seed(pcg_extras::seed_seq_from<std::random_device>());

    // Generates a uniformly distributed 32-bit unsigned integer less than
    // bound, such that 0 <= x < bound.
    if (upper_bound > 0)
        for (int count = 0; count < how_many; ++count)
            printf("%d\n", rng(upper_bound));
    else
        for (int count = 0; count < how_many; ++count)
            printf("%d\n", rng());

    return 0;
}

I compile it with this simple Makefile on a Mac OS X 10.10 system:

CPPFLAGS += -I/usr/local/include -Wno-format
CXXFLAGS += -std=c++11
CC        = $(CXX)

all: generate-random-numbers

generate-random-numbers: generate-random-numbers.o

And here is a simple test command line that detects duplicates:

./generate-random-numbers -n 100000 | sort | uniq -c | egrep '^   2'

When I run this repeatedly, I get dozens of duplicate numbers.

Can anyone explain to me what I am doing wrong?

EDIT 2015-12-25 21:49 PST: I updated the code to provide the ability to call rng() with and without arguments. Whether called with an upper bound or not, it still generates repeats.




Aucun commentaire:

Enregistrer un commentaire