Clarification on calling srand [duplicate] - c++

This question already has answers here:
How often should I call srand() in a C++ application?
(4 answers)
What does 'seeding' mean?
(4 answers)
Closed 3 years ago.
I'm wondering why it's advantageous to seed srand at the beginning of the program, instead of where I use it.
I generate pseudo-random numbers when seeding srand at the beginning of my program but I get the numbers all the same when I seed srand inside the function I call to generate the numbers
#include <iostream>
#include <ctime>
using namespace std;
int rng()
{
const int SIZE = 10;
int rng[10];
srand(time(NULL));
for (int i = 0; i < 10; i++)
{
rng[i] = rand() % 128 + 1;
return rng[i];
}
}
int main()
{
int array;
//srand(time(NULL)); If i put it here i get actual random numbers
cout << "Welcome to the program";
cout << "\nthis is your rng\n";
for (int i = 0; i < 10; i++)
{
array = rng();
cout << array << endl;
}
return 0;
}
When I run the program all of the numbers are the same, but when I delete the seeding from in the rng function and uncomment the srand in the main module the numbers are pseudo-random which is what I want. Im wondering why though. I've looked into it and heard that im seeding srand with a time and when I run that function the loop iterates so fast that all of the numbers are generated with the same seed value so they're all the same, but I'm wondering what's the difference from that and having srand(time(NULL)) in main because either way doesn't the function generate the numbers so fast they'll be at the same seed value anyway? It doesn't appear that way because of the different output but im curious, why?

time returns number of seconds since 1.1.1970 so calling it repeatedly during one second will indeed return same values. It doesn't matter exactly where you put srand as long as it's before all rand calls and it should only be called once per program as it's global and obviously resets the random sequence. So if you use it only where you need it, you risk that when some other part of the code will need it too and calls srand again, it will interfere with your rand calls. It's not necessary to call it at all but then the seed will always be the same. It's good for debugging to have an option to set the seed deterministicly.
That said, don't use it, just don't.
As you observed time is not a good seed generator and rand is not even good random number generator, certainly not for floats and x mod n. Use <random> library. It has std::random_device which can generate true random numbers = good seeds. Sadly it's not required to. std::mt19937 is go-to RNG which together with std::XX_YY_distributions should be more than enough for everything but the most extreme need for randomness. It's also thread-safe because you control access to the generator and how it's used.

Related

C++ Password Generator Generates Same Password [duplicate]

In this rather basic C++ code snippet involving random number generation:
include <iostream>
using namespace std;
int main() {
cout << (rand() % 100);
return 0;
}
Why am I always getting an output of 41? I'm trying to get it to output some random number between 0 and 100. Maybe I'm not understanding something about how the rand function works?
You need to change the seed.
int main() {
srand(time(NULL));
cout << (rand() % 101);
return 0;
}
This srand thing also works for C.
See also:
http://xkcd.com/221/
For what its worth you are also only generating numbers between 0 and 99 (inclusive). If you wanted to generate values between 0 and 100 you would need.
rand() % 101
in addition to calling srand() as mentioned by others.
srand() seeds the random number generator. Without a seed, the generator is unable to generate the numbers you are looking for. As long as one's need for random numbers is not security-critical (e.g. any sort of cryptography), common practice is to use the system time as a seed by using the time() function from the <ctime> library as such: srand(time(0)). This will seed the random number generator with the system time expressed as a Unix timestamp (i.e. the number of seconds since the date 1/1/1970). You can then use rand() to generate a pseudo-random number.
Here is a quote from a duplicate question:
The reason is that a random number generated from the rand() function isn't
actually random. It simply is a transformation. Wikipedia gives a better
explanation of the meaning of pseudorandom number generator: deterministic
random bit generator. Every time you call rand() it takes the seed and/or the
last random number(s) generated (the C standard doesn't specify the algorithm
used, though C++11 has facilities for specifying some popular algorithms), runs
a mathematical operation on those numbers, and returns the result. So if the
seed state is the same each time (as it is if you don't call srand with a truly
random number), then you will always get the same 'random' numbers out.
If you want to know more, you can read the following:
http://www.dreamincode.net/forums/topic/24225-random-number-generation-102/
http://www.dreamincode.net/forums/topic/29294-making-pseudo-random-number-generators-more-random/
You are not seeding the number.
Use This:
#include <iostream>
#include <ctime>
using namespace std;
int main()
{
srand(static_cast<unsigned int>(time(0)));
cout << (rand() % 100) << endl;
return 0;
}
You only need to seed it once though. Basically don't seed it every random number.
random functions like borland complier
using namespace std;
int sys_random(int min, int max) {
return (rand() % (max - min+1) + min);
}
void sys_randomize() {
srand(time(0));
}
"srand(time(NULL));" as 1st line at "main()" won't help you if you're using "rand()" at static init. somewhere. You better create "struct rnd_init { rnd_init() { srand (time (nullptr)); } }" named whatever suits you, as a static var at the scope where "rand()" is being used: at some constructor, or whatever.

How do i Pick a Random Number from an array in c++? [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 4 years ago.
Improve this question
int array[5];
int Random;
for (int i = 0; i <5; i++)
{
cin>>array[i];
}
for (int j = 0; j < 5; j++)
{
Random = array[rand() % array[j]];
}
cout << Random << endl;
This is giving me continously return 1 but i want different number every time
Rand is basically obsolete.
There were just so many complaints about how bad it was (because to use it correctly you had to remember to do a couple of things). Even Peris in his answer does not correct for uneven ranges.
So please try and use the modern random library it is much more powerful. Though its documentation is hard going you don't need to read it all. Here is a simple example of how to use it.
#include <random>
#include <iostream>
#include <vector>
int main()
{
std::vector<int> array(5, 0);
for (int i = 0; i < 5; ++i)
{
std::cin >> array[i];
}
std::random_device rd;
std::mt19937 gen(rd());
std::uniform_int_distribution<> dis(0, array.size() - 1);
std::cout << array[dis(gen)];
}
Notes:
rd: Random device. Gives some initial randomness to help initialize things.
Think of this as the `srand(time())` in the old random (but better).
mt19937: This is the algorithm used to generate the random number.
It is initialized with some random value from rd. But it
is a well know well understood random algorithm.
Also be seperating this out into its own object.
We don't have a central random number place. This means
different applications can have their own unique random number stream.
Note: If you want a random number stream. But the same stream
every time (testing/debugging) then don't use the random
device to initialize this object. Just use a nice normal
integer and it will give a random stream of numbers but each
time you run the application you get the same stream (which is useful
for debugging when you don't actually want real randomness).
dis: The main issue with the old rand() is that if just gave a number.
It was up to the user of the number to build appropriate distributions
and to be blunt most people either got it wrong or did not bother.
In the random library there are several built in distributions but uniform
is a nice easy one that is often useful (and I hope obvious).
rand() doesn't return a true-random, rather it returns a pseudo-random.
It all depends on the initial seed you provide to the random generator. If the initial seed is the same, then the consequent numbers you'll get from pseudo-random-algorithm is the same.
Then you should change the initial seed for the rand() on each call (in this case, each execution of your program). What else is a better changing value than time?
Note:
array[rand() % array[j]]; line on your code is highly vulnerable to segmentation fault by array index going out of bound.
Here is the solution.
#include <iostream>
#include <time.h>
using namespace std;
int main()
{
// Initialize the srand seed.
srand (time(NULL));
int size = 5;
int array[size];
int Random;
for (int i = 0; i <5; i++)
{
cin>>array[i];
}
int index = rand() % size;
Random = array[index];
cout << Random << endl;
}
UPDATE:
As many others suggested, you can move to std::uniform_int_distribution for better results. My answer only updates your initial code.

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

What's the Right Way to use the rand() Function in C++?

I'm doing a book exercise that says to write a program that generates psuedorandom numbers. I started off simple with.
#include "std_lib_facilities.h"
int randint()
{
int random = 0;
random = rand();
return random;
}
int main()
{
char input = 0;
cout << "Press any character and enter to generate a random number." << endl;
while (cin >> input)
cout << randint() << endl;
keep_window_open();
}
I noticed that each time the program was run, there would be the same "random" output. So I looked into random number generators and decided to try seeding by including this first in randint().
srand(5355);
Which just generated the same number over and over (I feel stupid now for implementing it.)
So I thought I'd be clever and implement the seed like this.
srand(rand());
This basically just did the same as the program did in the first place but outputted a different set of numbers (which makes sense since the first number generated by rand() is always 41.)
The only thing I could think of to make this more random is to:
Have the user input a number and set that as the seed (which would be easy to implement, but this is a last resort)
OR
Somehow have the seed be set to the computer clock or some other constantly changing number.
Am I in over my head and should I stop now? Is option 2 difficult to implement? Any other ideas?
Thanks in advance.
Option 2 isn't difficult, here you go:
srand(time(NULL));
you'll need to include stdlib.h for srand() and time.h for time().
srand() should only be used once:
int randint()
{
int random = rand();
return random;
}
int main()
{
// To get a unique sequence the random number generator should only be
// seeded once during the life of the application.
// As long as you don't try and start the application mulitple times a second
// you can use time() to get a ever changing seed point that only repeats every
// 60 or so years (assuming 32 bit clock).
srand(time(NULL));
// Comment the above line out if you need to debug with deterministic behavior.
char input = 0;
cout << "Press any character and enter to generate a random number." << endl;
while (cin >> input)
{
cout << randint() << endl;
}
keep_window_open();
}
It is common to seed the random number generator with the current time. Try:
srand(time(NULL));
The problem is that if you don't seed the generator it will seed itself with 0 (as if srand(0) were called). PRNGs are designed to generate the same sequence when seeded the same (due to the fact that PNRGs are not really random, they're deterministic algorithms and maybe a bit because it's quite useful for testing).
When you're trying to seed it with a random number using
srand(rand());
you're in effect doing:
srand(0);
x = rand(); // x will always be the same.
srand(x);
As FigBug mentioned, using the time to seed the generator is commonly used.
I think that the point of these articles is to have a go at implementing the algorithm that is in rand() not how to seed it effectively.
producing (pseudo) random numbers is non trivial and is worth investigating different techniques of generating them. I don't think that simply using rand() is what the authors had in mind.

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;