I want to create 3 random number at a time (simultaneously). However, they returned me the same numbers at a time even though they are actually random. Example:
------------------------
Variable: A B C
------------------------
Time 1 : 5 5 5
Time 2 : 3 3 3
Time 3 : 9 9 9
------------------------
They suppose to be different numbers at all. From the observation, I can see that my code can only pick a random number at a time (interval 1 second). Here is my generator code that I'm using:
unsigned int CMain::GenerateRandom(int min, int max)
{
srand((unsigned)time(0));
unsigned int random_integer;
int lowest = min, highest = max;
int range = (highest - lowest) + 1;
random_integer = lowest + int(range * rand() / (RAND_MAX + 1.0));
return random_integer;
}
How could I generate a totally random numbers at a time? Please help.
Thank you.
Your issue here is you're resetting the random seed every call using the current time which you shouldn't do.
Call srand() once before querying any random numbers - that's all and more than enough.
Right now you always reset your random seed to the exact same value (as you use current time). Random numbers in PCs aren't really random at all. The same seed will always result in the same set of random numbers generated later on. This is intentional and used in e.g. savegames for games to always have the same things happen without having to save every random number generated, etc.
Don't call srand() each time you generate a new random number. Call it once at the start of your program and then just call rand() each time you need a new random number.
FYI: Values returned from rand() are not "totally random". They are pseudo-random numbers generated by an algorithm. (This is not related to your question though.)
The problem is that you are calling srand() for every iteration. Srand() is setting a seed based on the current timestamp. Therefore you only need to call srand() once, and just call rand() to generate a new pseudo-random number. I say pseudo-random because computers cannot generate truly random numbers.
Sample code:
#include <iostream>
#include <cstdlib>
int main()
{
int i, r;
srand(time(0));
for(i = 0; r <= 20000; i++)
r = rand();
return 0;
}
time(0) changes slowly. If you query GenerateRandom quickly you can get the same number multiple times.
But in general, that isn't a right way to generate random numbers. You want to seed the random number generator only once, before any other function uses it. Treat rand as a global singleton object. If any of your functions modifies its seed by calling srand, then the change will affect all other calls to rand.
Related
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include <math.h>
int main()
{
int i;
int diceRoll;
for(i=0; i < 20; i++)
{
printf("%d \n", rand());
}
return 0;
}
This is the code I wrote in c (codeblocks) to get random numbers, the problem is I always get the same sequence: 41,18467,6334,26500 etc...
I'm still learning so please try to explain like you're talking with a 8 year old D:
You get the same sequence each time because the seed for the random number generator isn't set. You need to call srand(time(NULL)) like this:
int main()
{
srand(time(NULL));
....
Random number generators are pseudorandom. What this means is that they use some "algorithm" to come up with the next "random" number. In other words, if you start with the same seed to this algorithm, you get the same sequence of random numbers each time. To solve this, you have to make sure to seed your random number generator. Sometimes, it is desirable to use the same seed so that you may deduce if the logic of your program is working correct. Either way, one common way that folks seed their programs is through the use of time(NULL). time gives the time elapsed (in seconds) since the epoch time. What this means is that this function changes every second. Thus, if you seed your random number generator with (srand(time(NULL)) at the beginning of the program, you'll get a different random number sequence every different second that you run your program. Be sure not to seed for every random number that you request. Just do this once at the very beginning of your code and then leave it alone.
Your title says C# but I've answered with C++. You'll want to include ctime for this. It may also be beneficial to look at the new style of random number generation as rand() isn't very random these days. Look into #include random and make yourself an engine and distribution to pull random numbers through. Don't forget to seed there as well!
First of all, seed your random function by including <ctime> and calling srand(time(NULL));.
Secondly, you need a modulo if you're going to call rand(), for example: rand() % x will return a random number from 0 to x-1. Since you're simulating dice rolls, do rand() % 6 + 1.
The line srand((unsigned)(time(NULL)) must be outside the loop, must have this line just once in your code.
The modulo rand()%10 means you get any number starting from 0 going up to what you are modulo by -1. So in this case 0-9, if you want 1-10 you do: rand()%10 + 1
int main()
{
int i;
int diceRoll;
srand((unsigned)(time(NULL));
for(i=0; i < 20; i++)
{
printf("%d \n", rand() % 10); //Gets you numbers 0-9
}
return 0;
}
C++11 Introduced the class that allows for generating very random numbers, it also creates an even distribution of random numbers. There is also implementation to generate a seed (a number used to make the Random Number Generator more random).
I am trying to make a function that generates a random number between min and max but I am having trouble. The function only generates the seeds and the random number once. When I call the function in other words it will keep giving me the same number.
Below is the code, I try to generate a bunch of seeds, pick one of them randomly, use that seed for the RNG and finaly produce a random number.
int Utils::GenerateSuperRandomNum(int min, int max)
{
//Seed a the RNG
int randNum;
int randIndex;
seed_seq seq{ 1, 2, 3, 4, 5 };
vector<int> seeds(5 * max);
uniform_int_distribution<int> rngDistribution(min, max); //Generates number in the range min to max.
//Generate our seed numbers.
seq.generate(seeds.begin(), seeds.end());
//Generate random index bewteen 0 and size - 1.
srand(seeds.at(0));
randIndex = rand() % seeds.size();
//Seed the RNG with a random seed from our vector.
mt19937 rngGenerator(seeds.at(randIndex));
//Get a random number.
randNum = rngDistribution(rngGenerator);
return randNum;
}
seed_seq seq{ 1, 2, 3, 4, 5 };
vector<int> seeds(5 * max);
uniform_int_distribution<int> rngDistribution(min, max); //Generates number in the range min to max.
//Generate our seed numbers.
seq.generate(seeds.begin(), seeds.end());
seq is always fed the same input {1,2,3,4,5} so always has the same state. Since it has the same state, seeds.at(0) is always the same value.
//Generate random index bewteen 0 and size - 1.
srand(seeds.at(0));
Since srand is seeded with that same value every time, it to starts with the same state every time. Since it receives the same value every time, it always starts with the same state. The same state that rand uses.
randIndex = rand() % seeds.size();
Since rand always has the same state as per the srand, it will always generate the same first number every single time.
mt19937 rngGenerator(seeds.at(randIndex));
Since randIndex is always the same value, then seeds.at(randIndex) is always the same value. Since rngGenerator is always seeded with the same value, it always has the same state.
randNum = rngDistribution(rngGenerator);
Since rngDistribution always has the same state, it always produces the same value.
This is obviously a problem. The simple fix is to seed based on the CPU temperature, or the time, or some other value that changes often.
Basically, you've seriously overthought this. It's designed to be used like this:
int Utils::GenerateSuperRandomNum(int min, int max) {
static mt19937 rngGenerator(std::random_device{}());
std::uniform_int_distribution<int> rngDistribution(min, max);
return rngDistribution(rngGenerator);
}
std::random_device{}() generates a vaguely randomish number based on magic, hopefully hardware, like maybe the CPU tempurature or something. It can be slow or have other issues, so you should only use it once per program. Namely, to seed a faster/better generator.
static mt19937 rngGenerator( creates a single global generator, which is seeded the first time the function is called, and is never seeded again. This is perfect, because we want it to be initialized once, and then just do it's magic from then on. The usage of other generators like rand don't add any entropy, so don't do that. We also don't want to re-seed it, as that might accidentally reduce randomness, rather than increase it.
std::uniform_int_distribution<int> rngDistribution(min, max); and rngDistribution(rngGenerator) you seem to understand. They use the generator to give random numbers in that distribution. Done deal.
A seed does not make a (pseudo-)random number generator more random. It provides a starting point for generating a reproducible sequence of random numbers.
Which means, if you provide the exact same seed, you'll get the exact same results.
Making a random number generator more "random" by using it to generate it's own seed is a bit like trying to lift yourself up by pulling on your boot straps. If this is just for fun the time is a sufficiently random seed, if you are doing super spy crypto a h/w device that provides true random events is what you need.
You could try using this service, I don't know if it is valid or just the NSA trying to trick you. https://www.random.org
I noticed that while practicing by doing a simple console-based quiz app. When I'm using rand() it gives me the same value several times in a row. The smaller number range, the bigger the problem is.
For example
for (i=0; i<10; i++) {
x = rand() % 20 + 1;
cout << x << ", ";
}
Will give me 1, 1, 1, 2, 1, 1, 1, 1, 14, - there are definetely too much ones, right? I usually got from none to 4 odd numbers (rest is just the same, it can also be 11, 11, 11, 4, 11 ...)
Am I doing something wrong? Or rand() is not so random that I thought it is?
(Or is it just some habit from C#/Java that I'm not aware of? It happens a lot to me, too...)
If I run that code a couple of times, I get different output. Sure, not as varied as I'd like, but seemingly not deterministic (although of course it is, since rand() only gives pseudo-random numbers...).
However, the way you treat your numbers isn't going to give you a uniform distribution over [1,20], which I guess is what you expect. To achieve that is rather more complicated, but in no way impossible. For an example, take a look at the documentation for <random> at cplusplus.com - at the bottom there's a showcase program that generates a uniform distribution over [0,1). To get that to [1,20), you simply change the input parameters to the generator - it can give you a uniform distribution over any range you like.
I did a quick test, and called rand() one million times. As you can see in the output below, even at very large sample sizes, there are some nonuniformities in the distribution. As the number of samples goes to infinity, the line will (probably) flatten out, using something like rand() % 20 + 1 gives you a distribution that takes very long time to do so. If you take something else (like the example above) your chances are better at achieving a uniform distribution even for quite small sample sizes.
Edit:
I see several others posting about using srand() to seed the random number generator before using it. This is good advice, but it won't solve your problem in this case. I repeat: seeding is not the problem in this case.
Seeds are mainly used to control the reproducibility of the output of your program. If you seed your random number with a constant value (e.g. 0), the program will give the same output every time, which is useful for testing that everything works the way it should. By seeding with something non-constant (the current time is a popular choice) you ensure that the results vary between different runs of the program.
Not calling srand() at all is the same as calling srand(1), by the C++ standard. Thus, you'll get the same results every time you run the program, but you'll have a perfectly valid series of pseudo-random numbers within each run.
Sounds like you're hitting modulo bias.
Scaling your random numbers to a range by using % is not a good idea. It's just about passable if your reducing it to a range that is a power of 2, but still pretty poor. It is primarily influenced by the smaller bits which are frequently less random with many algorithms (and rand() in particular), and it contracts to the smaller range in a non-uniform fashion because the range your reducing to will not equally divide the range of your random number generator. To reduce the range you should be using a division and loop, like so:
// generate a number from 0 to range-1
int divisor = MAX_RAND/(range+1);
int result;
do
{
result = rand()/divisor;
} while (result >= range);
This is not as inefficient as it looks because the loop is nearly always passed through only once. Also if you're ever going to use your generator for numbers that approach MAX_RAND you'll need a more complex equation for divisor which I can't remember off-hand.
Also, rand() is a very poor random number generator, consider using something like a Mersenne Twister if you care about the quality of your results.
You need to call srand() first and give it the time for parameter for better pseudorandom values.
Example:
#include <iostream>
#include <string>
#include <vector>
#include "stdlib.h"
#include "time.h"
using namespace std;
int main()
{
srand(time(0));
int x,i;
for (i=0; i<10; i++) {
x = rand() % 20 + 1;
cout << x << ", ";
}
system("pause");
return 0;
}
If you don't want any of the generated numbers to repeat and memory isn't a concern you can use a vector of ints, shuffle it randomly and then get the values of the first N ints.
Example:
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main()
{
//Get 5 random numbers between 1 and 20
vector<int> v;
for(int i=1; i<=20; i++)
v.push_back(i);
random_shuffle(v.begin(),v.end());
for(int i=0; i<5; i++)
cout << v[i] << endl;
system("pause");
return 0;
}
The likely problems are that you are using the same "random" numbers each time and that any int mod 1 is zero. In other words (myInt % 1 == 0) is always true. Instead of %1, use % theBiggestNumberDesired.
Also, seed your random numbers with srand. Use a constant seed to verify that you are getting good results. Then change the seed to make sure you are still getting good results. Then use a more random seed like the clock to teat further. Release with the random seed.
I have the following method which generates a random number:
int random_number() //Random number generator
{
int x = rand() % 1000000 + 1; //Generate an integer between 1 and 1000000
return x;
}
The call to this method is used in a loop which iterates five times. The problem with this method is that it always seems to generate the same numbers when running the program several times. How can this be solved?
You need to seed the random number generator, such as:
srand ( time(NULL) );
int x = rand() % 1000000 + 1;
Seeding the pseudorandom number generator essentially decides on the random number set that it will iterate through. Using the time is the standard method of achieving adequately random results.
EDIT:
To clarify, you should seed only once and get many random numbers, something like this:
srand ( time(NULL) );
loop {
int x = rand() % 1000000 + 1;
}
Rather than something like:
loop {
//Particularly bad if this line is hit multiple times in one second
srand ( time(NULL) );
int x = rand() % 1000000 + 1;
}
make a call to srand(time(NULL)); when your program launches.
srand sets a seed to the rand function. Giving it the return value of time(NULL) helps getting a different seed at each program run.
As you tagged your question as c++, you could either use c++11 feature to handle random number generation.
femtoRgon is right. This will seed the program but take a look at the new c++ standard as they have improved random number generation
see
Random numbers in C++0x
rand is not really a random number, but rather a pseudo-random one that just "looks" random if you don't know the algorithm used to generate the values. From the man page:
The rand() function returns a pseudo-random integer in the range 0 to RAND_MAX inclusive
pseudo-random means that given the same input, called a seed, it will give the same output. This is actually quite useful when you're trying to debug a problem since the same "random" values will be returned, letting you reproduce the problem.
It's bad if you really need randomness.
As noted above by changing the seed to something different on each run, like say seconds since the epoch, you can get different values from your call to rand().
srand(time(NULL))
If you're trying to debug you may want to print out the seed so you can reproduce problems if they occur.
I have a simple integer vector, with only 4 values. I want to loop through the vector, assigning either 0 or 1 to each value. I want it to be random to the point that its different every time.
I thought the following would suffice:
for (int i = 0; i < (int)numberVect.size(); i++)
{
numberVect[i] = rand() % 2;
}
However, what I found was that every time I would close and re-open the program, the exact same values would be assigned.
So the first time through it would be 1,0,0,0, then if I ran the loop again without closing the program it would be 0,1,0,1. which seems perfect.
HOWEVER, after closing the program and restarting it up again, I would find the first sequence would again be 1,0,0,0 and the second would again be 0,1,0,1.
Also I have a second question in relation to this problem:
Can you suggest a way to make sure that AT LEAST one of the values in the vector is a 1? while still allowing the random generation to work seamlessly?
Thanks a lot and I hope you guys can help :D
Question 1
You need to seed your random number generator with srand.
The sequence of pseudo-random numbers generated depends on the seed value (and are thus reproducible with the same seed value). I use the the current time as the seed value:
srand(time(NULL));
Question 2
There are only 16 possible sequences for you to choose from (4 bits).
0000
0001
0010
0011
0100
0101
0110
0111
1000
1001
1010
1011
1100
1101
1110
1111
Out of these, you want to randomly select one with at least 1 high bit. Therefore you just need to randomly select a number from 1 to 15 and then convert it to binary!
There are two ways of doing this:
Method 1:
int R = rand() % 15 + 1;
Method 2:
float r = static_cast<float>(rand())/RAND_MAX;
int R = static_cast<int>( ceil(1 + (15-1)*r) );
Once you have R, convert it to binary. Here's a sample program with Method 1:
// Seed the random number generator
srand(static_cast<unsigned int>(time(NULL)));
// Get the random number from 1 - 15
int R = (rand()%15)+1;
cout<<R<<endl;
// Convert to binary
vector<int> numberVect(4);
for (int i = static_cast<int>(numberVect.size())-1; i >=0 ; i--)
{
numberVect[i] = R%2;
R/=2;
}
// Display
cout<<numberVect[0]<<","<<numberVect[1]<<","<<numberVect[2]<<","<<numberVect[3]<<endl;
Note: static_cast<int>(x) is the C++ way of doing (int)x if you didn't know.
You should seed your random generator with the current time at program start to avoid this behaviour.
You need to seed the random generator, before using it. For that you need srand()
I usually do that with passing current time to srand() as:
#include <time.h>
srand(time(NULL)); //seeding!
//now use
int whatever = rand();
Now everytime, you run this code you'll get different random sequence,even if there is one second of difference between two consecutive runs.
You need to seed your random numbers. Using the time is common practice.
Do this in your program before you generate any random numbers:
srand(time(NULL));
The random number generator isn't "truly random", it needs to start somewhere, and typically people will use the current system time as a good "kinda random" start point, guaranteeing that each run of the program will be different.
Your second question: can you make sure that at least one of the values is a "1" while still being random? Well, no, of course not, then it wouldn't be random. :) You can post-process, though, if you're willing to forgo some of the "randomness"-- after you generate the vector, check to see if there's at least one "1" value. If not, set one of them to "1". :)
You have to initialize the random seed. Include stdlib.h and time.h, then call this before calling rand() for the first time:
srand(time(NULL));
This code initializes the random seed with the current system time, in seconds, so you always get different results (unless you start the program twice during one second.)
You're getting the same results each time you run the program because you aren't seeding rand. It's usually recommended to seed based on time:
srand(time(NULL));
To make sure at least 1 number is 1, you could use a bool to indicate if you've gotten a 1 yet. If at the end of the array, you don't have a 1, do a final call to rand with a mod of the vector size, and set that value to 1.