I was curious to know, how do I implement probability in Java? For example, if the chances of a variable showing is 1/25, then how would I implement that? Or any other probability? Please point me in the general direction.
5 Answers
You'd use Random to generate a random number, then test it against a literal to match the probability you're trying to achieve.
So given:
boolean val = new Random().nextInt(25)==0;
val
will have a 1/25 probability of being true (since nextInt()
has an even probability of returning any number starting at 0 and up to, but not including, 25.)
You would of course have to import java.util.Random;
as well.
As pointed out below, if you're getting more than one random number it'd be more efficient to reuse the Random object rather than recreating it all the time:
Random rand = new Random();
boolean val = rand.nextInt(25)==0;
..
boolean val2 = rand.nextInt(25)==0;
-
1+1: Placing the
new Random()
in a field or variable and reusing it would help efficiency. Nov 18, 2011 at 14:26 -
@PeterLawrey you are correct of course, I've edited the answer appropriately. I just put it that way as a 1 line example! Nov 18, 2011 at 14:29
Generally you use a random number generator. Most of those return a number in the interval [0,1[ so you would then check whether that number is < 0.04 or not.
if( new Random().nextDouble() < 0.04 ) { //you might want to cache the Random instance
//we hit the 1/25 ( 4% ) case.
}
Or
if( Math.random() < 0.04 ) {
//we hit the 1/25 ( 4% ) case.
}
Note that there are multiple random number generators that have different properties, but for simple applications the Random
class should be sufficient.
Edit: I changed the condition from <=
to <
because the upper boundary of the random number is exlusive, i.e. the largest returned value will still be < 1.0. Hence x <= 0.04
would actually be slightly more than a 4% chance, while x < 0.04
would be accurate (or as accurate as floating point math can be).
-
3In the general case, this solution using rand.nextDouble() is better than the accepted answer, as it can apply to any arbitrary probability (rather than just to 1/x for a given integer x). For example, if your target probability is 33.5%, there is no simple, clean solution using rand.nextInt().– shiriAug 29, 2016 at 20:01
-
1@shiri that depends due to potential precision issues. Using integers you could create an integer between 0 and 1000 and check for the value being below 335.– ThomasSep 5, 2016 at 7:43
-
2agreed, I suppose it comes down to a matter of preference. When I think of probabilities I tend to think in terms of numbers in the range of [0,1], so I find nextDouble() <= X to be cleaner.– shiriSep 7, 2016 at 16:53
-
does it make sense to use <= (instead of <) given that == is misleading in floats due to precision?– HilikusOct 21, 2021 at 21:46
-
@Hilikus for small values the precision would be good enough for
==
but you can do it how you like. Whether the boundary is included or not should not make a huge difference.– ThomasOct 22, 2021 at 11:59
Since 1.7 it's better to use (in concurrent environment at least):
ThreadLocalRandom.current().nextInt(25) == 0
A random number generator isolated to the current thread. Like the global Random generator used by the Math class, a ThreadLocalRandom is initialized with an internally generated seed that may not otherwise be modified. When applicable, use of ThreadLocalRandom rather than shared Random objects in concurrent programs will typically encounter much less overhead and contention. Use of ThreadLocalRandom is particularly appropriate when multiple tasks (for example, each a ForkJoinTask) use random numbers in parallel in thread pools. Usages of this class should typically be of the form: ThreadLocalRandom.current().nextX(...) (where X is Int, Long, etc). When all usages are of this form, it is never possible to accidently share a ThreadLocalRandom across multiple threads.
This class also provides additional commonly used bounded random generation methods.
Java has a class called java.util.Random
which can generate random numbers. If you want something to happen with probability 1/25, simply generate a random number between 1 and 25 (or 0 and 24 inclusive) and check whether that number is equal to 1.
if(new java.util.Random().nextInt(25)==0){
//Do something.
}
Maybe you can implement this with generating random numbers.
Random rn = new Random();
double d = rn.nextDouble(); // random value in range 0.0 - 1.0
if(d<=0.04){
doSomeThing();
}