Advice on rand() code [duplicate] - c++

I'm a C++ newbie and I'm stumped on this. I need to call this function in my main function three times but each time it gives me the same result, i.e. pull_1, pull_2, pull_3 are the same. What do I need to do to make them actually random?
string PullOne()
{
string pick;
string choices[3] = {"BAR", "7", "cherries"};
std::srand(time(0));
pick = choices[(std::rand() % 3)];
return pick;
}
From my main function:
string pull_1, pull_2, pull_3;
pull_1 = PullOne();
pull_2 = PullOne();
pull_3 = PullOne();

You shouldn't call srand() before each call to rand(). Call it once – somewhere at the start of your program.
The problem is you restart the random generator so it starts to produce the very same pseudorandom sequence from the very same point.

The random number generator is reset to an initial state, which is dictated by the seed value, every time you call srand. Time value may be the same between successive calls to time, hence the same seed and the same number generated.
Call seeding function (srand) only once in your main function before generating random samples.

Why do you keep calling std::srand(time(0));? That re-seeds the PRNG.... and because this all happens within the same second, you're always re-seeding it with the same sequence.
Call srand once in your program, and once only.
Also, I would recommend, at least on POSIX-compliant systems, something like std::srand(time(0) ^ getpid()), so that you can run your program twice within the same "second" and still get a new PRNG sequence.

The time(0) function may not have 'ticked' between function calls. So you are seeding the random number generator with the same value each time, leading to identical values for rand()

Your problem is that you seed the RNG each time you call the function. You should only seed this once in a program for best results. If you want the result to vary from one execution of the program to the next, srand based on the result of the time() function.

Related

(c++) How do I stop this automatic loop, and why is it repeating the same number [duplicate]

I'm a C++ newbie and I'm stumped on this. I need to call this function in my main function three times but each time it gives me the same result, i.e. pull_1, pull_2, pull_3 are the same. What do I need to do to make them actually random?
string PullOne()
{
string pick;
string choices[3] = {"BAR", "7", "cherries"};
std::srand(time(0));
pick = choices[(std::rand() % 3)];
return pick;
}
From my main function:
string pull_1, pull_2, pull_3;
pull_1 = PullOne();
pull_2 = PullOne();
pull_3 = PullOne();
You shouldn't call srand() before each call to rand(). Call it once – somewhere at the start of your program.
The problem is you restart the random generator so it starts to produce the very same pseudorandom sequence from the very same point.
The random number generator is reset to an initial state, which is dictated by the seed value, every time you call srand. Time value may be the same between successive calls to time, hence the same seed and the same number generated.
Call seeding function (srand) only once in your main function before generating random samples.
Why do you keep calling std::srand(time(0));? That re-seeds the PRNG.... and because this all happens within the same second, you're always re-seeding it with the same sequence.
Call srand once in your program, and once only.
Also, I would recommend, at least on POSIX-compliant systems, something like std::srand(time(0) ^ getpid()), so that you can run your program twice within the same "second" and still get a new PRNG sequence.
The time(0) function may not have 'ticked' between function calls. So you are seeding the random number generator with the same value each time, leading to identical values for rand()
Your problem is that you seed the RNG each time you call the function. You should only seed this once in a program for best results. If you want the result to vary from one execution of the program to the next, srand based on the result of the time() function.

srand generating the same number [duplicate]

I'm a C++ newbie and I'm stumped on this. I need to call this function in my main function three times but each time it gives me the same result, i.e. pull_1, pull_2, pull_3 are the same. What do I need to do to make them actually random?
string PullOne()
{
string pick;
string choices[3] = {"BAR", "7", "cherries"};
std::srand(time(0));
pick = choices[(std::rand() % 3)];
return pick;
}
From my main function:
string pull_1, pull_2, pull_3;
pull_1 = PullOne();
pull_2 = PullOne();
pull_3 = PullOne();
You shouldn't call srand() before each call to rand(). Call it once – somewhere at the start of your program.
The problem is you restart the random generator so it starts to produce the very same pseudorandom sequence from the very same point.
The random number generator is reset to an initial state, which is dictated by the seed value, every time you call srand. Time value may be the same between successive calls to time, hence the same seed and the same number generated.
Call seeding function (srand) only once in your main function before generating random samples.
Why do you keep calling std::srand(time(0));? That re-seeds the PRNG.... and because this all happens within the same second, you're always re-seeding it with the same sequence.
Call srand once in your program, and once only.
Also, I would recommend, at least on POSIX-compliant systems, something like std::srand(time(0) ^ getpid()), so that you can run your program twice within the same "second" and still get a new PRNG sequence.
The time(0) function may not have 'ticked' between function calls. So you are seeding the random number generator with the same value each time, leading to identical values for rand()
Your problem is that you seed the RNG each time you call the function. You should only seed this once in a program for best results. If you want the result to vary from one execution of the program to the next, srand based on the result of the time() function.

rand() produces the same result on each function call (with srand(time(0))

I have a member function of a class that is supposed to generate a random number in a range. To do so, I am using the rand() function. The function generates a random number like this:
unsigned seed;
seed = time(0);
srand(seed);
std::cout << "Random Number: "<< rand() << std::endl;
The function is called on two different objects. The result is:
Random Number: 1321638448
Random Number: 1321638448
This is consistent every-time I call it. What am i doing wrong?
(Converting my comment to an answer).
For most applications, you'll only really want to seed rand once in the course of running a program. Seeding it multiple times requires you to get different random seeds, and it's easy to mess that up.
In your case, the time function usually returns something with resolution on the level of seconds (though this isn't actually required by the standard). As a result, if you call time twice within the same second, you might get back the same value. That would explain why you're getting duplicate values: you're seeding the randomizer with the same value twice and then immediately querying it for a random number.
The best solution to this is to just seed the randomizer once. Typically, you'd do that in main.
If you really do want to seed the randomizer multiple times, make sure that you're doing so using a seed that is going to be pretty much random. Otherwise, you risk something like this happening.
Pseudorandom number generators basically have to pass a set of statistical tests to make sure they're "random enough" as a set of numbers. But of course, it's not actually random. Calling srand(seed) with some seed basically generates a set of numbers which, if passed through those tests, will seem "random enough".
By calling srand(seed) with the same seed multiple times, you're effectively generating the same set over and over again and getting the first value in it.
You call srand(seed) ONCE, and then you call rand() to get the next values in the random number set. Or you need to call srand(seed) with a different (random) seed each time.
If you're on linux, you can also use /dev/urandom to get a random number- the kernel has been taking signal/noise from the environment to generate "entropy" for it, supposedly making it even better than an algorithm psuedorandom number generator.
srand function should be called only once in program(most cases, not all cases). If you want reseed, you should use different seed number. Because rand() function is pseudo-random number generator. In other words, rand() gives you a calculated number.
You can use much for powerful random number generating library after C++11. See: http://en.cppreference.com/w/cpp/numeric/random

rand() returns same values when called within a single function

I'm a C++ newbie and I'm stumped on this. I need to call this function in my main function three times but each time it gives me the same result, i.e. pull_1, pull_2, pull_3 are the same. What do I need to do to make them actually random?
string PullOne()
{
string pick;
string choices[3] = {"BAR", "7", "cherries"};
std::srand(time(0));
pick = choices[(std::rand() % 3)];
return pick;
}
From my main function:
string pull_1, pull_2, pull_3;
pull_1 = PullOne();
pull_2 = PullOne();
pull_3 = PullOne();
You shouldn't call srand() before each call to rand(). Call it once – somewhere at the start of your program.
The problem is you restart the random generator so it starts to produce the very same pseudorandom sequence from the very same point.
The random number generator is reset to an initial state, which is dictated by the seed value, every time you call srand. Time value may be the same between successive calls to time, hence the same seed and the same number generated.
Call seeding function (srand) only once in your main function before generating random samples.
Why do you keep calling std::srand(time(0));? That re-seeds the PRNG.... and because this all happens within the same second, you're always re-seeding it with the same sequence.
Call srand once in your program, and once only.
Also, I would recommend, at least on POSIX-compliant systems, something like std::srand(time(0) ^ getpid()), so that you can run your program twice within the same "second" and still get a new PRNG sequence.
The time(0) function may not have 'ticked' between function calls. So you are seeding the random number generator with the same value each time, leading to identical values for rand()
Your problem is that you seed the RNG each time you call the function. You should only seed this once in a program for best results. If you want the result to vary from one execution of the program to the next, srand based on the result of the time() function.

C++: seeding random number generator outside of main()

I was creating a simple program that simulates a coin toss for my class. (Actually, class is over this term and i'm just working through the rest of the projects that weren't required). It involves the creating and calling a function that generates a random number between 1 and 2. Originally, I tried to seed the random number generator within the function that would be using it (coinToss); however, it did not produce a random number. Each time the program was run it was the same number as though I had only used
rand()
instead of
unsigned seed = time(0);
srand(seed);
rand();
Yet, when i moved the above within
int main()
it worked fine.
My question is 1)why did it not work when setup within the function that called it and (2) how does rand()
have access to what was done by srand() if they do not both occur in the same function?
Obviously, i'm a beginner so please forgive me if i didn't formulate the question correctly. Also, my book has only briefly touched on rand() and srand() so that's all i really know.
thanks for any help!
Pertinent code:
First attempt that didn't work:
int main()
{
//...........
coinToss();
//...........
}
int coinToss()
{
unsigned seed = time(0);
srand(seed);
return 1 + rand() % 2;
}
Second attempt which did work:
int main()
{
unsigned seed = time(0);
srand(seed);
coinToss();
}
int coinToss()
{
return 1 + rand() % 2;
}
You probably only want to seed the random number generator once. rand() returns the next pseudo-random number from it's internal generator. Every time you call rand() you will get the next number from the internal generator.
srand() however sets the initial conditions of the random number generator. You can think of it as setting the 'starting-out point' for the internal random number generator (in reality it's a lot more complicated than that, but it's a useful cognitive model to follow).
So, you should be calling srand(time(0)) exactly once in your application - somewhere near the beginning. After that, you can call rand() as many times as you want!
However
To answer your actual question - the first version doesn't work because time() returns the number of seconds since the epoch. So If you call coinToss() several times in a second (say, if you wanted to simulate 100 coin tosses), then you'd be constantly seeding the random number generator with the same number, thereby resetting it's internal state (and thus the next number you get) every time.
Anyway - using time() as a seed to srand() is somewhat crappy for this very reason - time() doesn't chage very often, and worse, it's predictable. If you know the current time, you can work out what rand() will return. The internet has many, many examples of better srand() seeds.
Pseudo-random number generators (like rand) work by taking a single starting number (the seed) and performing a numeric transformation on it each time you request a new number. You want to seed the generator just once, or it will continually get reset, which is not what you want.
As you discovered, you should just call srand just once in main. Also note that a number of rand implementations have pretty short cycles on the low 4 bits or so. In practice this means you might get an easily predictable repeating cycle of numbers You might want to shift the return from rand right by 4-8 bits before you take the % 2.
EDIT: The call would look something like:
return 1 + (rand() >> 6) % 2;
Seed only once per program, not every time you call coinToss()
To expand on Mark B's answer: It is not so much that the random number generator is reset as it sets a new variable to be used in calculating random numbers. However your program doesn't do that much work between calls to srand. Therefore every time you call srand(time(0)) it is using the same seed, so you are resetting the internal state of the random number generator . If you put a sleep in there so that time(0) changed you would not get the same number every time.
As for how data passes from srand to rand, it is fairly simple, a global variable is used. All names that start with an underscore and a capital letter or two underscores are reserved for variables used by your compiler. More than likely this variable has been declared static so it isn't visible outside of the translation unit(aka the library file that contains your compiler's standard library.) This is done so that #define STUFF 5 doesn't break your standard library.
for simple simulations, you must not change the seed at all during the simulation. Your simulation will be "worse" in that case.
To understand this, you should see pseudo random sequences as a big wheel of fortune. When you change the seed, it is like you change the position, and then, each call to rand will give you a different number. If you roll again, it will be more probable finding yourself repeating numbers.