I know there are a lot of topics about random number generation in Android and Java in general. I am currently programming an app that rolls 5 dices. I currently use Random() to generate these numbers. This is my code:
Random r = new Random();
a[0] = r.nextInt(6)+1;
a[1] = r.nextInt(6)+1;
a[2] = r.nextInt(6)+1;
d[0] = r.nextInt(6)+1;
d[1] = r.nextInt(6)+1;
Documentation says that Random() without custom seed is sufficient for most tasks. Is it still random enough when I generate 5 random numbers in such short time? Is there any difference if I generate a new Random() object after each random number?
You don't need a new seed each time you generate a random number. The same seed will generate the same random sequence of numbers so you have to worry about generating an unpredictable seed. The default constructor Random() will generate a seed partially based on current time which should be sufficient for your purpose.
If you do not use a custom seed (e.g. based on time or some such non-easily-repeatable itme), then your results will repeat each time you execute (i.e. you will get the same sequence of pseudo random numbers).
You want to add a custom seed so that successive executions of your program do not always have the same result.
While it is not necessary for a simple homework question to use a custom seed, it would be a good idea to add use of a custom seed (so you learn about how to do that and why it may be needed for more complex problem solving).
Related
I understand I have to use the random method but thats where my understanding ends
The Random class has a nextInt(int) method that makes it easy to select a value:
Random random = new Random(); // ... or possibly reuse an existing Random
int side = random.nextInt(6); // resulting side is in 0...5
In many other languages, there is only a method to obtain an evenly-distributed number between 0 and 1. In those cases, multiplying this value by the size of the range will give you an evenly distributed number in the desired range, and then you simply add an offset to shift the result into the range in question. This is the same principle by which the internals of nextInt() operates.
If I pick a seed (say 999) and generate a stream of random numbers, how can I choose a second seed that ensures the second stream of random numbers does not match the first? Does the second seed need to be measurably different from 999? Would something as simple as seed2 = seed1 + 1000 work? The programming language I'm interested in is Java.
Simple question
java.lang.Math.random()
How does this work? Meaning there is no seed input, so does it generate a random number off the system time? Meaning like if two calls were made to this function at .00001s away from eachother (basically the same time), would it produce the same result?
Thanks!
The javadoc explains how it works:
When this method is first called, it creates a single new pseudorandom-number generator, exactly as if by the expression
new java.util.Random()
This new pseudorandom-number generator is used thereafter for all calls to this method and is used nowhere else.
Returned values are chosen pseudorandomly with (approximately) uniform distribution from that range. When this method is first called, it creates a single new pseudorandom-number generator, exactly as if by the expression new java.util.Random
This new pseudorandom-number generator is used thereafter for all calls to this method and is used nowhere else. This method is properly synchronized to allow correct use by more than one thread. However, if many threads need to generate pseudorandom numbers at a great rate, it may reduce contention for each thread to have its own pseudorandom-number generator.
In order to understand how does this code runs you must go through the various Random Number generator algorithms. In actual practice theres no concept call random numbers if you google "Psuedo Random Number Algorithm" then you can have a better insight about the various concepts.
Answering your Question : Yes there will be different if the Random Number Generator Algorithm is based on time (usually they are).
But at the output if u write
Random obj1 = new Random()
int p = obj1.nextInt(10%2)
int q = obj1.nextGaussian();
theres a chance that the same number may appear more than once. It is because the Number generated is undoubtedly a unique number but it due to various parameters the obtained output is filtered and so theres a probabilty that the ouput can be same
There are two principal means of generating random (really pseudo-random) numbers:
the Random class generates random integers, doubles, longs and so on, in various ranges.
the static method Math.random generates doubles between 0 (inclusive) and 1 (exclusive).
To generate random integers:
do not use Math.random (it produces doubles, not integers)
use the Random class to generate random integers between 0 and N.
To generate a series of random numbers as a unit, you need to use a single Random object - do not create a new Random object for each new random number.
Other alternatives are:
SecureRandom, a cryptographically strong subclass of Random
ThreadLocalRandom, intended for multi-threaded cases
import java.util.Random;
/** Generate 10 random integers in the range 0..99. */
public final class RandomInteger {
public static final void main(String... aArgs){
log("Generating 10 random integers in range 0..99.");
//note a single Random object is reused here
Random randomGenerator = new Random();
for (int idx = 1; idx <= 10; ++idx){
int randomInt = randomGenerator.nextInt(100);
log("Generated : " + randomInt);
}
log("Done.");
}
private static void log(String aMessage){
System.out.println(aMessage);
}
}
I am using a simple random calculations for a small range with 4 elements.
indexOfNext = new Random().nextInt(4); //randomize 0 to 3
When I attach the debugger I see that for the first 2-3 times every time the result is 1.
Is this the wrong method for a small range or I should implement another logic (detecting previous random result)?
NOTE: If this is just a coincidence, then using this method is the wrong way to go, right? If yes, can you suggest alternative method? Shuffle maybe? Ideally, the alternative method would have a way to check that next result is not the same as the previous result.
Don't create a new Random() each time, create one object and call it many times.
This is because you need one random generator and many numbers from its
random sequence, as opposed to having many random generators and getting
just the 1st numbers of the random sequences they generate.
You're abusing the random number generator by creating a new instance repeatedly. (This is due to the implementation setting a starting random number value that's a very deterministic function of your system clock time). This ruins the statistical properties of the generator.
You should create one instance, then call nextInt as you need numbers.
One thing you can do is hold onto the Random instance. It has to seed itself each time you instantiate it and if that seed is the same then it will generate the same random sequence each time.
Other options are converting to SecureRandom, but you definitely want to hold onto that random instance to get the best random number performance. You really only need SecureRandom is you are randomly generating things that have security implications. Like implementing crypto algorithms or working around such things.
"Random" doesn't mean "non-repeating", and you cannot judge randomness by short sequences. For example, imagine that you have 2 sequences of 1 and 0:
101010101010101010101010101010101
and
110100100001110100100011111010001
Which looks more random? Second one, of course. But when you take any short sequence of 3-4-5 numbers from it, such sequence will look less random than taken from the first one. This is well-known and researched paradox.
A pseudo-random number generator requires a seed to work. The seed is a bit array which size depends on the implementation. The initial seed for a Random can either be specified manually or automatically assigned.
Now there are several common ways of assigning a random seed. One of them is ++currentSeed, the other is current timestamp.
It is possible that java uses System.currentTimeMillis() to get the timestamp and initialize the seed with it. Since the resolution of the timestamp is at most a millisecond (it differs on some machines, WinXP AFAIK had 3ms) all Random instances instantiated in the same millisecond-resolution window will have the same seed.
Another feature of pseudo-random number generators is that if they have the same seed, they return the same numbers in the same order.
So if you get the first pseudo-random number returned by several Randoms initialized with the same seed you are bound to get the same number for a few times. And I suspect that's what's happening in your case.
It seems that the number 1 has a 30% chance of showing its self which is more than other numbers. You can read this link for more information on the subject.
You can also read up on Benford's law.
Whenever we create an object of Random class in java. We either of the constructor
Random()
Random(long seed)
What is the purpose of seed here in the 2nd constructor and how can I use it to my benefit i.e. manipulate its use?
The answer above sums it up clearly. As per java api docs from oracle, the first constructor
Random()
"Creates a new random number generator. 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. "
The seed is probably a derivative of the current time, or the current time itself. That should be enough to be "very likely to be distinct from any other invocation". Which, in essence, is most likely what you need, most of the time.
So why have another constructor that takes a seed?
Simply put, if you want to generate the same set of random numbers over and over, you use the same seed on your Random constructor. This is useful when doing experiments on different control sets, and you don't want to bother creating your own table of random inputs, but still want the same set of random input on a different experiment/control set.
There's no such thing as truly random numbers in computing. The available methods for getting a random number across all programming languages is nothing but an algorithm to simulate random numbers.
In some languages (C++, I know for sure), an unseeded random number generator will return the same series of numbers on every fresh execution of the program.
What is common is to seed the random number generator with the current time (which will be random enough for most purposes) so that the algorithm starts with a random number each time.
Pseudo-random number generators maintain some set of state information, which is advanced through some recurrence relation to determine the next value of the state. The output of a PRNG is some function of the state. Java's Random class uses a Linear Congruential Generator. LCG's work using the recurrence relationship Ui+1 = (A Ui + C) % M for some constant integer values A, C, and M. Java's current implementation uses a 48-bit state but uses 32 bits or less of it on each iteration of the recurrence.
Based on this, you can see that if you start with the same state you will get the exact same sequence of values out of your PRNG. This can be useful if you want to be able to reproduce exactly the same sequence of "randomness", for instance for debugging or for comparing two experiments head-to-head.
If you invoke the constructor without an argument, it picks a starting value for the state with a promise that different invocations are very likely to be distinct from each other. If you supply a seed to the constructor, that seed's value is used to set the initial state.