Generating two ( or multiple) uniformly distributed random numbers c++ [duplicate] - c++

This question already has answers here:
Why does rand() return the same value using srand(time(null)) in this for loop?
(5 answers)
Closed 7 years ago.
I would like to generate several uniformly distributed random numbers in the same pass.
So far I have a "standard" function for generating a random number
double generateRandomNumber()
{
srand((unsigned)time(NULL));
double r=((double)rand()/(double)RAND_MAX);
return r;
}
how ever when in main I call it like that:
# include <iostream>
# include <string>
# include <cmath>
# include <ctime>
int main()
{
// generate random number
double rr1=generateRandomNumber();
double rr2=generateRandomNumber();
cout << rr1 << endl;
cout << rr2 << endl;
return 0;
}
I get that both numbers are the same ( I guess its the time limitations of seconds), anyways, this is something I would like to generelize to multiple random numbers.
Can anyone suggest a better way? maybe using a different method or library?

Do not call srand every time beore using rand.
srand should be call only once on the program begins.
You can use static variable to see if srand is previously called.
double generateRandomNumber()
{
static bool initialized = false;
if (!initialized)
{
srand((unsigned)time(NULL));
initialized = true;
}
double r=((double)rand()/(double)RAND_MAX);
return r;
}

Related

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
I would do
int getIntFromRange1(int from, int to){
std::uniform_int_distribution<int> dist(from, to);
return dist(mt);
}
I would do as in Jarod42's answer: distribution objects should be lightweight, so constructing a new distribution when you need a random number is simple and fast (it's the random engine that is expensive).
However you can also consider this implementation:
inline int get_int_from_range(int from, int to)
{
using distribution_type = std::uniform_int_distribution<int>;
using param_type = typename distribution_type::param_type;
thread_local distribution_type dist;
return dist(mt, param_type(from, to));
}
The rationale is that there could be distributions that need to store values/states.
This isn't probably the case for integers and uniform distribution, but it's interesting that in N4316 - std::rand replacement the proposed implementation uses this technique.

Issue with Random Number Generator in a Class [duplicate]

This question already has answers here:
srand() — why call it only once?
(7 answers)
Closed 9 years ago.
First off this could be complete rubbish as I am new to C++ classes and have never used a random number generator before. But this is my attempt. It generates a random number between the values that I want, thats fine. but when outputting them via an array, all the random values are the same.
RandomNumberGenerator.h
#pragma once
#include <iostream>
#include <cstdlib>
#include <ctime>
class RandomNumber
{
public:
void randomNumber();
int actualRandomNumber;
};
RandomNumberGenerator.cpp
#include "RandomNumberGenerator.h"
void RandomNumber::randomNumber()
{
srand (time(NULL));
actualRandomNumber = rand() % 66 + 1;
}
Game.h
#include "RandomNumberGenerator.h"
class Game
{
private:
int myNumbers[6];
public:
void createGame();
};
Game.cpp
#include "Game.h"
void Game::createGame()
{
RandomNumber create;
std::cout << "Welcome to your game!" << std::endl;
for (int i = 0; i < 6; i++)
{
create.randomNumber();
myNumbers[i] = create.actualRandomNumber;
}
for (int i = 0; i < 6; i++)
{
std::cout << myNumbers[i] << std::endl;
}
}
main
#include "Game.h"
#include "RandomNumberGenerator.h"
int main()
{
Game play;
play.createGame();
system("pause");
return 0;
}
Thanks in advance for anyones time.
Everytime you call srand(time(NULL)), you set the starting point of your sequence depending on a value that only changes once a second, thus your number only changes once a second (independend from number of calls).
So only calling srand() once will fix your code.
Notice, that both rand() and your actualRandomNumber = rand() % 66 + 1; are really bad regarding their "randomness" (why).
Use the C++ STL instead, consider the example on the bottom of the page (you want the uniform int distribution).
Edit: Typo and link to OneC++ Talk
The pseudo random number generator starts with a certain number and then generates a sequence based on the first number.
When the first number is the same the output sequence will be the same.
To generate different sequences each time you launch your program, the idea is to use the starting time of your program relatively to a specific date in miliseconds.
So the Error in your code is that you placed the srand(time(NULL)) in the function randomnumber() and it's being called in the loop. Because the CPU is so fast the time(NULL) (the first number in the sequence) will return the same value in miliseconds. Thus your having the same sequence.
To solve this place srand(time(NULL)) in main()

srand(time(NULL)) in C++ [duplicate]

This question already has answers here:
Problems when calling srand(time(NULL)) inside rollDice function
(3 answers)
Closed 9 years ago.
If I comment out the line with srand, the program will work, but there is no seed so the values will be the same each time. The assignment requires that I use rand, srand, and time to have the dice function be completely random.
#include <iostream>
#include <cstdlib>
#include <cmath>
#include <ctime>
using namespace std;
int rollDice();
// function declaration that simulates the rolling of dice
int main() {
int roll1 = rollDice();
int roll2 = rollDice();
// define, initialize, and combine dice roll total
int total;
total = 0;
total = roll1 + roll2;
* this is where a bunch of stuff is output to the screen from the dice rolls, using total as well as some other stuff that is being calculated, i left it out for simplicity*
}
// function to simulate a random dice roll
int rollDice() {
int r;
srand (time(NULL));
r = (rand() % 6) + 1;
return r;
}
Put srand in the main and call it once.
You have to use the seed once to get all the results from a random sequence.
Here you restart the sequence every time you roll the dice.
See the documentation for srand()

Generating a random double between a range of values

Im currently having trouble generating random numbers between -32.768 and 32.768. It keeps giving me the same values but with a small change in the decimal field. ex : 27.xxx.
Heres my code, any help would be appreciated.
#include <iostream>
#include <ctime>
#include <cstdlib>
using namespace std;
int main()
{
srand( time(NULL) );
double r = (68.556*rand()/RAND_MAX - 32.768);
cout << r << endl;
return 0;
}
I should mention if you're using a C++11 compiler, you can use something like this, which is actually easier to read and harder to mess up:
#include <random>
#include <iostream>
#include <ctime>
int main()
{
//Type of random number distribution
std::uniform_real_distribution<double> dist(-32.768, 32.768); //(min, max)
//Mersenne Twister: Good quality random number generator
std::mt19937 rng;
//Initialize with non-deterministic seeds
rng.seed(std::random_device{}());
// generate 10 random numbers.
for (int i=0; i<10; i++)
{
std::cout << dist(rng) << std::endl;
}
return 0;
}
As bames53 pointed out, the above code can be made even shorter if you make full use of c++11:
#include <random>
#include <iostream>
#include <ctime>
#include <algorithm>
#include <iterator>
int main()
{
std::mt19937 rng;
std::uniform_real_distribution<double> dist(-32.768, 32.768); //(min, max)
rng.seed(std::random_device{}()); //non-deterministic seed
std::generate_n(
std::ostream_iterator<double>(std::cout, "\n"),
10,
[&]{ return dist(rng);} );
return 0;
}
Also, If you are not using c++ 11 you can use the following function instead:
double randDouble(double precision, double lowerBound, double upperBound) {
double random;
random = static_cast<double>(((rand()%(static_cast<int>(std::pow(10,precision)*(upperBound - lowerBound) + 1))) + lowerBound*std::pow(10,precision)))/std::pow(10,precision);
return random;
}
So, I think this is a typical case of "using time(NULL) isn't a great way of seeding random numbers for runs that start close together". There isn't that many bits that change in time(NULL) from one call to the next, so random numbers are fairly similar. This is not a new phenomena - if you google "my random numbers aren't very random", you'll find LOTS of this.
There are a few different solutions - getting a microsecond or nanosecond time would be the simplest choice - in Linux gettimeofday will give you a microsecond time as part of the struct.
It seams to be plainly obvious but some of the examples say otherwise... but i thought when you divide 1 int with another you always get an int? and you need to type cast each int to double/float before you divide them.
ie: double r = (68.556* (double)rand()/(double)RAND_MAX - 32.768);
also if you call srand() every time you call rand() you reset the seed which results in similar values returned every time instead of ''random'' ones.
I've added a for loop to your program:
#include <iostream>
#include <ctime>
#include <cstdlib>
using namespace std;
int main () {
srand(time (NULL));
for (int i = 0; i < 10; ++i) {
double r = ((68.556 * rand () / RAND_MAX) - 32.768);
cout << r << endl;
}
return 0;
}
Example output:
31.6779
-28.2096
31.5672
18.9916
-1.57149
-0.993889
-32.4737
24.6982
25.936
26.4152
It seems Okay to me. I've added the code on Ideone for you.
Here are four runs:
Run 1:
-29.0863
-22.3973
34.1034
-1.41155
-2.60232
-30.5257
31.9254
-17.0673
31.7522
28.227
Run 2:
-14.2872
-0.185124
-27.3674
8.12921
22.4611
-0.414546
-21.4944
-11.0871
4.87673
5.4545
Run 3:
-23.9083
-6.04738
-6.54314
30.1767
-16.2224
-19.4619
3.37444
9.28014
25.9318
-22.8807
Run 4:
25.1364
16.3011
0.596151
5.3953
-25.2851
10.7301
18.4541
-18.8511
-0.828694
22.8335
Perhaps you're not waiting at least a second between runs?

What's wrong with my random number generator?

I'm just diving into some C++ and I decided to make a random number generator (how random the number is, it really doesn't matter). Most of the code is copied off then net but my newbie eyes cannot see anything wrong with this, is there any way this can be tweaked to give a number other than "6" each time?
#include <iostream>
#include <string>
#include <cstdlib>
using namespace std;
int random_number(int min, int max)
{
srand((unsigned)time(0));
int random_num;
int range=(max-min)+1;
random_num = min+int(range*rand()/(RAND_MAX + 1.0));
return random_num;
}
int main()
{
for(int i =0;i < 100;i++)
{
cout << random_number(3,10) << endl;
}
}
Add srand before the loop
srand((unsigned)time(0));
for(int i =0;i < 100;i++)
{
std::cout << random_number(3,10) << endl;
}
Don't call srand() within random_number(). This will re-seed the random number generator every call. For 100 calls, you'll very likely get the same seed every call, and therefore the same number.
The problem is that you use srand everytime. CPU is so fast that it will execute all this code in a single second, so you get the same seed each time.
Move srand out of the loop, call it only once.