How do you generate random numbers effectively?
Every time a random number program boots up, it starts spitting same numbers as before. (I guess because of quasi nature of
Very few "random" number generators are actually random. Almost all are pseudorandom, following a predictable sequence when started with the same seed value. Many pseudorandom number generators (PRNGs) get their seed from the date and time of their initial invocation. Others get their seed from a source of random data supplied by the operating system, which often is generated from outside sources (e.g., mouse motion, keyboard activity).
The right way to seed a good random number generator is to not seed it. Every good generator has a default mechanism to supply the seed, and it is usually much better than any you can come up with. The only real reason to seed the generator is if you actually want the same sequence of random numbers (e.g., when you're trying to repeat a process that requires randomness).
See http://msdn.microsoft.com/en-us/library/system.random.aspx for the details of the C# Random class, but basically, it uses a very well known and respected algorithm and seeds it with the date and time.
To answer your key question, just use rand.Next(min, max+1)
and you'll always get a random sequence of numbers between min
and max
inclusive. The sequence will be the same every time you use the same seed. But rand = new Random()
will use the current time, and as long as your program is invoked with some separation in time, they'll be different.
I am not so conversant in C#. But I don't think this problem would occur in Java because the default constructor of Random class uses a seed based on current time and a unique count identifier.Below is code from java.util.Random class.
private static volatile long seedUniquifier = 8682522807148012L;
public Random() { this(++seedUniquifier + System.nanoTime()); }
If C# doesent support this out of box, you could use the above code to create a unique seed each time.
P.S: Note that since access to seedUniquifier is not synchronized, even though its volatile, there is a small possibility that same seeds are used for multiple Random objects. From javadoc of Random class:
"This constructor sets the seed of the random number generator to a value very likely to be distinct from any other invocation of this constructor."
"Seed" the random number generator by getting the number of seconds since midnight and then passing it in:
Random rand = new Random(secs);
This still does not generate perfectly random numbers, but should serve your purpose.
You can use a chaotic map to generate random numbers. The C++ code below (GenRandRea) returns a vector of random number using the so-called "Tent map" (https://www.wikiwand.com/en/Tent_map). The seed is an integer that is used to generate x (as a number between 0. and 1.) as input of the iterative map. Diferent seeds will generate different sequences.
vector<double> GenRandRea(unsigned seed, int VecDim){
double x, y, f;
vector<double> retval;
x = 0.5*(abs(sin((double)seed)) + abs(cos((double)seed)));
for (int i = 0; i<(tentmap_delay + VecDim); i++) {
if ((x >= 0.) && (x <= 0.5)) {
f = 2 * tentmap_r * x;
}
else {
f = 2 * tentmap_r * (1. - x);
}
if (i>=tentmap_delay) {
y = (x*tentmap_const) - (int)(x*tentmap_const);
retval.push_back(y);
}
x = f;
}
return retval;
}
with
const double tentmap_r = 0.75; //parameter for the tent map
const int tentmap_delay = 50; /*number of interactions in the tent map
allowing for sorting */
const double tentmap_const = 1.e6; //constant for the tent map
VecDim is the output vector dimension. The ideia is to iterate at least (tentmap_delay + VecDim) turns and write the result in retval (a vector of doubles).
To use this code:
vector<double> val;
val = GenRandRea(2, 10);
for (int kk=0; kk<10;kk++){
cout << setprecision(9) << val[kk] << endl;
}
which will for example produce:
0.767902586 0.848146121 0.727780818 0.408328773 0.88750684 0.83126026 0.253109609 0.620335586 0.569496621 0.145755069
Regards!
Producing the same sequence over and over is often a feature, not a bug, as long as you control it. Producing a repeatable sequence makes debugging easier. If you are serious about wanting a non-reproducible random sequence, you could look for a secure random number generator with this as a design aim. You've tagged your question C#, but since Java has http://docs.oracle.com/javase/1.4.2/docs/api/java/security/SecureRandom.html and the windows API has http://en.wikipedia.org/wiki/CryptGenRandom you may able to find an equivalent in C#.