Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++11 Generating random numbers from frequently changing range

Q: How do I generate (many) uniformly distributed integers from a-priory unknown ranges? What is the prefered way in terms of performance (milions of generated numbers)?

Context: In my app I have to generate many pseudo random numbers in many places. I use singleton pattern for the generator to maintain reproducibility of the app's run. Distribution is always uniform in my case, but the problem is that there are far too many possible ranges to pre-made the distribution object in C++11 style.

What I tried: There are two obvious solutions to this, first is to have one-time distribution objects and second is to use modulo to transform random number from widest possible range to the desired one. But somehow i doubt these are best possible :)

#include <random>
#include <iostream>
#include "limits.h"
using namespace std;

mt19937 mt;
uniform_int_distribution<int> * fixedDist;
uniform_int_distribution<int> * variableDist;

// this version creates and delete dist after just one use
int getIntFromRange1(int from, int to){
    variableDist = new uniform_int_distribution<int>(from,to);
    int num = (*variableDist)(mt);
    delete variableDist;
    return num;
}

// this version contains modulo
int getIntFromRange2(int from, int to){
    int num = (*fixedDist)(mt);
    int diff = to - from;
    num = num % diff;
    return num + from;
}

int main(){ 
   mt.seed(123456);
   fixedDist= new uniform_int_distribution<int>(0,INT_MAX)

   int a = getIntFromRange1(1,10); // 1 and 10 are just for illustration
   int b = getIntFromRange2(1,10); // can change freely

   cout << "a: " << a << endl; // a: 6
   cout << "b: " << b << endl; // b: 9

   getchar();
}

Duplicate question

Vary range of uniform_int_distribution

like image 286
teejay Avatar asked Aug 09 '14 19:08

teejay


Video Answer


1 Answers

I would do

int getIntFromRange1(int from, int to){
    std::uniform_int_distribution<int> dist(from, to);
    return dist(mt);
}
like image 96
Jarod42 Avatar answered Sep 19 '22 07:09

Jarod42