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.
Related
This question already has answers here:
Race-condition as a random number generator
(3 answers)
Closed 1 year ago.
I was reading up on multithreading in c++ and found out that if you'd run code like
#include <isostream>
#include <thread>
void function1(){
for(int i = 0; i<200; i++){
std::cout << '+';
}
}
void function2(){
for(int i = 0; i<200; i++){
std::cout << '-';
}
}
int main() {
std::thread worker1(function1);
std::thread worker2(function2);
system("pause>nul");
}
The plusses and minusses are in random order as this is dependent on what thread is finishing first, my question is then if this form of racing between threads could be a good random number generator and why (not).
Thanks in advance
No. You cannot do it, if you really need random numbers. Even as a seed you may not uses it. There is not enough entropy.
Speedwise it would be also totally insufficient.
I remember that when I was working in the gaming industry, some really good mathematiciens worked on random numbers for a long time and official governnment authorities certified the random number generators after weeks of test.
The authors of the C++ <random> library made the same efforts. To come up with better and faster algorithms may be extremely difficulty.
Additionally, maybe the behaviour with multithreading is even deterministic. For cooperative and preemtive (with priorities) multitasking this is most probably true.
But nice idea . . .
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
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
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.
This question already has answers here:
How to generate a random number in C++?
(14 answers)
Closed 5 years ago.
I have two questions.
What other ways are there to seed a psuedo-random number generator in C++ without using srand(time(NULL))?
The reason I asked the first question. I'm currently using time as my seed for my generator, but the number that the generator returns is always the same. I'm pretty sure the reason is because the variable that stores time is being truncated to some degree. (I have a warning message saying, "Implicit conversion loses integer precision: 'time_t' (aka 'long') to 'unsigned int') I'm guessing that this is telling me that in essence my seed will not change until next year occurs. For my purposes, using time as my seed would work just fine, but I don't know how to get rid of this warning.
I have never gotten that error message before, so I assume it has something to do with my Mac. It's 64-bit OS X v10.8. I'm also using Xcode to write and compile, but I had no problems on other computers with Xcode.
Edit:
After toying and researching this more, I discovered a bug that 64-bit Macs have. (Please correct me if I am mistaken.) If you try to have your mac select a random number between 1 and 7 using time(NULL) as the seed, you will always get the number four. Always. I ended up using mach_absolute_time() to seed my randomizer. Obviously this eliminates all portability from my program... but I'm just a hobbyist.
Edit2:
Source code:
#include <iostream>
#include <time.h>
using namespace std;
int main(int argc, const char * argv[]) {
srand(time(NULL));
cout << rand() % 7 + 1;
return 0;
}
I ran this code again to test it. Now it's only returning 3. This must be something to do with my computer and not the C++ itself.
Tl;dr but, most likely, you're doing it wrong. You're only supposed to set the seed once, whereas you might have something like:
for ( ... )
{
srand(time(NULL));
whatever = rand();
}
when it should be
srand(time(NULL));
for ( ... )
{
whatever = rand();
}
1.Not really. You can ask user to input random seed, for example. Or use some other system parameters, but this won't make a difference.
2.To rid of this warning you have to do explicit conversion. Like:
unsigned int time_ui = unsigned int( time(NULL) );
srand( time_ui );
or
unsigned int time_ui = static_cast<unsigned int>( time(NULL) );
or
unsigned int time_ui = static_cast<unsigned int>( time(NULL)%1000 );
to check whether this is really conversion problem you can simply output your time on the screen and see yourself
std::cout << time(NULL);
You should see random once at the begining of you program:
int main()
{
// When testing you probably want your code to be deterministic
// Thus don't see random and you will get the same set of results each time
// This will allow you to use unit tests on code that use rand().
#if !defined(TESTING)
srand(time(NULL)); // Never call again
#endif
// Your code here.
}
For x86, direct call to the CPU time stamp counter rdtsc, instead of a library function TIME(NULL), could be used. Below 1) reads timestamp 2) seed RAND in assembly:
rdtsc
mov edi, eax
call srand
For C++, the following would do the job with g++ compiler.
asm("rdtsc\n"
"mov edi, eax\n"
"call srand");
NOTE: But may not be recommended if code is running in virtual machine.