C++ generation of random numbers [duplicate] - c++

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
how to generate different random number in a loop in C++?
This is my code:
for(i=0;i<10;i++)
{
srand ( time(NULL) );
cout<<time(NULL);
max=100,min=0;
for(j=0;j<3;j++)
{
cout<<(( (rand() % (max - min + 1)) + min)%5);
}
}
Now i get the output:
1357207288 0 1 4
1357207289 0 1 4
1357207290 0 1 4
and so on. I want to get different random numbers each time. How can I achieve this.

The reason you get the same repeatedly is because you initialize it with the same seed each time. That is, since you are performing so few operations, not a single second has passed since the first iteration of the loop to the last one. Hence, time(nullptr) will return the same for each iteration.
To solve this, move srand ( time(NULL) ); outside of the loop, which will mean setting the random seed only once.
srand ( time(NULL) );
for(int i=0;i<10;i++)
{
cout<<time(NULL);
int max=100;
for(int j=0;j<3;j++)
{
cout<<(( (rand() % (max - min + 1)) + min)%5);
}
}

You must move srand() outside of your loop, otherwise you receive the same numbers.
srand ( time(NULL) );
for(i=0;i<10;i++)
{
cout<<time(NULL);
max=100,
for(j=0;j<3;j++)
{
cout<<(( (rand() % (max - min + 1)) + min)%5);
}
}
If you don't you will use the same seed since the time will not change in the nanoseconds your program takes to execute.

srand(time(NULL));
printf("%d", rand() % 10+1);
for(i=1; i<rand()% max_length; i++) {
printf("%ld", rand() % 10);
}
This will generate random numbers (also random length of them).

You get the same results even with srand() out of the loop because in C the generation algorithm used by rand is guaranteed to only be advanced by calls to this function. In C++, this constraint is relaxed, and a library implementation is allowed to advance the generator on other circumstances (such as calls to elements of <random>). Put a sleep inside the loop and see what happens.
Obviously in plain C this doesn't happen.
However, boost libraries offers you some good PRNG functionality. Use it instead of the broken srand(time(NULL));

Related

Broken random number generator? [duplicate]

This question already has answers here:
Random numbers in C
(10 answers)
How can I generate different random numbers for each player?
(3 answers)
Closed 4 years ago.
So I was creating a program that would call a function and return 0 or 1 (0 meaning tails and 1 meaning heads) and then use that to print the outcome of 100 flips.
It seemed simple enough thinking I could use srand(time(NULL)) to seed rand() with constantly varying seeds. Here was my first crack.
#include <stdio.h>
#include <stdlib.h>
int flip();
int main(void) {
int heads = 0;
int tails = 0;
for (short int count = 1; count <= 100; ++count) {
int number = flip();
if (number == 0) {
printf("%s", "Tails");
++tails;
}
else if (number == 1) {
printf_s("%s", "Heads");
++heads;
}
}//end for
printf_s("\n%d Tails\n", tails);
printf_s("%d Heads", heads);
}//end main
int flip(void) {
srand(time(NULL));
int number = (int)rand();
printf("%d", number%2);
return number%2;
}//end flip
I would run the program and my rand() value would always be a five digit integer repeated in each iteration of the for statement (i.e 15367, 15745, or 15943).
I messed around until I discovered changing srand(time(NULL)) to srand(time(NULL)*time(NULL)/rand()) did the trick.
My only thought is that the time between each for iteration is so small the the time(NULL) part of the srand() function doesn't change enough to feed a different seed value.
I also tried srand(time(NULL)/rand()), however, this produced the same result (52 heads 48 tails) every time I ran the program (20+times); however, the rand() values were all different from each other.
I do not know why these things happened, or why the final srand(time(NULL)*time(NULL)/rand()) function worked, and I would love it if someone could explain!
The reason is, that time(NULL) changes only once per second!
This means, that you seed the random number generator 100 times with the same seed.
A better way is to seed the RNG only once at start of the process (at the head of main(), then you should get different values.
If you start your program more often than once a second, you could also seed it with
srand(time(NULL)+getpid());
or similar.

generate random number in a range c++ [duplicate]

This question already has answers here:
How does modulus and rand() work?
(4 answers)
Closed 8 years ago.
I'm using the ncurses library to build a game. I'm having trouble generating the correct random numbers. The while loop below needs to keep generating random numbers until they are between 1 and 45(this is my y-axis limits on the standard screen). I can't figure out what I'm doing wrong because the while loop condition looks fine to me. The problem is that while loop starts running infinitely. Im not doing anything but printing the generated numbers at the end as i just want to see that the correct numbers are generated. can anyone please help me with this problem? The following is my int main.
int main()
{
int r,c,x=0;
initscr();
raw();
keypad(stdscr, TRUE);
noecho();
//mvprintw(22,45,"<");
getmaxyx(stdscr,r,c);
int n,n2 = 0;
while((n<1)||(n>45)){
srand (time(NULL));
n = rand();
srand (time(NULL));
n2 = rand();
}
mvprintw(4,10,"First Random Number: %d\n", n);
mvprintw(5,10,"Second Random number: %d\n", n2);
getch();
endwin();
return 0;
}
This is how you can do it in C++:
#include <iostream>
#include <random>
int main()
{
std::random_device rd;
std::mt19937 gen( rd());
std::uniform_int_distribution<> dis( 1, 45);
for (int n=0; n<1000; ++n)
std::cout << dis(gen) << ' ';
std::cout << '\n';
}
Using rand() % x is a flawed design because of the bias introduced be dividing a range not evenly. You can read this to learn more about the bias introduced by rand() % x.
You want to call srand once at the start of things and then use modulus to bring rand results into your range, something like:
srand(time(NULL));
n = rand() % 45 + 1;
n2 = rand() % 45 + 1;
Just like #unholySheep commented, rand() returns a value between 0 and RAND_MAX, which it a huge value. Therefore, it is very unlikely you will get quickly a value between 1 and RAND_MAX.
Therefore, the solution is to do the reminder of the division by the number you want:
n = 1 + rand() % 45;
You do not even need a while.
You can get a random number between 1 and 45 inclusive with:
n = rand() % 45 + 1;
It won't be perfect in terms of distribution but it'll be close enough for anyone who's neither a statistician nor a cryptographer, in which case you probably would be using real random numbers.
You should also call srand() once, at the start of your program somewhere, rather than multiple times, especially if you're using the current time to seed it.
Doing it multiple times within the same second will give you a decidedly non-random sequence such as:
42, 42, 42, 42, 42, 42, 42, ...

Identical Random Numbers Generated in C++

I've been banging my head against this for half an hour now, and have NO idea what's wrong.
I'm trying to generate a list of 10 random numbers, 1-100. But when I run it they all come out the same number. It is very frustrating! I thought that it was because the number was still stored in the RAM, but after re-randomizing the random number and the variable three times, it still comes out with the same number. What am I doing wrong?
Code:
main() {
int i;
int randnum;
srand(time(NULL));
randnum = rand() % 2;
for (i = 0; i < 10; i++) {
srand(time(NULL));
randnum = rand() % 100 + 1;
srand(time(NULL));
rand();
list[i] = randnum;
srand(time(NULL));
randnum = rand() % 100 + 1;
srand(time(NULL));
rand();
}
srand(time(NULL));
randnum = rand() % 100 + 1;
}
Don't call srand() more than once. This code likely takes less than a second to execute, so every time you call srand(time(NULL)) when time is measured in seconds on your implementation, you just reset the pseudo random number generator to the same seed, so all your numbers come out the same.
Don't reinitialize the generator with srand(time(NULL)). Use it only once, at the beginning of your code.
What you're doing wrong is that you're resetting the random number generator's state.
The reason its not obvious is because you're using time. time returns time_t, which, according to the standard is "the implementation’s best approximation to the current calendar time". This generally represents the number of seconds since 00:00 hours, Jan 1, 1970 UTC. Now, your code will likely execute within a millisecond, so all your time calls return the same value.
So your code is equivalent to:
int const somenum = time(NULL);
srand(somenum); //reset state using some seed.
//rand() will always produce the same value after an
// srand call of the same seed.
randnum = rand() % 100 + 1;
srand(somenum); //reset state using some seed.
randnum = rand() % 100 + 1;
srand(somenum); //reset state using some seed.
randnum = rand() % 100 + 1;
srand(somenum); //reset state using some seed.
randnum = rand() % 100 + 1;
To test this, wait for a keypress between each call to rand and you will see they are different.
The way to fix this is to only call srand(time(NULL)) once, at the start.
Now, in C++11, there is another way:
#include <iostream>
#include <random>
int main()
{
const int rand_max = 20;
std::default_random_engine rng(std::random_device{}());
std::uniform_int_distribution<> dist(0, rand_max);
std::cout<<"This will always be as random a number as your hardware can give you: "<<dist(rng)<<std::endl;
return 0;
}
std::random_device makes use of a built in hardware random number generator if available, so you don't have to worry about seeding with time. If you really do want a pseudo random number, then just use a different random number generator.
You can also control the random number distribution in C++11.

Random numbered array gives the same number [duplicate]

This question already has answers here:
Same random numbers every loop iteration
(4 answers)
Closed 9 years ago.
I'm attempting to generate two arrays of random numbers. One array for height and the other for width of a text-art fish tank. But the arrays always have the same repeated number.
ex: [ 2, 2, 2, 2 ] or [ 9, 9, 9]
I must be setting up the loop incorrectly, but I need help to see what's wrong.
//Generate random numbers for fish positions in vector
if ( fish_collection.size() != 0 )
{
int randHeight[fish_collection.size()];
int randWidth[fish_collection.size()];
for ( int i = 0; i < fish_collection.size(); i++ )
{
srand (time(NULL));
randHeight[i] = rand() % 10 + 1;
randWidth[i] = rand() % (tank_size - 5) + 1;
}
//random number printed test
for ( int i = 0; i < fish_collection.size(); i++ )
{
cout << randWidth[i] << ',';
}
cout << endl;
//Enter the fish in random position
for ( int j = 0; j < fish_collection.size(); j++ )
{
tank_frame[randHeight[j]].replace ( randWidth[j], fish_collection[j].size(), fish_collection[j] );
}
}
You have to call srand(time(NULL)) only once in the program (usually at the beginning of main).
Calling it more than once I believe resets the entire sequence which explains why you're always getting the same number (the first one) every time. (And the reason you're always getting the same first one, is that most likely the calls are so close together, the time is the same).
'time(NULL)' returns the number of seconds since 00:00 1st January 1970, which explains why 'srand(time(NULL))' always seeds to the same value: It executes in less than one second, so time(NULL) returns the same value. (See this link)
You call srand() every time when you call rand() function. This is incorrect: srand() should be used only once in the beginning of your program, because the value you pass to it sets the whole sequence of further rand() values. In this example you always call srand() with the same argument (because time updates not very often), thus the rand() sequence was always the same, thus call to rand() always returned the same value.

How do I generate totally a random number at a time?

I want to create 3 random number at a time (simultaneously). However, they returned me the same numbers at a time even though they are actually random. Example:
------------------------
Variable: A B C
------------------------
Time 1 : 5 5 5
Time 2 : 3 3 3
Time 3 : 9 9 9
------------------------
They suppose to be different numbers at all. From the observation, I can see that my code can only pick a random number at a time (interval 1 second). Here is my generator code that I'm using:
unsigned int CMain::GenerateRandom(int min, int max)
{
srand((unsigned)time(0));
unsigned int random_integer;
int lowest = min, highest = max;
int range = (highest - lowest) + 1;
random_integer = lowest + int(range * rand() / (RAND_MAX + 1.0));
return random_integer;
}
How could I generate a totally random numbers at a time? Please help.
Thank you.
Your issue here is you're resetting the random seed every call using the current time which you shouldn't do.
Call srand() once before querying any random numbers - that's all and more than enough.
Right now you always reset your random seed to the exact same value (as you use current time). Random numbers in PCs aren't really random at all. The same seed will always result in the same set of random numbers generated later on. This is intentional and used in e.g. savegames for games to always have the same things happen without having to save every random number generated, etc.
Don't call srand() each time you generate a new random number. Call it once at the start of your program and then just call rand() each time you need a new random number.
FYI: Values returned from rand() are not "totally random". They are pseudo-random numbers generated by an algorithm. (This is not related to your question though.)
The problem is that you are calling srand() for every iteration. Srand() is setting a seed based on the current timestamp. Therefore you only need to call srand() once, and just call rand() to generate a new pseudo-random number. I say pseudo-random because computers cannot generate truly random numbers.
Sample code:
#include <iostream>
#include <cstdlib>
int main()
{
int i, r;
srand(time(0));
for(i = 0; r <= 20000; i++)
r = rand();
return 0;
}
time(0) changes slowly. If you query GenerateRandom quickly you can get the same number multiple times.
But in general, that isn't a right way to generate random numbers. You want to seed the random number generator only once, before any other function uses it. Treat rand as a global singleton object. If any of your functions modifies its seed by calling srand, then the change will affect all other calls to rand.