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.
Related
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.
I'm trying to write a piece of code that goes through a random element of a string array and then outputs it. After it outputs it then sets that element to 0. And then that if statement ensures that name will not be outputted again.
void group(){
int random = rand() % 50;
int i, j = 0;
while(j<50){
srand(0);
random = rand() % 50;
groupNum = 1;
cout << "Group " << groupNum << " has: ";
if(names[random] != "0"){
cout << names[random] << " ";
names[random] = "0";
j++;
}
if(names[random] == "0"){
continue;
}
i++;
if(i == peoplePerGroup){
groupNum++;
cout << "\n\n";
i=0;
}
}
}
srand function (as a pseudo-random number generator) should only be seeded once, before any calls to rand(), and the start of the program. It should not be repeatedly seeded, or reseeded every time you wish to generate a new batch of pseudo-random numbers.
"In order to generate random-like numbers, srand is usually initialized to some distinctive runtime value, like the value returned by function time (declared in header ). This is distinctive enough for most trivial randomization needs."
Also, every time your function runs, it's get a random element of your array and sets it to zero. The only way this loop ends is in a scenario that every single elements on this array were setted to zero. Buy in each loop, the index choosed is random. Think about how many times they need to run until they fill your requirements.
As a little explanation to why the re-seeding with the same number causes this issue:
rand() uses pseudo-randomness and therefore it is reproducable. Basically it meshes up some internal number that is set based on the seed. The number for example has bitwise XOR ( ^ ) applied to a constant etc. After every call, the number is also incremented internally.
Naturally that means that with the same starting number (aka the seed) you get the same results every time.
By the way, your whole code becomes much smoother if you fill all your words into an std::set and remove the word from the set when taking it, instead of setting it to null. See here: How to select a random element in std::set?
Or even easier, fill them into a vector and apply: std::random_shuffle
Then just iterate through that vector a single time to receive the words in random order.
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, ...
I have a variable that will either become 1 or 0, and all I know is rand()% 2.
The problem is when I loop it it keeps becoming either 1 for about four times straight then 0, or 0 for straight 6 times then 1.
I want it to be like 0 for once or twice, then 1, then 0 again. Something like that.
Is it possible to do this?
You either want a random number or a predictable result. You can't choose the amount of randomness, the whole point of a random number generator is to generate something unpredictable.
But what you can do is simply use the random number in a different way. If you want, say, at most, 4 consecutive runs of 0 or 1 you could determine the count of consecutive numbers using rand and generate the numbers yourself:
int number = 0;
for (int runs = 0; runs < 100; ++runs) {
int count = rand() % 4;
for (int i = 0; i < (count ? count : 1); ++i) { // Ensure at least 1 run
printf("%d", number);
}
number = 1 - number;
}
See codepad example:
http://codepad.org/OKe5Agib
If you really want to have only runs of 1 or 2, while maintaining some randomness, you can keep track of it like this;
int nextRandomIshThing( ) {
static int n1 = 0;
static int n2 = -1;
if( n1 != n2 ) {
n1 = n2;
// use a high-order bit, which supposedly has better randomness
// 14 because the standard guarantees that rand() produces at least
// 15 bits of randomness (not sure why that exactly)
n2 = (rand( ) >> 14) & 1;
} else {
n2 = !n2;
}
return n2;
}
http://codepad.org/HTTtPezu
But beware that depending on how you're using this, it means that users can "game" your system; "I've seen 2 1's, therefore the next must be 0!". A truly random source will always produce long sequences. There is a 1 in 8 chance for a truly random source to produce 4 1's or 0's in a row, and a 1 in 16 chance of 5. When you consider that you don't care where exactly the run starts, this becomes even more likely. If you want to be fair, embrace this instead of fighting it!
Oh and don't forget to srand.
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));