在java中以一定的概率做一个动作

问题描述 投票:0回答:2

在Java中,我试图以概率p执行一个动作。 p 是我的代码中的浮点变量。我想出了这种方法:

if( new Random().nextFloat() < p)
  do action

我想确认这是否是正确的做法。

java random
2个回答
4
投票

最后有一个TL;DR


来自

nextFloat()
的javadocs(我强调):

public float nextFloat()

返回下一个伪随机数,均匀分布浮点值 来自此随机数生成器序列的 0.0 和 1.0 之间。

如果您了解什么是均匀分布,那么了解

nextFloat()
对您来说就足够了。不过我要解释一下均匀分布。

均匀分布中,U(a,b)区间[a,b]中的每个数字,以及[a,b]内相同长度的所有子区间都是等概率的,即它们具有相同的概率。

uniform

图中,左边是PDF,右边是均匀分布的CDF。

对于均匀分布,从分布中得到小于或等于n的数P(x<= n))的概率等于该数本身(看右图,这是均匀分布的累积分布函数)。是, P(x <= 0.5) = 0.5, P(x <= 0.9) = 0.9)。您可以从任何优秀的统计书籍或谷歌搜索中了解有关均匀分布的更多信息。

适合您的情况:

现在,使用

nextFloat()
生成的数字小于或等于 p 的概率等于 p,因为
nextFloat()
返回均匀分布的数字。因此,要使某个动作以等于 p 的概率发生,您所要做的就是:

if (condition that is true with a probability p) {
    do action
}

从关于

nextFloat()
和均匀分布的讨论来看,结果是:

if(randObj.nextFloat() <= p) {
    do action
}

P.S.:您不需要每次在条件中创建一个新的

Random
对象,您可以在循环之前创建一个新的
randObj
对象,然后在您想要生成随机数时调用其
nextFloat()
方法数字,正如我在代码中所做的那样。

pjs的评论:

看一下pjs对这个问题的评论,非常重要,说得很好。我引用:

不要每次都创建一个新的Random

对象,PRNG 不是这样的
本来就是用来用的!单个 
Random
 对象提供一系列值
具有良好的分布特性。创建了多个 
Random
 对象
快速连续的情况是:1)计算量大,2)可能有
高度相关的初始状态,从而产生高度相关的
结果。 
Random
 实际上,当您创建单个实例时效果最佳
每个程序并不断从中吸取教训,除非你真的真的知道
您正在做什么以及使用相关性的具体原因
诱导策略。


TL;博士

你所做的就是

几乎正确的做法。只需在 <

 之后添加等号(使其成为 
<=
)就足够了,省略等号也没什么坏处!


1
投票
是的。 这是正确的(从纯概率的角度来看)。

Random().nextFloat()

 将生成一个介于 
0.0
1.0
 之间的数字(不包括)。  因此,只要您的概率是在 
0.0
1.0
 范围内的浮点数,这 
is 就是正确的做法。

您可以在

此处
阅读更多确切的nextFloat()文档。

© www.soinside.com 2019 - 2024. All rights reserved.