Is it correct random generator function? [duplicate] - c++

This question already has answers here:
Generating a random integer from a range
(14 answers)
rand() function not generating enough random
(2 answers)
Closed 8 years ago.
I use this function to generate random integer.
int rnd(int min, int max)
{
static int srand(time(0));
return min + rand() % max;
}
Is it right? May be better to move srand(time(0)); to the main function? Like this:
int rnd(int min, int max){
return min + rand() % max;
}
int main(){
srand(time(0));
..............
}

Your first version does not do what you intend:
int rnd(int min, int max)
{
static int srand(time(0));
return min + rand() % max;
}
This does not call the function srand. It declares a static variable of type int and assigns it the value of time(0). Like int a(42); (or in C++11 int a{42};) declares an integer and sets it to 42.
Definitely use the second variant. It also makes live much easier, if you want to have another function for creating random values in a different way.
Additionally I strongly recommend to use std::random (or boost::random if you are not allowed to use C++11 for some obscure reason).

Definitely. You are now not calling the function but creating an integer variable named srand instead which shadows the global srand().
It does not help to re-seed the random generator each time -- it would even return always the same value if called during the same second! Calling it just once in main() would be better.
Also it should probably be min + rand() % (max - min + 1).

In general you only need to initialize the pseudorandom number generator once, so in the main function is a good idea.
I believe Netscape once had a bug due to seeding the random number generator too often, which caused its SSL implementation to be more easily cracked.

Is it right?
If by that you mean "is it generating a random number?", the answer is yes.
If you mean "is it optimal?" then the answer is no. You only need to initialize the sequence of random number once.
May be better to move srand(time(0)); to the main function
Maybe ... (you know what you need better than us).
What are you trying to achieve (that is, what are you using this random generator for)? If it is anything with financial data, online gambling application (or anything that takes/manages/costs money) it is not ok (nor is it to use srand and rand - you need something stronger).

Related

Trouble generating random numbers in c++ on a Mac using Xcode [duplicate]

This question already has an answer here:
std::random_shuffle produce the same result even though srand(time(0)) called once
(1 answer)
Closed 7 years ago.
I am writing a program that uses random numbers extensively in different ways and I am getting the same random numbers each time. I know to put srand(time(NULL));at the beginning of the program to seed the random number generator and so I have that, but it isn't working. Perhaps it has something to do with XCode or the Mac or something else? I can't find a similar problem online that I has a solution I haven't already tried. Some ways I'm using the random numbers are:
for (int i=0; i<num; i++)
{
chrom_arr[i] = i;
}
random_shuffle(&chrom_arr[0], &chrom_arr[num-1]);
(to get an array with a series of random ints between 0 and num-1)
int crossover = rand() % num;
and other simple things like that. Even though I have srand(time(NULL)); at the beginning, it still doesn't work. I've also tried srand(time(0)); and also putting it in different parts of the program, but I have since learned that's not right.
Alex, can you please post a small but complete program that fails to generate different random numbers every time you run it? I'd be interested to see it...
Here's one that (of course) does yield different numbers every time it is run on my Mac:
#include <iostream>
#include <ctime>
#include <cstdlib>
int main()
{
srand(time(NULL));
for (int i = 0; i < 10; ++i)
std::cout << rand() % 10 << std::endl;
return 0;
}
What does it do if you compile and run it several times on your computer?
UPDATE:
I thought you meant srand() + rand() also produced identical numbers every time. That is not true. However, you are right about the behaviour of srand() + random_shuffle(): it may indeed produce the same numbers every time, depending on your compiler. It does on my compiler (clang on Mac) too.
This is explained here.
You should try somethig like this:
srand(static_cast<unsigned int>(time(0)));
std::shuffle(chrom_arr.begin(), chrom_arr.end(), default_random_engine(rand()));
This will work as long as chrom_arr is a std::vector. Once you are using C++, I presume this is what you are trying to do.

std::mt19937 doesn't return random number [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 7 years ago.
Improve this question
I have the following piece of code:
unsigned int randomInt()
{
mt19937 mt_rand(time(0));
return mt_rand();
};
If I call this code, for example 4000 times in a for loop, I don't get random unsigned integers, instead I get for example 1000 times one value and the next 1000 times I get the next value.
What am I doing wrong?
This happens because you call f 4000 times in a loop, which probably takes less than a mili second, so at each call time(0) returns the same value, hence initializes the pseudo-random generator with the same seed. The correct way is to initialize the seed once and for all, preferably via a std::random_device, like so:
#include <random>
#include <iostream>
static std::random_device rd; // random device engine, usually based on /dev/random on UNIX-like systems
// initialize Mersennes' twister using rd to generate the seed
static std::mt19937 rng{rd()};
int dice()
{
static std::uniform_int_distribution<int> uid(1,6); // random dice
return uid(rng); // use rng as a generator
}
int main()
{
for(int i = 0; i < 10; ++i)
std::cout << dice() << " ";
}
A source of randomness is a resource that belongs to your entire program, not to a single function. You should pretty much never create a source of randomness inside a routine used to return a random value.
Good options include:
Pass a source of randomness into your function
Make your source of randomness a global variable
Make your source of randomness a static variable, so that initialization happens once.
One thing you might think to try that you should not do is to replace time(0) with a similar function that has a higher resolution; while you will get different results, this will still generate poor quality random numbers, and may even be much slower than generating random numbers properly. (I believe there are random number generators that can work properly with such usage, but those have to be designed for that purpose)

random numbers not generating properly ? (C++) [duplicate]

This question already has answers here:
using rand to generate a random numbers
(6 answers)
Closed 8 years ago.
I am currently using these functions in C++ to find a number and a suit for a card.
int getnumber () {
srand(time(0));
int number ;
number = rand()% 13 + 1;
return number;
};
int getsuitn () {
srand(time(0));
int suitn;
suitn = rand() % 4 + 1;
return suitn;
}
the output is always just the default constructor for the class, I have all the libraries needed to make this work, what am I doing wrong?
With the same seed the same sequence will be generated every time. Since you seed with the current time in seconds, every call you make in the same second will get the same first number from the sequence. Your whole program probably runs in under a second, so they all get the same result.
Seed the random number generator once at the start of your program.
Question: are you using c++11?
You should use <random> header. These functions will be mostly deprecated in C++14. An example of how to use <random>:
cppreference example

Random number generator always picks the same number [duplicate]

This question already has answers here:
function with rand initializes matrix always the same way
(2 answers)
Seeding a random number generator C++ [duplicate]
(4 answers)
Closed 8 years ago.
I'm making a small "dungeons and dragons" type of program to help demonstrate rand() command to me. It's working just fine, except it always picks 2. Never 1. Help?
#include <iostream>
#include <cstdlib>
using namespace std;
int main()
{
cout << "welcome to T's version of dungeons and dragons! \n Scenario:";
int Scenario1 = rand() % 2 + 1;
if(Scenario1==1){
cout << "you come across a sleeping traveler, Do you ignore him, or steal his loot?";
}
else {
cout << "you find an old bandit hideout in a cave. Do you ignore, or enter?";
}
}
rand() will essentially generate the same series of numbers every time if you don't seed it.
The seed determines how the rand function generates numbers. For better 'randomness', call the following once at the beginning of the program, for example as the first statement inside main:
srand(time(NULL));
This seeds the random number generator with the value of the current UNIX timestamp, which should be unique enough to guarantee a better illusion of randomness.
More information on srand here:
http://www.cplusplus.com/reference/cstdlib/srand/
Edit
As others have mentioned, it's better to use the functionality found in the <random> header, as this is a more modern approach that avoids many of the pitfalls of the srand/rand paradigm.
rand() will always generate the number in same sequence.
To generate totally random number you can use srand(time(0)); time() is available in header file called #include <ctime>
Fore more detail please have a look :: https://www.youtube.com/watch?v=naXUIEAIt4U

rand() and srand() in C++

What is the basis of generating random numbers in C++?
Is there some logic or principle behind that?
Are the numbers generated completely random?
Suppose I am running this program:
#include <iostream.h>
#include <stdlib.h>
#include <time.h>
int main()
{
/*
Declare variable to hold seconds on clock.
*/
time_t seconds;
/*
Get value from system clock and
place in seconds variable.
*/
time(&seconds);
/*
Convert seconds to a unsigned
integer.
*/
srand((unsigned int) seconds);
/*
Output random values.
*/
cout<< rand() << endl;
cout<< rand() << endl;
cout<< rand() << endl;
return 0;
}
What it shows:
http://img14.imageshack.us/img14/1538/98271820.png
It showed 205 twice.
The question was basically answered in comments and another answer, but I'll gather it up in one place.
C++ rand() function produces not a truly random sequence of numbers, but a pseudo-random one. This means that it is basically a pre-defined sequence of numbers which are "random", but fixed somewhere (actually, it's more complex than that, but this is a simplification for better understanding). Think of it as a long list of integers.
Each call to rand() function pulls the current number and moves the pointer to "current "random" number" to the next one.
What srand() function does is basically setting the pointer to some location in the list. If you don't call the srand() function on each launch, or call it with fixed parameter (seed), you will have the same sequence of numbers on each program launch.
When you're setting your seed from the seconds, if you launch your program twice within that second, your seed will be the same - hence producing the same result.
Try the following code:
#include <windows.h>
// << other code >>
for (int i=0; i<50; i++) {
time(&seconds);
srand(seconds);
cout<< seconds<<" "<<rand()<<endl;
Sleep(100);
}
You will notice, that each "seconds" value correspond to some fixed "first" value for the rand() function.
Starting with the second question:
Are the numbers generated completely random?
No, that is very unlikely to ever happen in a computer. They are "pseudo-random" numbers, which is some sequence of numbers that vary in range over time in a random-like fashion. But if you start with the same "seed", you get the same sequence each time. This predictability is sometimes very useful, as it allows repeating the same experiment several times with the same outcome - altering the seed, will allow a similar run to have a different outcome.
The function srand sets the seed. Some systems do have a function called randomize, but it is not part of the standard as such. If it does exist it sets the seed to something unknown to the code - such as the current time in milliseconds.
Is there some logic or principle behind that?
Yes. There are several methods for generating pseudo-randum numbers. Simple ones can be written in one or two lines of C code using regular int or long types, and just consists of taking the "current value" + some constant, multiplied by some large number and modulo some other large number.
More complex ones involve dozens of more lines of rather complicated math with large numbers - for example Mersenne Twister is a recent work that is available as source code if you search a little bit.