I have created a simulation environment which has several stochastic parts involved. I draw numbers from normal, uniform and lognormal distributions. In most of the cases this runs fine, however, when I decide to do 100 simulations after each other I am getting the error:
R6010 Abort() has been called.
In my console I get the error: invalid argument for mersenne_twister::seed. However, I am only using the standard pseudo-random number generator rand(). At no point I call mersene_twister. So this probably is a method from the std::normal_distribution.
Furthermore I don't seed why my seed value is invalid after X iterations and not for the first X iterations?
Does anyone have any experience with this error? Does anyone have any suggestions how to solve this
P.s. srand(time(0)) is called only once, in the beginning of the main. While all random numbers are generated in a second class "random_num".
P.s.s I am aware that this might not be the best way to generate random numbers, however it is sufficient for my purpose.
The code as requested for the RNG:
double random_num::uniform(int lb, int ub)//Generate uniformly distributed random numbers with lowerbound lb and upperbound ub
{
//srand(time(0));
double number;
number =((double) rand() / (RAND_MAX+1)) * (ub-lb+1) + lb;
return number;
}
double random_num::normal(double mean, double var) //Generate normally distributed random numbers with mean and variance
{
//srand(time(0));
default_random_engine generator (rand());
normal_distribution<double> distribution(mean, var);
return distribution(generator);
}
double random_num::lognormal(double mean, double var, double offset)
{
//srand(time(0));
random_num dummy;
double random;
random = exp(dummy.normal(mean,var))-offset; //Calculate the 3 parameter lognormal
return random;
}
#lip The problem was indeed that rand() returned a zero at some moment. And therefore default_random_engine generator(0); aborted.
The solution was quite simple:
Create a function that checks that rand() it is not a zero:
int rand0()
{
int dummy = rand();
while(dummy==0)
{
dummy = rand();
}
return dummy;
}
And then: default_random_engine generator(rand0());
Related
I was using rand() to produce some random numbers inside a function to populate some arrays but when I ran the program I noticed it was giving always the same row of generated numbers. The arrays were filled with the same row of generated numbers, it could be all 0 or a row with different numbers, but this pattern of numbers were the same in every array.
So I used debug to run the program step by step and it worked, rand() were generating different numbers to every array..
After this I decided to try another method to generate random numbers. I found a way to do this using Boost library.
This is the code I'm using now:
int main(){
typedef boost::mt19937 RNGType;
RNGType rng( (unsigned int)time(NULL));
boost::uniform_int<> one_to_six( 1, 6);
boost::variate_generator< RNGType, boost::uniform_int<> >
dice(rng, one_to_six);
for(int i=0;i<10;i++){
std::cout<<dice()<<std::endl;
}
}
If I use this code on main() function, everything goes well and it gives me 10 random numbers.
But if I put this code in a function to call it whenever I want it returns me the same number. Always 55555555, or 0000000..
Fun fact is, if I use debug and make a breakpoint at that function and run it step by step, it works again giving me always different numbers.
So I don't know what I'm missing here..
edit: When I used rand() I was using srand((unsigned int)time(NULL));
update 1:
int random(int begin,int end){
typedef boost::mt19937 RNGType;
RNGType rng( (unsigned int)time(NULL));
boost::uniform_int<> one_to_six( begin , end );
boost::variate_generator< RNGType, boost::uniform_int<> >
dice(rng, one_to_six);
return dice();
}
int main() {
for(int i=0; i<10; i++)
cout<<random(0,6)<<endl;
}
If I use this method it will give me the same sequence. If I run it step by step with debug it will work and give me different numbers.
You seed the rng in every function call, therefore you always get a random sequence (of length 1) starting from a seed. Since you use time(NULL) as the seed, all calls within a second will get the same seed and therefore the same sequence.
Since you don't want to have the same sequence repeatedly, you should not seed the rng between calls to random but instead continue the sequence from previous call, just like you do in the version that is entirely inside main. That requires you to maintain the state of the generator object between the calls instead of constructing a new one every time.
Found another way, and it's working now.
I'll let the code here if someone needs
boost::random::mt19937 gen;
int random(int begin, int end)
{
boost::random::uniform_int_distribution<> dist(begin, end);
return dist(gen);
}
int main(){
for(int i=0;i<10;i++)
std::cout << random(0,20) << std::endl;
}
I am building a simulation in C++ and I have an exponential generator to make the burst times of the processes.
Usually it returns values as such: 3.14707,1.04998. But frequently 1/10 occasions such numbers turn out: 2.64823e-307
This is the code of the generator (I am using srand ( time(NULL) ); at the beginning of the program):
double exponential(float u)
{
double x,mean;
mean = 10;
// generate a U(0,1) random variate
x = rand();
u = x / RAND_MAX;
return (-mean * log(u));
}
And this is how I assign the values. The while part inside is my effort to get rid of such values but it didn't work:
for (int i = 0; i < nPages; i++)
{
index[i] = i;
arrival[i]= poisson(r);
burst[i]=exponential(u);
while (burst[i]<1 || burst[i]>150)
{
cout<<"P"<<i<<endl;
burst[i]=(burst[i-1]+burst[i+1])/2;
}
}
Why do you use the C library instead of the C++ library ??
std::random_device rd;
std::default_random_engine gen(rd());
std::exponential_distribution<double> dist(lambda);
double x = dist(gen);
If the size of burst is nPages, then
for (int i = 0; i < nPages; i++)
{
//...
burst[i]=(burst[i-1]+burst[i+1])/2;
}
will step outside its bounds, so you are likely to end up with nonsense.
You need to think about what is required at the edges.
As far as the comments about rand go rand considered harmful is worth a watch. In your case taking log of 0 is not sensible.
Using your exponential function copied verbatim, I cannot reproduce the error you describe. Issues with the PRNG cranking out either 0 or RAND_MAX should only show up one time out of RAND_MAX apiece, not 10% of the time. I suspect either a buggy compiler, or that what you have shared is not the actual code that produces the described problem.
Im trying to shuffle a deck of cards but random_shuffle produces the same result every time
void
Deck::shuffle() {
cout << "SHUFFLING CARDS!!!\n\n";
srand(time(0));
random_shuffle(cards.begin(), cards.end());
displayCards();
}
That's because you seed pseudo-random number generator to the same value each time:
srand(time(0));
The granularity of time are seconds, if I'm not mistaken. If you pause the execution for some time between calls to Deck::shuffle() you should see different results.
Remove that line from the function and call it once at the start of your program.
I think that the problem is because you are putting srand(...) inside of your function.
Try to move it outside (so that it will be executed only once)
You are reseeding the random number generator each time you call shuffle.
You should only seed the random number generator once per application (typically in your application initialization):
int main()
{
// other initialization
srand(time(NULL)); // seed the number generator
// ...
}
It is important to know that to be able to receive a "random" number you have to seed the generator. Also it should be seeded outside the function.
srand(time(NULL));
The use of the time function will help ensure that you will receive a random number.
time.h does need to be included for it to work. For more reference on srand, click here.
I'm not familiar with random_shuffle, but here's a function that does a perfect shuffle - in other words, each 52! permutations of the deck has to be equally likely.
This is from Gayle Laakmann's Cracking the Coding Interview (Question 20.2)
void Deck::shuffle() {
int temp, index;
for (int i = 0; i < cards.size(); i++){
index = (int) (rand() %(cards.size() - i)) + i;
temp = cards[i];
cards[i] = cards[index];
cards[index] = temp;
}
}
The function below runs, but always returns the same numbers each time I run the program. Is there a way to generate random numbers that are different each time I run the program?
int getrand(int min,int max){
int rnum = rand()%(max-min)+min;
return rnum;
}
You might like to use the high-quality standard library random number generation facilities:
#include <random>
typedef std::mt19937 rng_type;
std::uniform_int_distribution<rng_type::result_type> udist(min, max);
rng_type rng;
int main()
{
// seed rng first:
rng_type::result_type const seedval = 4; // or implement a good get_seed()?
rng.seed(seedval);
rng_type::result_type random_number = udist(rng);
return random_number;
}
try with this:
/* initialize random seed: */
srand ( time(NULL) );
somewhere when your program start ( absolutely not in your getrand() function ). This will force the generator to start each time with a different seed.
Seems like you forgot to call srand.
Pseudo random number generators need to be "seeded" before you use them; the default seed is the same every time, so you get the same sequence.
Typically you use something like srand(time(NULL)), but this fails if you run the program again within a second.
It's also good to use up a random number or two after seeding, since the first few values are highly correlated with the seed itself.
a simple solution to randomize once would be:
int getrand(int min, int max) {
static bool init = false;
if (!init) {
srand(time(NULL));
init = true;
}
return rand()%(max-min)+min;
}
You need to initiate the seed. Check out srand. Also, try boost if you want:
boost::lagged_fibonacci607 base_prng(seed);
boost::variate_generator<boost::lagged_fibonacci607&,boost::uniform_smallint<> > prng(base_prng,boost::uniform_smallint<>(min,max))
I'm in need of a C++ (pseudo, i don't care) random number generator that can get me different numbers every time I call the function. This could be simply the way I seed it, maybe there's a better method, but every random generator I've got doesn't generate a new number every time it's called. I've got a need to get several random numbers per second on occasion, and any RNG i plug in tends to get the same number several times in a row.
Of course, I know why, because it's seeded by the second, so it only generates a new number every second, but I need to, somehow, get a new number on every call. Can anyone point me in the right direction?
Sounds like you do it like this:
int get_rand() {
srand(time(0));
return rand();
}
Which would explain why you get the same number within one second. But you have to do it like this:
int get_rand() {
return rand();
}
And call srand once at program startup.
You only need to seed the generator once with srand() when you start, after that just call the rand() function. If you seed the generator twice with the same seed, you'll get the same value back each time.
You should only seed the PRNG once.
Boost.Random has a variety of pretty good random number generators.
If you're generating a large number of random numbers, you could try an XORShift generator. For longs (8 bit):
// initial setup
unsigned long x = ... init from time etc ...
// each time we want a random number in 'x':
x ^= x << 21;
x ^= x >> 35;
x ^= x << 4;
This code generates a unique random number only once.
#include <ctime>
# include <iostream>
using namespace std;
int main()
{
int size=100;
int random_once[100];
srand(time(0));
for (int i=0;i<size;i++) // generate unique random number only once
{
random_once[i]=rand() % size;
for(int j=0;j<i;j++) if (random_once[j]==random_once[i]) i--;
}
for ( i=0;i<size;i++) cout<<" "<<random_once[i]<<"\t";
return 0;