0

I am trying to generate a random number between 0 and 2 (inclusive) for a C++ program:

#include <iostream>
#include <string>
#include <cstdlib>
#include <random>

using namespace std;

    int generateRowMovement(){
        //http://www.cplusplus.com/reference/random/uniform_int_distribution/
        default_random_engine generator;
        uniform_int_distribution<int> distribution(0,2);
        int row = distribution(generator);
        return row;
    }

int main(){
    int row = generateRowMovement();
    cout << row << endl;

    int row2 = generateRowMovement();
    cout << row2 << endl;

    int row3 = generateRowMovement();
    cout << row3 << endl;

    return 0;
}

All 3 results are:

0
0
0

I have been testing this for 30 minute and it is always zero. I have tried following this link and this SO post (which posts link back to), but none of their solution is fix this problem. How can I generate 0, 1, and 2?

artemis
  • 6,857
  • 11
  • 46
  • 99
  • 4
    You initialize default_random_engine each time to the same state/seed. So results are the same (0 in your case). Initiazie it once and use it consequently – Severin Pappadeux Sep 15 '19 at 01:39
  • 2
    Did you try creating the generator and the distribution once, and then calling distribution(generator) many times? Right now you create the generator and distribution from scratch for every random variate that you create. – Wilf Rosenbaum Sep 15 '19 at 01:40
  • I actually have these functions as part of a class. I moved this into function, because outside of the function it results in a ton of errors – artemis Sep 15 '19 at 01:43
  • 4
    How to use `` is pretty clear. I don't see that you've followed any kind of guideline. "default_random_engine generator;" makes one instance for each call. I think you'll find plenty of other versions here at SO. – Ted Lyngmo Sep 15 '19 at 01:48
  • OK that is good to know thank you – artemis Sep 15 '19 at 01:49
  • 1
    Same problem as https://stackoverflow.com/questions/15461140/stddefault-random-engine-generate-values-between-0-0-and-1-0 – GregS. Sep 15 '19 at 01:52
  • What's wrong with invoking `rand() % 3` ? – selbie Sep 15 '19 at 01:56
  • 2
    @JerryM. It's not only _good_ to know. You _must_ know it. – Ted Lyngmo Sep 15 '19 at 01:56
  • @selbie :-) bias? – Ted Lyngmo Sep 15 '19 at 01:57
  • @TedLyngmo - more likely denial. :) – selbie Sep 15 '19 at 02:09
  • You need to be aware that if you create a new generator with the same seed and distribution, you will always get the same sequence. In typical application, you will create a single instance of the generator once and provide a new seed for each run of the application. – Phil1970 Sep 15 '19 at 02:10
  • @Phil1970 I sort of agree. It'll be one `thread_local` instance of a good PRNG in my book. – Ted Lyngmo Sep 15 '19 at 02:12
  • 1
    @selbie rand() is not uniform.. it generates a pseudo-random sequence of values in range from 0 to 2^15, often by using overflow. And you operation would have a slight bias even if distribution was truly uniform. – Swift - Friday Pie Sep 15 '19 at 02:22
  • "_The generation of random numbers is too important to be left to chance. —Robert R._" – Ted Lyngmo Sep 15 '19 at 02:25
  • Possible duplicate of [std::default\_random\_engine generate values between 0.0 and 1.0](https://stackoverflow.com/q/15461140/608639), [seeding default_random_engine?](https://stackoverflow.com/q/22105867/608639) and [Generate random numbers using C++11 random library](https://stackoverflow.com/q/19665818/608639) – jww Sep 15 '19 at 03:32

1 Answers1

2

There are two issues with the code you posted that keeps it from working how you intend it to. The first is that generator is never given a seed, or as is commonly shown online, a random_device, ie

random_device rd;
default_random_engine generator(rd());

The second is that every time you call the function, you're creating a new random engine, and a new distribution. It would be better to create a random device, give it to to the engine only once, and then let your function return the values based on those.

#include <iostream>
#include <string>
#include <cstdlib>
#include <random>

using namespace std;

random_device rd;
default_random_engine generator(rd());
uniform_int_distribution<int> distribution(0,2);

int generateRowMovement(){
    return distribution(generator);
}

int main(){
    int row = generateRowMovement();
    cout << row << endl;

    int row2 = generateRowMovement();
    cout << row2 << endl;

    int row3 = generateRowMovement();
    cout << row3 << endl;

    return 0;
}
KBentley57
  • 146
  • 6