Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Generating pseudo-random integers from a changing interval efficiently

I wrote the following class for generating random integers from a given interval [lower, upper].

 class RandomInteger {

protected:

    std::random_device randomDevice;
    std::default_random_engine randomEngine;
    std::uniform_int_distribution<> distribution;

public:

    RandomInteger(int64_t lower, int64_t upper);

    virtual ~RandomInteger();

    virtual int64_t generate();
};


RandomInteger::RandomInteger(int64_t lower, int64_t upper) : randomEngine(this->randomDevice()), distribution(lower, upper) {
}

RandomInteger::~RandomInteger() {
    // TODO Auto-generated destructor stub
}

int64_t RandomInteger::generate() {
    int64_t i = this->distribution(this->randomEngine);
    return i;
}

This is okay if the interval remains the same and multiple calls to generate are made. However, now my use case is generating integers from an interval which is always changing (the upper bound increases every time).

First and foremost, this needs to be fast. This has nothing to do with cryptography so very pseudo-random numbers are okay (and std::random_device is probably not needed). I would also like to avoid C style if possible and use modern C++11 style.

Can you suggest ways to do this efficiently?

like image 281
clstaudt Avatar asked Nov 03 '22 00:11

clstaudt


1 Answers

Use the overload of uniform_int_distribution::operator() that accepts a const param_type &:

int64_t RandomInteger::generate(int64_t lower, int64_t upper) {
    int64_t i = this->distribution(this->randomEngine,
      std::uniform_int_distribution<int64_t>{lower, upper}.param());
    return i;
}

(Note that you should value-initialize distribution, as you are not interested in setting its param. Also, distribution should be templated with int64_t, not int.)

If uniform_int_distribution preserves any state, then this will use it efficiently.

In actual fact, most implementations of uniform_int_distribution do not preserve any state; see e.g. libstdc++ random.tcc: http://gcc.gnu.org/onlinedocs/gcc-4.6.0/libstdc++/api/a01001_source.html#l00832

like image 183
ecatmur Avatar answered Nov 11 '22 03:11

ecatmur