In Java, I am trying to do an action with a probability p. p is a float variable in my code. I came up with this way of doing it:
if( new Random().nextFloat() < p)
do action
I wanted to confirm if this is the correct way of doing it.
There is a TL;DR at the end.
From javadocs for nextFloat()
(emphasis by me):
public float nextFloat()
Returns the next pseudorandom, uniformly distributed float value between 0.0 and 1.0 from this random number generator's sequence.
If you understand what uniform distribution is, knowing this about nextFloat()
is going to be enough for you. Yet I am going to explain a little about uniform distribution.
In uniform distribution, U(a,b) each number in the interval [a,b], and also all sub-intervals of the same length within [a,b] are equally probable, i.e. they have equal probability.
In the figure, on the left is the PDF, and on the right the CDF for uniform distribution.
For uniform distribution, the probability of getting a number less than or equal to n, P(x <= n) from the distribution is equal to the number itself (look at the right graph, which is cumulative distribution function for uniform distribution). That is, P(x <= 0.5) = 0.5, P(x <= 0.9) = 0.9. You can learn more about uniform distribution from any good statistics book, or some googling.
Now, probability of getting a number less than or equal to p generated using nextFloat()
is equal to p, as nextFloat()
returns uniformly distributed number. So, to make an action happen with a probability equal to p all you have to do is:
if (condition that is true with a probability p) {
do action
}
From what is discussed about nextFloat()
and uniform distribution, it turns out to be:
if(randObj.nextFloat() <= p) {
do action
}
P.S.: You don't need to create a new Random
object each time in your conditional, you can create one, say randObj
before your loop, and then invoke its nextFloat()
method whenever you want to generate a random number, as I have done in my code.
Take a look at the comment on the question by pjs, which is very important and well said. I quote:
Do not create a new
Random
object each time, that's not how PRNGs are meant to be used! A singleRandom
object provides a sequence of values with good distributional properties. MultipleRandom
objects created in rapid succession are 1) computationally expensive, and 2) may have highly correlated initial states, thus producing highly correlated outcomes.Random
actually works best when you create a single instance per program and keep drawing from it, unless you really really know what you're doing and have specific reasons for using correlation induction strategies.
What you did is almost the right way to do it. Just adding the equal sign after <
(to make it <=
) is all that's needed, and it doesn't hurt much to leave out the equal sign either!