nash.ouroboro
nash.ouroboro

Reputation: 83

Generate random numbers with uniform distribution (getting same number in loop)

I need to generate random numbers between two specified numbers in a loop with a uniform distribution. I am using the random library of C++11.

My problem is that I keep getting the same number in the loop. It is required that the number generated on every loop pass be different. Code below:

#include <cstdlib>
#include <stdio.h>
#include <iostream>
#include <random>
using namespace std;

double randnum (double a, double b)
{
  std::default_random_engine generator;
  std::uniform_real_distribution<double> distribution (a,b);
  double num=distribution(generator);

  return num;
}


int main()
{
    int np=100;

    double umin =0;
    double umax=0.5;
    double u[np];

    for (int i=0;i<np;i++)
    {
        u[i]=randnum(umin,umax);
        cout<<u[i]<<endl;
    }    
}

Please help. Any advice on generating random number by any alternative means is welcome, but it must have a uniform distribution.

Upvotes: 3

Views: 4613

Answers (2)

nash.ouroboro
nash.ouroboro

Reputation: 83

Wanted to add to the 1st answer: Using static function will generate different numbers in the loop but would generate the same set of random numbers on every run. I avoided this by using time as seed:

#include <iostream>
#include <random>
#include <chrono>
using namespace std;

double randnum (double a, double b)
{
  unsigned seed = std::chrono::system_clock::now().time_since_epoch().count();
  static std::default_random_engine generator (seed);
  //static std::default_random_engine generator;
  std::uniform_real_distribution<double> distribution (a,b);
  return distribution(generator);
}

int main()
{
    const int np=100;

    double umin =0;
    double umax=0.5;
    double u[np];

    for (int i=0;i<np;i++)
    {
        u[i]=randnum(umin,umax);
        cout<<u[i]<<endl;
    }    
}

Upvotes: 1

TemplateRex
TemplateRex

Reputation: 70516

The random number engines in the Standard Library are pseudo-random, i.e. deterministic in how their internal state is initialized and mutated. This means that each function call will get a fresh new generator that will continue to give the same number over and over again.

Just make the generator a static function variable so that its state can evolve over different function calls.

#include <iostream>
#include <random>
using namespace std;

double randnum (double a, double b)
{
  static std::default_random_engine generator;
  std::uniform_real_distribution<double> distribution (a,b);
  return distribution(generator);
}

int main()
{
    const int np=100;

    double umin =0;
    double umax=0.5;
    double u[np];

    for (int i=0;i<np;i++)
    {
        u[i]=randnum(umin,umax);
        cout<<u[i]<<endl;
    }    
}

Live Example.

Note, you will get the same sequence of numbers for each run of your compiled program. To get more random behavior across program invocations, you can use e.g. std::random_device.

Upvotes: 6

Related Questions