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);
}
}
Related
Will this:
new java.util.Random(/* random seed */ 0)
new java.util.Random(/* random seed */ 1)
result in somehow "less random" / "more similar" random generators than this?
new java.util.Random(/* random seed */ 0)
new java.util.Random(/* random seed */ 1000)
In other words: do I risk having similar series of ints obtained from the random generators if their random seeds are similar?
No, similar seeds, will not produce similar random numbers.
Only same seeds will produce same numbers.
The code to set the seed is:
void setSeed(long seed) {
this.seed = (seed ^ 0x5DEECE66DL) & ((1L << 48) - 1);
..}
This formula avoids that this.seed gets simlar values for the input seed value (used in the constructor, or by setSeed().
However there is some weakness, als explained in
http://dontpanic.42.nl/2011/03/when-random-isn-as-random-as-expected.html
The state updates used to produce pseudo-random numbers are chaotic. Hence, using adjacent seed values results in entirely different state trajectories.
Random numbers are never random. They are entirely pre-defined and given the same seed will always result in the same numbers even over a million different runs of the commands, that is the reason they are called "Pseudorandom". The best thing to do is to seed with a value that will be different each time the program is run and can not be predicted easily such as the current time and date and/or number of clock cycles that have passed.
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.
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).
If a seed number is defined for the random number generation, is it possible that different random number sequences are achieved on different computers? If so, how to achieve the same sequences?
private static final long seed = 1;
Random generator = new Random(seed);
for (int i = 0; i < nchrom; i++) {
val = (int) Math.round(generater.nextDouble()*(nchrom-1));
//...
}
Yes, with the same seed you should get the same sequence of numbers. The algorithm is specified in the documentation:
An instance of this class is used to generate a stream of pseudorandom numbers. The class uses a 48-bit seed, which is modified using a linear congruential formula. (See Donald Knuth, The Art of Computer Programming, Volume 2, Section 3.2.1.)
If two instances of Random are created with the same seed, and the same sequence of method calls is made for each, they will generate and return identical sequences of numbers. In order to guarantee this property, particular algorithms are specified for the class Random. Java implementations must use all the algorithms shown here for the class Random, for the sake of absolute portability of Java code. However, subclasses of class Random are permitted to use other algorithms, so long as they adhere to the general contracts for all the methods.
My only concern would be that if you're using nextDouble() you could run into some artifacts of floating point unit differences. I suspect you won't, but that would be my concern. I'd recommend that you use nextInt anyway:
val = generator.nextInt(nchrom); // Exclusive upper bound
When I enter 42 for the seed value, it provides a certain sequence of numbers and reproduces the same ones every time the program is used. But the sequence of numbers in my program doesn't match up with the sequence of numbers in another program. I need to figure out how to make both of them provide the same output of random numbers when both seed values are set to 42. Is this the correct format for getting a seed value from the user? What could be causing the numbers to not match up? Thanks for the help.
public class SampleTest {
public static void main(String[] args) {
System.out.println("Please enter a seed value: ");
Scanner in = new Scanner(System.in);
seed = in.nextInt();
Random ranGen = new Random(seed);
You say that you are seeding the random number generator with the same seed, making the same calls, and yet the number sequences are different.
I think there are two plausible explanations for what is happening:
Your two applications are in fact not seeding the generator and using it the same way. There are lots of mistakes that could have been made, including accidentally using more than one generator (as per #PD's comment).
The applications are running on platforms with different implementations of the generator class. (This would be contraindicated by the javadocs for Random, which specify the exact generator formulae that should be used.)
The way to figure out which of these two possibilities is occurring is to write a simple test application that just prints the sequence of numbers produced by a Random instance with a given seed, then run it on both machines.