I can't understand what was the meaning of Seed in java.util.Random ? I had read Why does this code print “hello world”? question and I am still confuse about seed . Can anyone describe me kindfully what was seed actually mean ? Thanks.
In documentation for setSeed() method ... what does mean seed - the initial seed ?
public void setSeed(long seed)
Sets the seed of this random number generator using a single long seed. The general contract of setSeed is that it alters the state of this random number generator object so as to be in exactly the same state as if it had just been created with the argument seed as a seed. The method setSeed is implemented by class Random by atomically updating the seed to
(seed ^ 0x5DEECE66DL) & ((1L << 48) - 1)
and clearing the haveNextNextGaussian flag used by nextGaussian().
The implementation of setSeed by class Random happens to use only 48 bits of the given seed. In general, however, an overriding method may use all 64 bits of the long argument as a seed value.
Parameters:
seed - the initial seed
I would expect if I can understand exactly meaning of seed , I am sure I will understand clearly to this answer.
A pseudo-random number generator produces a sequence of numbers. It
isn't truly random, but generally a mathematical calculation which
produces an output that matches some desirable distribution, and
without obvious patterns. In order to produce such a sequence, there
must be state stored for the generator to be able to generate the next
number in that sequence. The state is updated each time using some
part of the output from the previous step.
Seeding explicitly initialises this state. A 'seed' is a starting
point, from which something grows. In this case, a sequence of
numbers.
This can be used either to always generate the same sequence (by using
a known constant seed), which is useful for having deterministic
behaviour. This is good for debugging, for some network applications,
cryptography, etc.
Or, in situations where you want the behaviour to be unpredictable
(always different each time you run a program, a card game perhaps),
you can seed with a number likely to be continually changing, such as
time.
The 'randomness' of the sequence does not depend on the seed chosen,
though it does depend on not reseeding the sequence.
Taken from What is a seed in relation to a random number generation algorithm and why is computer time used to create this seed more often than not?
This should answer your question.
The pseudorandom number generator is implemented in terms of an integer which is, each time you ask for a number, transformed into another integer by the pseudorandom sequence generator function.
The initial value of that internal integer is termed the seed. The idea is to set it differently each time you instantiate Random because the pseudorandom sequence is fully deterministic once the seed is assigned.
If you use the nullary constructor, new Random(), then System.currentTimeMillis() will be used for the seed, which is good enough for almost all cases.
java.util.Random.setSeed(long seed): Sets the seed of this random number generator using a single long seed
Syntax:
public void setSeed(long seed)
Parameters:
seed - the initial seed
Every Random constructed with the same seed will generate the same
pattern of numbers every time.
So basically we set seed with a long value when we want to get the
same random number sequence every time (like in video
games,debugging,etc)
I strongly recommend to go through this answer:https://stackoverflow.com/a/23127798/9080948
and this video:https://youtu.be/86_cnhqSyh0
Related
There are 2 constructors of Random class
public Random()
public Random(long seed)
The description for the second constructor as per oracle states as
Creates a new random number generator using a single long seed. The seed is the initial value of the internal state of the pseudorandom number generator which is maintained by method next(int).
I did not understand it completely. And I did not find any articles/book which clearly explains why,when and how it is used.
Can any one explain please?
If you use the constructor with the seed, you will get a repeatable sequence, so it's good for testing. If you use the constructor without the seed, you don't know what sequence of random-like numbers will be produced.
A pseudorandom number generator works by repeatedly generating a new number based on the one it has previously generated. That means that if you always have the same first "random" number, and you use the same pseudorandom number generator to generate the second, you'll always have the same second "random" number as well.
The first Random constructor constructs a pseudorandom number generator with a nondeterminate seed (first number in the sequence), so you'll almost always end up with a different sequence of "random" numbers. The second Random constructor constructs a pseudorandom number generator with whatever seed you want, so if you give it the same seed, you'll always get the same sequence.
Here's an example. If you create a Random like this:
Random yourRandom = new Random();
it will start off with some seed. That seed could be 42, 121, 3810, whatever. You can never be sure when you create it. All the random numbers it generates are based off of that seed, and so since it nearly always uses a different seed, you'll nearly always get different "random" numbers out of it.
On the other hand, if you create a Random like this instead:
Random yourOtherRandom = new Random(36);
all the numbers yourOtherRandom generates will be calculated starting from 36. Since the first number (36) is the same, and the second number is calculated from the first, etc., everything yourOtherRandom generates will be the same every time you run your program.
This is a fun one!
The Random number generation is not random at all. If you use the same seed and ask it for a bunch of random numbers, you will get the same sequence. This is important as it allows different computers to predictably generate the same sequence as long as they have shared the seed.
If you do not specify a seed, then one is chosen for you that is very unlikely to be chosen by any other VM in the world. BUT, if someone were to guess the seed you used, they would be able to generate the same sequence of numbers.
From Google search:Random search
The Random generator is a Pseudorandom number generator. That means that it is, in fact, not a random number generator but only some clever algorithm that produces fully deterministic numbers that just look like random.
When the generator is used, each time it produces a random number it modifies its internal state in order to produce a different number at the next call. However, at the beginning the internal state of this algorithm must be initialised, and the value that is used for this initialisation is commonly called seed. The parameterless constructor makes a seed on its own, based on system time, while the other constructor lets you to put your seed, which allows you to make it repeatable - the same seed (and the same generator) will produce the same sequence of numbers.
If you are interested, here is the source code of the Random class from OpenJDK (i.e. the open source implementation of Java, but it should be functionally equivalent). The constructor with seed is at line 135, the setSeed method is at line 168 and e.g. the nextInt method is at line 328 which just calls a private method next which is at line 198 and which is where all the magic happens. It also has javadoc with the reference to the (probably more mathematical) description of this kind of generator.
I wonder whether what you want to ask is about distinguishing the default constructor and argument constructor. When you instantiate a new Random object, you can code this:
Random random=new Random();
In this way, we invoke the default constructor, i.e no argument constructor.
But if you code this:
Random random=new Random(47);
we invoke a constructor which argument is 47.
It is similar to C language; a seed will "randomly" create a number if you use the same seed and no matter when it will not change. But if you choose the first method, the number will modify once running!
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.
How does the seed value passed to Java's random number generator effect its output? How would i go about figuring out which numbers it will output if i know the seed value?
Also are some seed values better than others at producing more psudo-randomness than others?
You cannot generate truly random numbers in software, because software is deterministic: given some input, it will in principle always generate a predictable output.
So, to get random numbers, a number of algorithms have been invented that generate sequences of numbers that look random (but are not really - that's why they are called pseudo-random numbers).
Such an algorithm starts with some start value, the seed, and then does some calculations with it to generate the next pseudo-random number.
If the algorithm is any good, then there should be no difference in seed values: one seed value should not be better than any other in generating random numbers.
Often, the current time is taken as the seed value, so that each time you generate a sequence of numbers, you get a different sequence. Note that if you use the same seed value, you will get the same sequence of pseudo-random numbers each time you run it.
If you use pseudo-random numbers for cryptographic purposes, you should be very careful, because if an attacker knows the seed value then he can re-generate the sequence of random numbers which might compromise the security of your system. For really secure systems, people use special hardware-based random number generators, which can generate truly random numbers. Java has a class java.security.SecureRandom to interface with such systems.
See Random number generation on Wikipedia for a lot more detail and information on different algorithms.
I need to test out a Java program 20 times and need to set the random seed so that the tests can be repeated. If I were to set the initial seed as 0 and then increment by 1 at each run (i.e. 1,2,3 etc), would this method still ensure complete randomness, even though the seeds are not far apart?
Thank you
Any seed will provide the same level of randomness as any other seed for a standard PRNG like the one included with Java. So it's fine to use an incrementing seed for tests.
You might want to consider using a better random number generator though. The one included with Java yields noticeable repeating patterns if you render the values as an image (I can't find a reference offhand, but I recall it being apparent). I'd recommend the Mersenne Twister (there are Java versions) as an alternative that's fast and has a very long period so you won't easily see patterns.
If you use a seed of 0 the sequence of random numbers will be repeatable from that point. You would only need to use a different random seed if you wanted a different sequence. i.e. you should be able to set the seed once per test.
Why not just use the current time as the seed? ie, System.currentTimeMillis() ?
Do you need a number or a string? I use UUID.randomUUID().toString() to get a UUID for my tests when I need strings, but if you need a number then you can use System.nanoTime().