Variables always the same after first execution? - c++

I'm porting a python script to C++, which calls a function over thousand times. I've never programmed in C++ so i'm not sure what's happening and couldn't figure out a better title to the question.
This is not my actual function, but it reproduces the same error
int maior_sequencia()
{
int random;
srand(time(NULL));
int maior_sequencia = rand() % 6+1;
printf("%i", maior_sequencia);
return 1;
}
int main()
{
for(int i = 1; i<=100; i++)
{
maior_sequencia();
}
return 1;
}
If the first result from maior_sequencia() is 3, then it will output 3333333...
If i run the program again, and the first result is for is 5, it will output 555555...
Why is this happening?

int maior_sequencia()
{
int random;
srand(time(NULL));
//^^This will reset random seed every time you call this function
int maior_sequencia = rand() % 6+1;
printf("%i", maior_sequencia);
return 1;
}
Since you reset the random seed every time you call the maior_sequenciafunction, therefore, it will give you same value.
Try to put
srand(time(NULL));
inside main before the for loop instead.

The problem is two fold. First your use of srand and your use of time. When you seed a random number generator using time(), time is the number of seconds from some date in 1973, I forget the exact date, but it's known as linux time. Since you seed every time, you're resetting the random number generator, this is a good practice, however, since you're seeding it with something returning a number in seconds, it is likely your program is taking less than a second to run. Either do as someone else suggest, and seed the random number generator only once, or seed in something with a finer granularity... ms is probably acceptable.

Related

Why use "time" in srand?

I like to learn by screwing around with code, recently I copied and pasted a random number generator code. Then I removed all the lines of code that were not "necessary" to make the executable work to generate a random number. The final straw was me deleting "time" from srand.
srand((unsigned) time(0));
What is the point of "time(0)" here?
Does it use the time that the program is opened to generate the seed for the random number? Is that why removing it (time) makes it not work? Because then it doesn't have a seed?
Also...
include <stdlib.h>
include <stdio.h>
include <time.h>
int main()
{
srand((unsigned) time(0));
printf("Your dice has been rolled! You got:");
int result = 1 + (rand() % 20);
printf("%d", result);
}
that's the whole code and I noticed it used the "rand" result for output. Does the "rand" pull the seed from "srand"?
If you don’t “seed” the random number generator (or if you use the same seed value), you’ll get the same set of pseudorandom numbers.
Using the current time is an easy way to get a different seed every time.
The effect of srand cannot cross threads, so the random number seed should be set once on each thread. #Buddy said that using time(0) is the most convenient way to do this, and each call will get a different seed.Of course you can use an atomic variable .
std::atomic<int> seek(2374213); //init whatever you like
void thread1fun()
{
srand(++seek);
//...
int rand_num = rand();
}
void thread2fun()
{
srand(++seek);
//...
int rand_num = rand();
}

Program works only if I keep displaying something until solution is found

I have made a program that generates a random array of numbers. I am aware that if I make a for structure to place random numbers, there might be a chance that I will have values that will repeat. For that I made a separate recursive function that keeps looking for duplicates and replace them with other values until there will be only distinct numbers:
#include <iostream>
#include <stdlib.h>
#include <time.h>
using namespace std;
int n, m, k, row[100];
int verif(int v[100], int k)
{
for(int i=0; i<k-1; i++)
for(int j=i+1; j<k; j++)
if(v[i]==v[j])
{
cout<<".";
srand(time(NULL));
v[i]=rand()%100+1;
return verif(v, k);
}
return 1;
}
int main()
{
k=10, n=10;
srand(time(NULL));
row[0]=rand()%n+1;
srand(row[0]);
for(int i=1; i<k; i++)
{
srand(row[i-1]);
row[i]=rand()%n+1;
}
verif(row, k);
for(int i=0; i<k; i++)
cout<<row[i]<<" ";
return 0;
}
I hope you can explain me why does a simple cout inside verif makes my program to work and why without it nothing works.
This is a result of calling a function recursively for an extended period of time, likely triggering a stack overflow on your machine.
This expression
srand(time(NULL));
seeds the random number generator for rand() to the value of the present number of seconds since the epoch. Naturally this number changes only once per second. Reseeding the rand generator will get you the same sequence as last time, so the result of rand()%100 + 1 on the following line will remain the same until the result of time(NULL) changes.
Now that you've ensured that v[i]==v[j] will be true until at least a second has passed since the initial assignment, you recursively call this function again, (and again (and again...)) until you get a new value from your "random" number generating procedure (at least a second has passed) or you run out of space on the stack. (you crash)
You can clearly see this happening much more clearly by using a function which holds up execution for longer than is taken by the cout statement, for instance
std::this_thread::sleep_for(std::chrono::milliseconds{500});
You can see such an effect here on coliru
With the sleeping function (which holds the execution up for 500 milliseconds every recursion) you get ~13 recursions.
Without it you get ~2846000 recursions. That's quite a difference.
There are better ways to get a set of non-repeating random numbers in a range, as shown in the answers to this question. I'm partial to Darklighter's answer myself. For that answer if you want, say, 10 elements out of 100, generate the vector with 100 elements, shuffle and then resize it to include only the first 10.
The cout solves the problem because it takes time to print something on the console. All the rest of the code takes roughly 0 time, thus each time you do
srand(time(NULL));
v[i]=rand()%100+1;
You will get exactly the same number, as you always use the same seed. Then I am not 100% sure what happens, it might be a stackoverflow because you keep calling the function recursively forever, or it might be something else. Actually it doesnt really matter, because the real problem is your seed.
Only with the cout you will eventually get a differnt seed and also a different random number.
You should seed the rng only once. And btw if you want random numbers you should use the rngs from <random> and not rand (actually it should be deprecated because of its low quality).

Seeding Random number generator not working

I have a c++ program that uses a random generator to create a cube. To create the cube I have this:
void generateSquare() {
int num = 0;
srand(time(NULL));
for (int r = 0; r < MSQUARE; r++) {
for (int c = 0; c < MSQUARE; c++) {
do {
num = (rand() % (MSQUARE * MSQUARE)) + 1;
} while (!checkUnique(num));
cube[r][c] = num;
}
}
}
It only allows a number to be generated one. This function is then wrapped in a do..while loop so that if the square doesn't meet a specific condition a new square will be generated until the one that does meet the condition is generated.
The problem is that it continually is generating the same square over and over again. I thought that the srand(time(NULL)) would seed the rand() function so that it would generate different random numbers each time to create a new unique square every time it is called but it looks like that is not happening.
void checkSquare() {
do {
generateSquare();
} while (!perfect);
}
This is not the actual do...while loop but gives you an idea of how it's being called.
How do I make sure the seed is unique each time?
You should call srand only once, at the beginning of your program. The reason why your seed is always the same is because time returns a number of seconds. Since you're calling it in a loop it always has the same value (until a second goes by).
Also if you can use C++11 or later you should look at the pseudo-random number generation in the standard library
srand sets the seed of the rand function. If you set it to a specific number it will always return you the same sequence of numbers. You will use this if you want to test a program, otherwise you use rand() without srand().
http://www.cplusplus.com/reference/cstdlib/srand/

random_shuffle produces same results every time

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;
}
}

A random number generator that can get different numbers in < a second

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;