This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Java: generating random number in a range
I am unable to understand what is happenning in class Random and in it's methods.
will someone explain it,plz?
or is there any simpler way also to generate random numbers?
Note:I want to understand the code of the function (Random.nextInt),not how to use it.
If you want random integers between x (inclusive) and y (exclusive), here's what you do:
int yourRandomNumber = new Random().nextInt(y-x) + x;
Example: if you want a random selection of [4,5,6,7], you will do:
int yourRandomNumber = new Random().nextInt(4 /* i.e. 8-4 */) + 4;
What is difficult to understand? There are methods for generating nearly every type of random number... The one you want is probably this:
int nextInt(int n)
Returns a pseudorandom, uniformly distributed int value between 0 (inclusive) and the specified value (exclusive), drawn from this random number generator's sequence.
EDIT: You ask how the function actually works. This too is explained in the javadoc of the function. If you're more interested in details, you should probably get the D. Knuth book referenced in the docs (from http://download.oracle.com/javase/1.4.2/docs/api/java/util/Random.html):
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.
The algorithms implemented by class Random use a protected utility method that on each invocation can supply up to 32 pseudorandomly generated bits.
Many applications will find the random method in class Math simpler to use.
Related
I am writing some kotlin, and would like to use the Prime constructor for BigIntegers. Because I want to generate some really big prime numbers.
The documentation for the constructor looks like this:
BigInteger(int bitLength, int certainty, Random rnd)
Constructs a randomly generated positive BigInteger that is probably prime, with the specified bitLength.
My problem is here that I find it a little unspecified what these arguments actually do.
bitlength
My first assumption is that this is just the amount of bits that I want the BigInt to have. This seems simple enough, but still i'm a bit in doubt about whether this means my number will use this many bits, or if it is a maximum, minimum etc.
certainty
This one is really mystical to me. Is this the probability that the number is prime, or the probability of that is has the beforementioned bitlength.
And on top of that, which unit do we use to denote certainty? percentages, is some probability ranking system i have never heard of?
** rnd**
I assume this is just a random generator as they come standardly in java.
But what is it used for in this context? it would be nice to be able to know why I should provide one
Hope someone can help in clearing my my confusion
The rest of the documentation is here:
https://docs.oracle.com/javase/7/docs/api/java/math/BigInteger.html
I wrote program that simulates dice roll
Random r = new Random();
int result = r.nextInt(6);
System.out.println(result);
I want to know if there is a way to "predict" next generated number and how JVM determines what number to generate next?
Will my code output numbers close to real random at any JVM and OS?
They're pseudorandom numbers, meaning that for general intents and purposes, they're random enough. However they are deterministic and entirely dependent on the seed. The following code will print out the same 10 numbers twice.
Random rnd = new Random(1234);
for(int i = 0;i < 10; i++)
System.out.println(rnd.nextInt(100));
rnd = new Random(1234);
for(int i = 0;i < 10; i++)
System.out.println(rnd.nextInt(100));
If you can choose the seed, you can precalculate the numbers first, then reset the generator with the same seed and you'll know in advance what numbers come out.
I want to know if there is a way to "predict" next generated number and how JVM determines what number to generate next?
Absolutely. The Random class is implemented as a linear congruential number generator (LCNG). The general formula for a linear congruential generator is:
new_state = (old_state * C1 + C2) modulo N
The precise algorithm used by Random is specified in the javadocs. If you know the current state of the generator1, the next state is completely predictable.
Will my code output numbers close to real random at any JVM and OS?
If you use Random, then No. Not for any JVM on any OS.
The sequence produced by an LCNG is definitely not random, and has statistical properties that are significantly different from a true random sequence. (The sequence will be strongly auto-correlated, and this will show up if you plot the results of successive calls to Random.nextInt().)
Is this a problem? Well it depends on what your application needs. If you need "random" numbers that are hard to predict (e.g. for an algorithm that is security related), then clearly no. And if the numbers are going to be used for a Monte Carlo simulation, then the inate auto-correlation of a LCNG can distort the simulation. But if you are just building a solitaire card game ... it maybe doesn't matter.
1 - To be clear, the state of a Random object consists of the values of its instance variables; see the source code. You can examine them using a debugger. At a pinch you could access them and even update them using Java reflection, but I would not advise doing that. The "previous" state is not recorded.
Yes, it is possible to predict what number a random number generator will produce next. I've seen this called cracking, breaking, or attacking the RNG. Searching for any of those terms along with "random number generator" should turn up a lot of results.
Read How We Learned to Cheat at Online Poker: A Study in Software Security for an excellent first-hand account of how a random number generator can be attacked. To summarize, the authors figured out what RNG was being used based on a faulty shuffling algorithm employed by an online poker site. They then figured out the RNG seed by sampling hands that were dealt. Once they had the algorithm and the seed, they knew exactly how the deck would be arranged after later shuffles.
You can also refer this link.
Check How does java.util.Random work and how good is it?:
In other words, we begin with some start or "seed" number which
ideally is "genuinely unpredictable", and which in practice is
"unpredictable enough". For example, the number of milliseconds— or
even nanoseconds— since the computer was switched on is available on
most systems. Then, each time we want a random number, we multiply the
current seed by some fixed number, a, add another fixed number, c,
then take the result modulo another fixed number, m. The number a is
generally large. This method of random number generation goes back
pretty much to the dawn of computing1. Pretty much every "casual"
random number generator you can think of— from those of scientific
calculators to 1980s home computers to currentday C and Visual Basic
library functions— uses some variant of the above formula to generate
its random numbers.
And also Predicting the next Math.random() in Java
For example the code below. It has a random class. However it always produce the same output everywhere . In this case which item is the seed?
source: link
import java.util.Random;
public class RandomTest {
public static void main(String[] s) {
Random rnd1 = new Random(42);
Random rnd2 = new Random(42);
System.out.println(rnd1.nextInt(100)+" - "+rnd2.nextInt(100));
System.out.println(rnd1.nextInt()+" - "+rnd2.nextInt());
System.out.println(rnd1.nextDouble()+" - "+rnd2.nextDouble());
System.out.println(rnd1.nextLong()+" - "+rnd2.nextLong());
}
}
42 is the seed, as the very same Javadoc says. So, what is a seed? A random number is seldom truly random - often it's a pseudo-random instead. This means it's generated from a function, which is said PRNG (pseudo random number genrator). Being generated from a function, in turn, means that the output is not random anymore, since it's predictable!
However, depending on your needs, this pseudo-randomness may be enough - I said enough because generating random bit is expensive, and I'm not talking about time or memory, but about money (see this link on wikipedia). So, for example, if you need a random value to place enemies in your game, a pseudo-random number is ok - but if your are building security-related software, you want to use a true random number, or at least a cryptographically secure PRNG.
How can we describe a PRNG, like the one used in Math.random()? It's a function, initialized with a seed S that returns an array of values A. Note that, for each integer S, is defined one and only one array A. For example (values are not actual):
first call second call third call
seed: 14329 .18 .82 .5
seed: 3989 .7 .02 .93
So you seed you PRNG with some known value when you want its result to be predictable - for example for testing purposes or to ensure that, each time you run level 1 in your game, the enemies are always placed in the same (pseudo) random places - otherwise you don't need to explicitely pass a seed.
Random Seed on Wikipedia:
A random seed (or seed state, or just seed) is a number (or vector)
used to initialize a pseudorandom number generator.
In other word, it is the number from which a seem-to-be-random sequence will be generated. Therefore, if you use the same number, the senquence will always be the same.
In practice, we usually use System Time as seed.
The seed is given as the argument of the constructor of Random; using the same seed will yield the same sequence of numbers. However this is discussed under the link in thet question.
In this case the seed is 42. This is the reason for the same output - you use the same seed.
You can use for example
Random rnd1 = new Random(System.currentTimeMillis())
for different outputs.
The seed is the initial value of the internal state of the pseudorandom number generator which is maintained by method next(int).
The invocation new Random(seed) is equivalent to:
Random rnd = new Random();
rnd.setSeed(seed);
From the Java documentation in the Random class
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).
The invocation new Random(seed) is equivalent to:
Random rnd = new Random();
rnd.setSeed(seed);
So 42 is the seed given to the new Random() in your example
there is some ways to generate random Numbers in java
one of them is this:
Random rand=new Random();
int randomInteger=rand.nextInt();
now my question is this: can we predict next random Number?
edited after 4 answers:
my real problem is this:
I'm working on a Snake Game( nibbles in Linux) and I'm programing the snake to move, now I want to know if it's possible to Predict the next place that the apple will appear.
is it possible?
You can not only predict it, but know it absolutely, if you know exactly what System.currentTimeMillis would return when you called new Random(). That's because new Random() is a shortcut for new Random(System.currentTimeMillis()), which sets the seed of a pseudo-random generator. (Well, that's what it did when I last looked at the source; the docs don't actually say it has to use that.) if you know the seed that new Random() used. Pseudo-random generators are deterministic, if you know the seed, you know the sequence. Update: Looking at the Java 6 source [I don't have Java 7 source handy], the default seed is a combination of a seed number that gets incremented on use, plus System.nanoTime. So you'd need to know both of those. Raises the bar.
If you don't know the exact value of System.currentTimeMillis() as of when new Random() occurs the seed used by new Random(), then it's very difficult indeed to predict what the next value will be. That's the point of pseudo-random generators. I won't say it's impossible. Just really, really hard to do with any degree of confidence.
Update after question edit: It's possible, but very, very hard, and in terms of doing so in a way that would allow a player to improve their score in the game, I'd say you can ignore it.
The "random" numbers generated by the Random class are generated algorithmically, and as such are really pseudo-random numbers. So yes, in theory, you can predict the next number. Knowing one number that Random has produced, though, or even a series of numbers, isn't enough information to predict the next number; you would also need to know the seed that the Random object is using, and you would need to follow its pseudo-random number generation algorithm.
If you would like a repeatable set of "random" numbers, you can specify your own seed when creating an instance of Random, e.g.
Random rand = new Random(1234); // Replace 1234 with any value you'd like
Every time you instantiate Random with the same seed, you'll get the same series of numbers. So, for example, you could write a small command-line program that instantiates Random with some seed and prints a list of the numbers it returns, and then instantiate Random with the same seed in your code. Then you would know which numbers your code will receive and in what order. That's very handy for debugging.
There could be NO really random numbers on deterministic devices like computer. But.
If you want a cryptographically secure random number, use SecureRandom: http://docs.oracle.com/javase/6/docs/api/java/security/SecureRandom.html
Random uses a deterministic algorithm:
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.
http://docs.oracle.com/javase/6/docs/api/java/util/Random.html#Random
Essentially, if you know the seed of the random number generator, you can predict the entire sequence with certainty. If you don't, no matter how many numbers you generate, there's no way to accurately predict the next one.
Note that if you're relying on the numbers being unpredictable for security, you should be using java.secure.SecureRandom rather than java.util.Random.
As others answer this question, it is possible to predict randomness of java.util.Random if you know the starting seed.
If you are working on a linux like system, take a look at these special files /dev/random and dev/urandom. Reads from these files are said to return "better" random numbers, the randomness depends on keyboard activity, mouse movement and some other exotic factors.
See this Wikipedia page for details. This page also says equivalent APIs exist in Windows.
I have piece of code which generates some Random number and prints out on console. However I am curious about the pattern which it prints, Such as,
import java.util.*;
public class Test
{
public static void main(String[] args)
{
Random random = new Random(-6732303926L);
for(int i=0;i<10;i++)
System.out.println(random.nextInt(10)+" ");
}
}
Result : 0 1 2 3 4 5 6 7 8 9 - Every number in new line.
And if you change this code a bit! like,
import java.util.*;
public class Test
{
public static void main(String[] args)
{
Random random = new Random(-6732303926L);
for(int i=0;i<10;i++)
System.out.println(random.nextInt(11)+" ");
}
}
Result : 8 9 2 2 10 3 8 7 0 10 - Every number in new line.
What is the reason of 0123456789 which is not random at all!?
0123456789 is random too, in this case - it's about as likely to come up as 14235682907, which would no doubt not have given you any cause for concern.
You spotted a fluke, basically. If you print the next 10 numbers in the first case, they're not preserving any obvious order.
It's like flipping a coin - the pattern HHHHHHHH is just as likely to come up as the exact pattern HHTHTTHH; there's a 1 in 28 chance of each coming up, as at any of the 8 steps there's a 50% chance of it going wrong. But the first pattern looks like it's broken, whereas the second doesn't.
I think it is random... you are using a specific seed for the random function. You just found the seed that will give you the numbers 0 - 9, in order.
EDIT: Apparently, this is the algorithm:
The java.util.Random class implements what is generally called a linear congruential generator (LCG). An LCG is essentially a formula of the following form:
numberi+1 = (a * numberi + c) mod m
Source: here
The Random class is a pseudo-random number generator. Thus it is not truely random, but instead relies on mathematical operations performed on an initial seed value. Thus, certain seeds will produce certain (potentially interesting/fun) sequences
The reason for the sequence is so that one can test software by making Random predicable with predictable and repeatable sequences using its next methods. Whenever a particular long seed parameter is a parameter to the Random constructor, the instanced Random object is supposed to return the same sequences of values through its next methods. This is a deliberate feature of java.util.Random.
java.util.Random has two constructors:
Random()
and
Random(long seed)
The constructor without a long integer seed uses the system time for creating a seed value for the pseudo random number generator. No two instantiations of Random will use the same seed and you should get a very good pseudo-random sequence. A Random instantiation using the constructor without a seed creates an instance with unpredictable sequences of values that will be pseudo-random.
The constructor with a seed value is intended only for making Random deterministic with predictable sequences using its next methods. The typical use of a seed is for software test purposes where results must be predicable and repeatable. Every instance of Random that uses the same long seed integer will create the same sequence of results every time. The particular long you used causes the sequence to be 0 1 2 3 4 5 6 7 8 9 over and over again when getting one of 10 integer values using nextInt(10) method. This and other predictable sequences that are repeatable every time software executes are very useful for testing software and are not meant for creating unpredictable pseudo-random sequences.
Creating random with a seed ensures a certain behavior. Especially, creating two instances of Random with the same seed, will always behave identically. Someone found out (via brute force, I guess) that using this particular seed together with the first 10 nextInt(10), creates such a seemingly ordered sequence. This sequence is pseudo-random updon first creation, but can be reproduced. Changing anything in the slightest gives a different result.
Random is based on the seed you give to it, if you want to get true random numbers, use time functions as seeds, and you'll get a real random number series.