7

The code below show how to random double in C++11. In this solution each time, when I run this program the result are the same - I don't know why? How to change it to get different solution in every time when I run the program?

#include <random>
int main(int argc, char **argv)
{
  double lower_bound = 0.;
  double upper_bound = 1.;
  std::uniform_real_distribution<double> unif(lower_bound, upper_bound);
  std::default_random_engine re;      
  double a_random_double = unif(re);
  cout << a_random_double << endl;
  return 0;
}
//compilation: "g++ -std=c++0x program_name.cpp -o program_name"
user1519221
  • 631
  • 5
  • 13
  • 24
  • 1
    Give it a seed value. Btw, being able to generate the same sequence of 'random' values is great for testing. – John G Jan 13 '14 at 21:57
  • There's no good reason to use `default_random_engine`. It's basically the "I don't care" engine, but then why use it over, say, `mt19937` which is high quality *and* shorter to type. – Cory Nelson Jan 13 '14 at 22:09
  • 2
    @CoryNelson `default_random_engine` is the obvious choice for someone who knows nothing about random engines. That's why it exists. A novice who first looks at `` and its dozens of options for engines and distributions is unlikely to do the level of research required to make intelligent choices, they just want something that works. We should just be happy they aren't using `rand()`. – Casey Jan 13 '14 at 23:06

4 Answers4

7

You need to seed the random number generator before you generate samples. You do this when you construct the default_random_engine instance. For example:

std::random_device rd;
std::default_random_engine re(rd()); 

If you wish to be more prescriptive about the generator you use then you should specify one rather than relying on the library implementor's choice for default_random_engine. The available choices are listed here: http://en.cppreference.com/w/cpp/numeric/random#Predefined_random_number_generators

Also beware that some implementations do not use a non-deterministic source for random_device. If you are faced with such an implementation, you'll need to find an alternative source for your seed.

David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490
  • `std::random_device{}()` is a good general choice for a seed value: `std::default_random_engine re{std::random_device{}()};` – Casey Jan 13 '14 at 21:55
  • Watch out for an unexpected default seed with MinGW: http://stackoverflow.com/q/18880654/417197 – André Jan 14 '14 at 12:38
3

You have to initialize the random engine with some initial seed value.
An option is to use std::random_device.

#include <iostream>
#include <random>

int main() {
    const double lower_bound = 0;
    const double upper_bound = 1;
    std::uniform_real_distribution<double> unif(lower_bound, upper_bound);
    
    std::random_device rand_dev;          // Use random_device to get a random seed.

    std::mt19937 rand_engine(rand_dev()); // mt19937 is a good pseudo-random number 
                                          // generator.

    double x = unif(rand_engine);
    std::cout << x << std::endl;
}

You may want to watch a great presentation freely available online: "rand() Considered Harmful" (from GoingNative 2013 C++ event).

Community
  • 1
  • 1
Mr.C64
  • 41,637
  • 14
  • 86
  • 162
0

The engine was not initialized with a seed.

#include <chrono>
...
std::default_random_engine re(std::chrono::system_clock::now().time_since_epoch().count());
Dani J
  • 174
  • 6
0

As others have noted, you haven't given the generator an explicit seed.

Let's look at what's happening. GCC implements std::default_random_engine as a std::linear_congruential_engine<uint_fast32_t, 16807UL, 0UL, 2147483647UL>. When you write std::default_random_engine re;, you call the constructor for this class with no arguments, which defaults to a seed value of linear_congruential_engine::default_seed = 1u. So if you want a seed other than 1, you have to provide it yourself.

Reference: http://gcc.gnu.org/onlinedocs/gcc-4.8.2/libstdc++/api/a00860.html

Chris Culter
  • 4,470
  • 2
  • 15
  • 30